[med-svn] [liblemon] 01/02: Imported Upstream version 1.3.1+dfsg

Andreas Tille tille at debian.org
Fri Aug 5 14:09:52 UTC 2016


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository liblemon.

commit 8b116ae5872292dc67172529510cc6dc378e3bf9
Author: Andreas Tille <tille at debian.org>
Date:   Fri Aug 5 16:07:49 2016 +0200

    Imported Upstream version 1.3.1+dfsg
---
 .hg_archival.txt                             |    5 +
 .hgignore                                    |   53 +
 .hgtags                                      |    1 +
 AUTHORS                                      |   26 +
 CMakeLists.txt                               |  375 +++
 INSTALL                                      |  167 ++
 LICENSE                                      |   32 +
 NEWS                                         |  337 +++
 README                                       |   50 +
 cmake/FindCOIN.cmake                         |  110 +
 cmake/FindGLPK.cmake                         |   55 +
 cmake/FindGhostscript.cmake                  |   10 +
 cmake/FindILOG.cmake                         |  102 +
 cmake/FindSOPLEX.cmake                       |   23 +
 cmake/LEMONConfig.cmake.in                   |   13 +
 cmake/nsis/lemon.ico                         |  Bin 0 -> 22486 bytes
 cmake/nsis/uninstall.ico                     |  Bin 0 -> 15086 bytes
 cmake/version.cmake                          |    1 +
 cmake/version.cmake.in                       |    1 +
 contrib/CMakeLists.txt                       |   19 +
 demo/CMakeLists.txt                          |   19 +
 demo/arg_parser_demo.cc                      |  112 +
 demo/digraph.lgf                             |   29 +
 demo/graph_to_eps_demo.cc                    |  206 ++
 demo/lgf_demo.cc                             |   70 +
 doc/CMakeLists.txt                           |   86 +
 doc/Doxyfile.in                              |  292 ++
 doc/DoxygenLayout.xml                        |  181 ++
 doc/coding_style.dox                         |  127 +
 doc/dirs.dox                                 |   90 +
 doc/groups.dox                               |  777 +++++
 doc/images/adaptors1.eps                     |  303 ++
 doc/images/adaptors2.eps                     |  349 +++
 doc/images/bipartite_matching.eps            |  586 ++++
 doc/images/bipartite_partitions.eps          |  114 +
 doc/images/connected_components.eps          |  159 +
 doc/images/edge_biconnected_components.eps   |  159 +
 doc/images/graph_to_eps.png                  |  Bin 0 -> 24986 bytes
 doc/images/grid_graph.eps                    |  286 ++
 doc/images/matching.eps                      |  130 +
 doc/images/node_biconnected_components.eps   |  159 +
 doc/images/nodeshape_0.eps                   |   57 +
 doc/images/nodeshape_1.eps                   |   57 +
 doc/images/nodeshape_2.eps                   |   57 +
 doc/images/nodeshape_3.eps                   |   77 +
 doc/images/nodeshape_4.eps                   |   77 +
 doc/images/planar.eps                        |  181 ++
 doc/images/strongly_connected_components.eps |  180 ++
 doc/images/tsp.eps                           |  229 ++
 doc/lgf.dox                                  |  135 +
 doc/license.dox                              |   25 +
 doc/mainpage.dox.in                          |   61 +
 doc/migration.dox                            |  145 +
 doc/min_cost_flow.dox                        |  153 +
 doc/named-param.dox                          |  119 +
 doc/namespaces.dox                           |   30 +
 doc/references.bib                           |  356 +++
 doc/template.h                               |   22 +
 lemon/CMakeLists.txt                         |   91 +
 lemon/adaptors.h                             | 3638 +++++++++++++++++++++++
 lemon/arg_parser.cc                          |  474 +++
 lemon/arg_parser.h                           |  440 +++
 lemon/assert.h                               |  214 ++
 lemon/base.cc                                |   37 +
 lemon/bellman_ford.h                         | 1116 +++++++
 lemon/bfs.h                                  | 1754 +++++++++++
 lemon/bin_heap.h                             |  347 +++
 lemon/binomial_heap.h                        |  445 +++
 lemon/bits/alteration_notifier.h             |  472 +++
 lemon/bits/array_map.h                       |  351 +++
 lemon/bits/bezier.h                          |  174 ++
 lemon/bits/default_map.h                     |  182 ++
 lemon/bits/edge_set_extender.h               |  627 ++++
 lemon/bits/enable_if.h                       |  131 +
 lemon/bits/graph_adaptor_extender.h          |  401 +++
 lemon/bits/graph_extender.h                  | 1332 +++++++++
 lemon/bits/lock.h                            |   65 +
 lemon/bits/map_extender.h                    |  332 +++
 lemon/bits/path_dump.h                       |  177 ++
 lemon/bits/solver_bits.h                     |  194 ++
 lemon/bits/traits.h                          |  388 +++
 lemon/bits/variant.h                         |  494 ++++
 lemon/bits/vector_map.h                      |  244 ++
 lemon/bits/windows.cc                        |  166 ++
 lemon/bits/windows.h                         |   44 +
 lemon/bucket_heap.h                          |  594 ++++
 lemon/capacity_scaling.h                     | 1014 +++++++
 lemon/cbc.cc                                 |  460 +++
 lemon/cbc.h                                  |  129 +
 lemon/christofides_tsp.h                     |  254 ++
 lemon/circulation.h                          |  807 +++++
 lemon/clp.cc                                 |  464 +++
 lemon/clp.h                                  |  164 ++
 lemon/color.cc                               |   44 +
 lemon/color.h                                |  204 ++
 lemon/concept_check.h                        |   77 +
 lemon/concepts/bpgraph.h                     | 1029 +++++++
 lemon/concepts/digraph.h                     |  491 ++++
 lemon/concepts/graph.h                       |  788 +++++
 lemon/concepts/graph_components.h            | 2134 ++++++++++++++
 lemon/concepts/heap.h                        |  324 ++
 lemon/concepts/maps.h                        |  223 ++
 lemon/concepts/path.h                        |  312 ++
 lemon/config.h.in                            |   22 +
 lemon/connectivity.h                         | 1688 +++++++++++
 lemon/core.h                                 | 2506 ++++++++++++++++
 lemon/cost_scaling.h                         | 1607 ++++++++++
 lemon/counter.h                              |  249 ++
 lemon/cplex.cc                               |  994 +++++++
 lemon/cplex.h                                |  292 ++
 lemon/cycle_canceling.h                      | 1230 ++++++++
 lemon/dfs.h                                  | 1637 +++++++++++
 lemon/dheap.h                                |  352 +++
 lemon/dijkstra.h                             | 1303 +++++++++
 lemon/dim2.h                                 |  726 +++++
 lemon/dimacs.h                               |  448 +++
 lemon/edge_set.h                             | 1420 +++++++++
 lemon/edmonds_karp.h                         |  556 ++++
 lemon/elevator.h                             |  982 +++++++
 lemon/error.h                                |  276 ++
 lemon/euler.h                                |  287 ++
 lemon/fib_heap.h                             |  475 +++
 lemon/fractional_matching.h                  | 2139 ++++++++++++++
 lemon/full_graph.h                           | 1082 +++++++
 lemon/glpk.cc                                | 1012 +++++++
 lemon/glpk.h                                 |  263 ++
 lemon/gomory_hu.h                            |  568 ++++
 lemon/graph_to_eps.h                         | 1186 ++++++++
 lemon/greedy_tsp.h                           |  251 ++
 lemon/grid_graph.h                           |  699 +++++
 lemon/grosso_locatelli_pullan_mc.h           |  840 ++++++
 lemon/hao_orlin.h                            | 1015 +++++++
 lemon/hartmann_orlin_mmc.h                   |  654 +++++
 lemon/howard_mmc.h                           |  651 +++++
 lemon/hypercube_graph.h                      |  459 +++
 lemon/insertion_tsp.h                        |  533 ++++
 lemon/karp_mmc.h                             |  590 ++++
 lemon/kruskal.h                              |  324 ++
 lemon/lemon.pc.in                            |   10 +
 lemon/lgf_reader.h                           | 3854 ++++++++++++++++++++++++
 lemon/lgf_writer.h                           | 2687 +++++++++++++++++
 lemon/list_graph.h                           | 2510 ++++++++++++++++
 lemon/lp.h                                   |   95 +
 lemon/lp_base.cc                             |   30 +
 lemon/lp_base.h                              | 2147 ++++++++++++++
 lemon/lp_skeleton.cc                         |  143 +
 lemon/lp_skeleton.h                          |  234 ++
 lemon/maps.h                                 | 4057 ++++++++++++++++++++++++++
 lemon/matching.h                             | 3505 ++++++++++++++++++++++
 lemon/math.h                                 |   77 +
 lemon/max_cardinality_search.h               |  794 +++++
 lemon/min_cost_arborescence.h                |  808 +++++
 lemon/nagamochi_ibaraki.h                    |  702 +++++
 lemon/nauty_reader.h                         |  113 +
 lemon/nearest_neighbor_tsp.h                 |  238 ++
 lemon/network_simplex.h                      | 1659 +++++++++++
 lemon/opt2_tsp.h                             |  367 +++
 lemon/pairing_heap.h                         |  474 +++
 lemon/path.h                                 | 1164 ++++++++
 lemon/planarity.h                            | 2754 +++++++++++++++++
 lemon/preflow.h                              |  985 +++++++
 lemon/quad_heap.h                            |  343 +++
 lemon/radix_heap.h                           |  438 +++
 lemon/radix_sort.h                           |  487 ++++
 lemon/random.cc                              |   29 +
 lemon/random.h                               | 1005 +++++++
 lemon/smart_graph.h                          | 1344 +++++++++
 lemon/soplex.cc                              |  465 +++
 lemon/soplex.h                               |  158 +
 lemon/static_graph.h                         |  476 +++
 lemon/suurballe.h                            |  776 +++++
 lemon/time_measure.h                         |  610 ++++
 lemon/tolerance.h                            |  242 ++
 lemon/unionfind.h                            | 1824 ++++++++++++
 scripts/unify-sources.sh                     |  390 +++
 scripts/valgrind-wrapper.sh                  |   22 +
 test/CMakeLists.txt                          |  161 +
 test/adaptors_test.cc                        | 1468 ++++++++++
 test/arc_look_up_test.cc                     |   84 +
 test/bellman_ford_test.cc                    |  289 ++
 test/bfs_test.cc                             |  239 ++
 test/bpgraph_test.cc                         |  456 +++
 test/circulation_test.cc                     |  169 ++
 test/connectivity_test.cc                    |  316 ++
 test/counter_test.cc                         |  118 +
 test/dfs_test.cc                             |  238 ++
 test/digraph_test.cc                         |  569 ++++
 test/dijkstra_test.cc                        |  246 ++
 test/dim_test.cc                             |   87 +
 test/edge_set_test.cc                        |  396 +++
 test/error_test.cc                           |   90 +
 test/euler_test.cc                           |  225 ++
 test/fractional_matching_test.cc             |  527 ++++
 test/gomory_hu_test.cc                       |  142 +
 test/graph_copy_test.cc                      |  388 +++
 test/graph_test.cc                           |  603 ++++
 test/graph_test.h                            |  421 +++
 test/graph_utils_test.cc                     |  217 ++
 test/hao_orlin_test.cc                       |  164 ++
 test/heap_test.cc                            |  310 ++
 test/kruskal_test.cc                         |  147 +
 test/lgf_reader_writer_test.cc               |  578 ++++
 test/lgf_test.cc                             |  169 ++
 test/lp_test.cc                              |  470 +++
 test/maps_test.cc                            | 1022 +++++++
 test/matching_test.cc                        |  449 +++
 test/max_cardinality_search_test.cc          |  162 +
 test/max_clique_test.cc                      |  188 ++
 test/max_flow_test.cc                        |  395 +++
 test/min_cost_arborescence_test.cc           |  207 ++
 test/min_cost_flow_test.cc                   |  548 ++++
 test/min_mean_cycle_test.cc                  |  223 ++
 test/mip_test.cc                             |  171 ++
 test/nagamochi_ibaraki_test.cc               |  142 +
 test/path_test.cc                            |  339 +++
 test/planarity_test.cc                       |  262 ++
 test/radix_sort_test.cc                      |  266 ++
 test/random_test.cc                          |   40 +
 test/suurballe_test.cc                       |  267 ++
 test/test_tools.h                            |   50 +
 test/test_tools_fail.cc                      |   25 +
 test/test_tools_pass.cc                      |   25 +
 test/time_measure_test.cc                    |   60 +
 test/tsp_test.cc                             |  287 ++
 test/unionfind_test.cc                       |  102 +
 tools/CMakeLists.txt                         |   31 +
 tools/dimacs-solver.cc                       |  279 ++
 tools/dimacs-to-lgf.cc                       |  148 +
 tools/lemon-0.x-to-1.x.sh                    |  134 +
 tools/lgf-gen.cc                             |  847 ++++++
 230 files changed, 114705 insertions(+)

diff --git a/.hg_archival.txt b/.hg_archival.txt
new file mode 100644
index 0000000..f834209
--- /dev/null
+++ b/.hg_archival.txt
@@ -0,0 +1,5 @@
+repo: 6ed5fe0ea387ba9808e21048f02c665b16aa8c23
+node: bdabbf66b2ad131199059736178664f44c69adaf
+branch: 1.3
+latesttag: r1.3
+latesttagdistance: 11
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..73230ed
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,53 @@
+syntax: glob
+*.obj
+*.orig
+*.rej
+*~
+*.o
+*.log
+*.lo
+*.tar.*
+*.bak
+Makefile.in
+aclocal.m4
+config.h.in
+configure
+Makefile
+config.h
+config.log
+config.status
+libtool
+stamp-h1
+lemon/lemon.pc
+lemon/libemon.la
+lemon/stamp-h2
+doc/Doxyfile
+doc/references.dox
+cmake/version.cmake
+.dirstamp
+.libs/*
+.deps/*
+demo/*.eps
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+
+syntax: regexp
+(.*/)?\#[^/]*\#$
+(.*/)?\.\#[^/]*$
+^doc/html/.*
+^doc/.*\.tag
+^autom4te.cache/.*
+^build-aux/.*
+^.*objs.*/.*
+^test/[a-z_]*$
+^tools/[a-z-_]*$
+^demo/.*_demo$
+^.*build.*/.*
+^doc/gen-images/.*
+CMakeFiles
+DartTestfile.txt
+cmake_install.cmake
+CMakeCache.txt
diff --git a/.hgtags b/.hgtags
new file mode 100644
index 0000000..b5eb130
--- /dev/null
+++ b/.hgtags
@@ -0,0 +1 @@
+57ab090b6109902536ee34b1e8d4d123474311e3 r1.3
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..4019ca6
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,26 @@
+The main developers of release series 1.x are
+
+ * Balazs Dezso <deba at inf.elte.hu>
+ * Alpar Juttner <alpar at cs.elte.hu>
+ * Peter Kovacs <kpeter at inf.elte.hu>
+ * Akos Ladanyi <ladanyi at tmit.bme.hu>
+
+For more complete list of contributors, please visit the history of
+the LEMON source code repository: http://lemon.cs.elte.hu/hg/lemon
+
+Moreover, this version is heavily based on version 0.x of LEMON. Here
+is the list of people who contributed to those versions.
+
+ * Mihaly Barasz <klao at cs.elte.hu>
+ * Johanna Becker <beckerjc at cs.elte.hu>
+ * Attila Bernath <athos at cs.elte.hu>
+ * Balazs Dezso <deba at inf.elte.hu>
+ * Peter Hegyi <hegyi at tmit.bme.hu>
+ * Alpar Juttner <alpar at cs.elte.hu>
+ * Peter Kovacs <kpeter at inf.elte.hu>
+ * Akos Ladanyi <ladanyi at tmit.bme.hu>
+ * Marton Makai <marci at cs.elte.hu>
+ * Jacint Szabo <jacint at cs.elte.hu>
+
+Again, please visit the history of the old LEMON repository for more
+details: http://lemon.cs.elte.hu/hg/lemon-0.x
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..03e1cc7
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,375 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+CMAKE_POLICY(SET CMP0048 OLD)
+
+SET(PROJECT_NAME "LEMON")
+PROJECT(${PROJECT_NAME})
+
+INCLUDE(FindPythonInterp)
+INCLUDE(FindWget)
+
+IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
+  INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
+ELSEIF(DEFINED ENV{LEMON_VERSION})
+  SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
+ELSE()
+  EXECUTE_PROCESS(
+    COMMAND
+    hg log -r. --template "{latesttag}"
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION_TAG
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+  EXECUTE_PROCESS(
+    COMMAND
+    hg log -r. --template "{latesttagdistance}"
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION_DIST
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+  EXECUTE_PROCESS(
+    COMMAND
+    hg log -r. --template "{node|short}"
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION_ID
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+
+  IF(HG_REVISION_TAG STREQUAL "")
+    SET(HG_REVISION_ID "hg-tip")
+  ELSE()
+    IF(HG_REVISION_TAG STREQUAL "null")
+      SET(HG_REVISION_TAG "trunk")
+    ELSEIF(HG_REVISION_TAG MATCHES "^r")
+      STRING(SUBSTRING ${HG_REVISION_TAG} 1 -1 HG_REVISION_TAG)
+    ENDIF()
+    IF(HG_REVISION_DIST STREQUAL "0")
+      SET(HG_REVISION ${HG_REVISION_TAG})
+    ELSE()
+      SET(HG_REVISION
+	"${HG_REVISION_TAG}+${HG_REVISION_DIST}-${HG_REVISION_ID}")
+    ENDIF()
+  ENDIF()
+
+  SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
+ENDIF()
+
+SET(PROJECT_VERSION ${LEMON_VERSION})
+
+SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
+
+FIND_PACKAGE(Doxygen)
+FIND_PACKAGE(Ghostscript)
+
+SET(LEMON_ENABLE_GLPK YES CACHE STRING "Enable GLPK solver backend.")
+SET(LEMON_ENABLE_ILOG YES CACHE STRING "Enable ILOG (CPLEX) solver backend.")
+SET(LEMON_ENABLE_COIN YES CACHE STRING "Enable COIN solver backend.")
+SET(LEMON_ENABLE_SOPLEX YES CACHE STRING "Enable SoPlex solver backend.")
+
+IF(LEMON_ENABLE_GLPK) 
+  FIND_PACKAGE(GLPK 4.33)
+ENDIF(LEMON_ENABLE_GLPK)
+IF(LEMON_ENABLE_ILOG)
+  FIND_PACKAGE(ILOG)
+ENDIF(LEMON_ENABLE_ILOG)
+IF(LEMON_ENABLE_COIN)
+  FIND_PACKAGE(COIN)
+ENDIF(LEMON_ENABLE_COIN)
+IF(LEMON_ENABLE_SOPLEX)
+  FIND_PACKAGE(SOPLEX)
+ENDIF(LEMON_ENABLE_SOPLEX)
+
+IF(GLPK_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_GLPK TRUE)
+ENDIF(GLPK_FOUND)
+IF(ILOG_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_CPLEX TRUE)
+ENDIF(ILOG_FOUND)
+IF(COIN_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_CLP TRUE)
+  SET(LEMON_HAVE_CBC TRUE)
+ENDIF(COIN_FOUND)
+IF(SOPLEX_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_SOPLEX TRUE)
+ENDIF(SOPLEX_FOUND)
+
+IF(ILOG_FOUND)
+  SET(DEFAULT_LP "CPLEX")
+  SET(DEFAULT_MIP "CPLEX")
+ELSEIF(COIN_FOUND)
+  SET(DEFAULT_LP "CLP")
+  SET(DEFAULT_MIP "CBC")
+ELSEIF(GLPK_FOUND)
+  SET(DEFAULT_LP "GLPK")
+  SET(DEFAULT_MIP "GLPK")
+ELSEIF(SOPLEX_FOUND)
+  SET(DEFAULT_LP "SOPLEX")
+ENDIF()
+
+IF(NOT LEMON_DEFAULT_LP OR
+    (NOT ILOG_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CPLEX")) OR
+    (NOT COIN_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CLP")) OR
+    (NOT GLPK_FOUND AND (LEMON_DEFAULT_LP STREQUAL "GLPK")) OR
+    (NOT SOPLEX_FOUND AND (LEMON_DEFAULT_LP STREQUAL "SOPLEX")))
+  SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
+    "Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)" FORCE)
+ELSE()
+  SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
+    "Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)")
+ENDIF()
+IF(NOT LEMON_DEFAULT_MIP OR
+    (NOT ILOG_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CPLEX")) OR
+    (NOT COIN_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CBC")) OR
+    (NOT GLPK_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "GLPK")))
+  SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
+    "Default MIP solver backend (GLPK, CPLEX or CBC)" FORCE)
+ELSE()
+  SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
+    "Default MIP solver backend (GLPK, CPLEX or CBC)")
+ENDIF()
+
+
+IF(DEFINED ENV{LEMON_CXX_WARNING})
+  SET(CXX_WARNING $ENV{LEMON_CXX_WARNING})
+ELSE()
+  IF(CMAKE_COMPILER_IS_GNUCXX)
+    SET(CXX_WARNING "-Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas")
+    SET(CMAKE_CXX_FLAGS_DEBUG CACHE STRING "-ggdb")
+    SET(CMAKE_C_FLAGS_DEBUG CACHE STRING "-ggdb")
+  ELSEIF(MSVC)
+    # This part is unnecessary 'casue the same is set by the lemon/core.h.
+    # Still keep it as an example.
+    SET(CXX_WARNING "/wd4250 /wd4355 /wd4503 /wd4800 /wd4996")
+    # Suppressed warnings:
+    # C4250: 'class1' : inherits 'class2::member' via dominance
+    # C4355: 'this' : used in base member initializer list
+    # C4503: 'function' : decorated name length exceeded, name was truncated
+    # C4800: 'type' : forcing value to bool 'true' or 'false'
+    #        (performance warning)
+    # C4996: 'function': was declared deprecated
+  ELSE()
+    SET(CXX_WARNING "-Wall")
+  ENDIF()
+ENDIF()
+SET(LEMON_CXX_WARNING_FLAGS ${CXX_WARNING} CACHE STRING "LEMON warning flags.")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}")
+
+IF(MSVC)
+  SET( CMAKE_CXX_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
+    "Flags used by the C++ compiler during maintainer builds."
+    )
+  SET( CMAKE_C_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
+    "Flags used by the C compiler during maintainer builds."
+    )
+  SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used for linking binaries during maintainer builds."
+    )
+  SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used by the shared libraries linker during maintainer builds."
+    )
+ELSE()
+  SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING
+    "Flags used by the C++ compiler during maintainer builds."
+    )
+  SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING
+    "Flags used by the C compiler during maintainer builds."
+    )
+  SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used for linking binaries during maintainer builds."
+    )
+  SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used by the shared libraries linker during maintainer builds."
+    )
+ENDIF()
+
+MARK_AS_ADVANCED(
+    CMAKE_CXX_FLAGS_MAINTAINER
+    CMAKE_C_FLAGS_MAINTAINER
+    CMAKE_EXE_LINKER_FLAGS_MAINTAINER
+    CMAKE_SHARED_LINKER_FLAGS_MAINTAINER )
+
+IF(CMAKE_CONFIGURATION_TYPES)
+  LIST(APPEND CMAKE_CONFIGURATION_TYPES Maintainer)
+  LIST(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
+  SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
+      "Add the configurations that we need"
+      FORCE)
+ endif()
+
+IF(NOT CMAKE_BUILD_TYPE)
+  SET(CMAKE_BUILD_TYPE "Release")
+ENDIF()
+
+SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
+    "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel Maintainer."
+    FORCE )
+
+
+INCLUDE(CheckTypeSize)
+CHECK_TYPE_SIZE("long long" LONG_LONG)
+SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
+
+INCLUDE(FindThreads)
+
+IF(NOT LEMON_THREADING)
+  IF(CMAKE_USE_PTHREADS_INIT)
+    SET(LEMON_THREADING "Pthread")
+  ELSEIF(CMAKE_USE_WIN32_THREADS_INIT)
+    SET(LEMON_THREADING "Win32")
+  ELSE()
+    SET(LEMON_THREADING "None")
+  ENDIF()
+ENDIF()
+
+SET( LEMON_THREADING "${LEMON_THREADING}" CACHE STRING
+  "Choose the threading library, options are: Pthread Win32 None."
+  FORCE )
+
+IF(LEMON_THREADING STREQUAL "Pthread")
+  SET(LEMON_USE_PTHREAD TRUE)
+ELSEIF(LEMON_THREADING STREQUAL "Win32")
+  SET(LEMON_USE_WIN32_THREADS TRUE)
+ENDIF()
+
+ENABLE_TESTING()
+
+IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+  ADD_CUSTOM_TARGET(check ALL COMMAND ${CMAKE_CTEST_COMMAND})
+ELSE()
+  ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND})
+ENDIF()
+
+ADD_SUBDIRECTORY(lemon)
+IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
+  ADD_SUBDIRECTORY(contrib)
+  ADD_SUBDIRECTORY(demo)
+  ADD_SUBDIRECTORY(tools)
+  ADD_SUBDIRECTORY(doc)
+  ADD_SUBDIRECTORY(test)
+ENDIF()
+
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
+  ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
+  @ONLY
+)
+IF(UNIX)
+  INSTALL(
+    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
+    DESTINATION share/lemon/cmake
+  )
+ELSEIF(WIN32)
+  INSTALL(
+    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
+    DESTINATION cmake
+  )
+ENDIF()
+
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/cmake/version.cmake.in
+  ${PROJECT_BINARY_DIR}/cmake/version.cmake
+  @ONLY
+)
+
+SET(ARCHIVE_BASE_NAME ${CMAKE_PROJECT_NAME})
+STRING(TOLOWER ${ARCHIVE_BASE_NAME} ARCHIVE_BASE_NAME)
+SET(ARCHIVE_NAME ${ARCHIVE_BASE_NAME}-${PROJECT_VERSION})
+ADD_CUSTOM_TARGET(dist
+  COMMAND cmake -E remove_directory ${ARCHIVE_NAME}
+  COMMAND hg archive ${ARCHIVE_NAME}
+  COMMAND cmake -E copy cmake/version.cmake ${ARCHIVE_NAME}/cmake/version.cmake
+  COMMAND tar -czf ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_NAME}
+  COMMAND zip -r ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.zip ${ARCHIVE_NAME}
+  COMMAND cmake -E copy_directory doc/html ${ARCHIVE_NAME}/doc/html
+  COMMAND tar -czf ${ARCHIVE_NAME}.tar.gz ${ARCHIVE_NAME}
+  COMMAND zip -r ${ARCHIVE_NAME}.zip ${ARCHIVE_NAME}
+  COMMAND cmake -E copy_directory doc/html ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
+  COMMAND tar -czf ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
+  COMMAND zip -r ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.zip ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
+  COMMAND cmake -E remove_directory ${ARCHIVE_NAME}
+  COMMAND cmake -E remove_directory ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
+  DEPENDS html
+  WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
+
+# CPACK config (Basically for NSIS)
+IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
+  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
+  SET(CPACK_PACKAGE_VENDOR "EGRES")
+  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
+    "LEMON - Library for Efficient Modeling and Optimization in Networks")
+  SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
+
+  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
+
+  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
+    "${PROJECT_NAME} ${PROJECT_VERSION}")
+  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
+    "${PROJECT_NAME} ${PROJECT_VERSION}")
+
+  SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
+
+  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
+  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
+  SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
+  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
+
+  SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
+    "C++ header files")
+  SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
+    "DLL and import library")
+  SET(CPACK_COMPONENT_BIN_DESCRIPTION
+    "Command line utilities")
+  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
+    "Doxygen generated documentation")
+
+  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
+
+  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
+  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
+  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
+
+  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
+    "Components needed to develop software using LEMON")
+  SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
+    "Documentation of LEMON")
+
+  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
+
+  SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
+  SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
+  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
+
+  SET(CPACK_GENERATOR "NSIS")
+  SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
+  SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
+  #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
+  SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
+  SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
+  SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
+  SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
+  SET(CPACK_NSIS_CONTACT "lemon-user at lemon.cs.elte.hu")
+  SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
+    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
+    ")
+  SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
+    !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
+    Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
+    ")
+
+  INCLUDE(CPack)
+ENDIF()
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..3fba5b2
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,167 @@
+Installation Instructions
+=========================
+
+This file contains instructions for building and installing LEMON from
+source on Linux. The process on Windows is similar.
+
+Note that it is not necessary to install LEMON in order to use
+it. Instead, you can easily integrate it with your own code
+directly. For instructions, see
+https://lemon.cs.elte.hu/trac/lemon/wiki/HowToCompile
+
+
+In order to install LEMON from the extracted source tarball you have to
+issue the following commands:
+
+   1. Step into the root of the source directory.
+
+      $ cd lemon-x.y.z
+
+   2. Create a build subdirectory and step into it.
+
+      $ mkdir build
+      $ cd build
+
+   3. Perform system checks and create the makefiles.
+
+      $ cmake ..
+
+   4. Build LEMON.
+
+      $ make 
+
+      This command compiles the non-template part of LEMON into
+      libemon.a file. It also compiles the programs in the 'tools' and
+      'demo' subdirectories.
+
+   5. [Optional] Compile and run the self-tests.
+
+      $ make check
+
+   5. [Optional] Generate the user documentation.
+
+      $ make html
+
+      The release tarballs already include the documentation.
+
+      Note that for this step you need to have the following tools
+      installed: Python, Doxygen, Graphviz, Ghostscript, LaTeX.
+
+   6. [Optional] Install LEMON
+
+      $ make install
+
+      This command installs LEMON under /usr/local (you will need root
+      privileges to be able to do that). If you want to install it to
+      some other location, then pass the
+      -DCMAKE_INSTALL_PREFIX=DIRECTORY flag to cmake in Step 3.
+      For example:
+      
+      $ cmake -DCMAKE_INSTALL_PREFIX=/home/username/lemon'
+
+Configure Options and Variables
+===============================
+
+In Step 3, you can customize the build process by passing options to CMAKE.
+
+$ cmake [OPTIONS] ..
+
+You find a list of the most useful options below.
+
+-DCMAKE_INSTALL_PREFIX=PREFIX
+
+  Set the installation prefix to PREFIX. By default it is /usr/local.
+
+-DCMAKE_BUILD_TYPE=[Release|Debug|Maintainer|...]
+
+  This sets the compiler options. The choices are the following
+
+  'Release': A strong optimization is turned on (-O3 with gcc). This
+    is the default setting and we strongly recommend using this for
+    the final compilation.
+
+  'Debug': Optimization is turned off and debug info is added (-O0
+    -ggdb with gcc). If is recommended during the development.
+
+  'Maintainer': The same as 'Debug' but the compiler warnings are
+    converted to errors (-Werror with gcc). In addition, 'make' will
+    also automatically compile and execute the test codes. It is the
+    best way of ensuring that LEMON codebase is clean and safe.
+
+  'RelWithDebInfo': Optimized build with debug info.
+
+  'MinSizeRel': Size optimized build (-Os with gcc)
+
+-DTEST_WITH_VALGRIND=YES
+
+  Using this, the test codes will be executed using valgrind. It is a
+  very effective way of identifying indexing problems and memory leaks.
+
+-DCMAKE_CXX_COMPILER=path-to-compiler
+
+  Change the compiler to be used.
+
+-DBUILD_SHARED_LIBS=TRUE
+
+  Build shared library instead of static one. Think twice if you
+  really want to use this option.
+
+-DLEMON_DOC_SOURCE_BROWSER=YES
+
+  Include the browsable cross referenced LEMON source code into the
+  doc. It makes the doc quite bloated, but may be useful for
+  developing LEMON itself.
+
+-DLEMON_DOC_USE_MATHJAX=YES
+
+  Use MathJax (http://mathjax.org) for rendering the math formulae in
+  the doc.  It of much higher quality compared to the default LaTeX
+  generated static images and it allows copy&paste of the formulae to
+  LaTeX, Open Office, MS Word etc. documents.
+
+  On the other hand, it needs either Internet access or a locally
+  installed version of MathJax to properly render the doc.
+
+-DLEMON_DOC_MATHJAX_RELPATH=DIRECTORY
+  
+  The location of the MathJax library. It defaults to
+  http://www.mathjax.org/mathjax, which necessitates Internet access
+  for proper rendering. The easiest way to make it usable offline is
+  to set this parameter to 'mathjax' and copy all files of the MathJax
+  library into the 'doc/html/mathjax' subdirectory of the build
+  location.
+
+  See http://docs.mathjax.org/en/latest/installation.html for more details.
+
+  
+-DLEMON_ENABLE_GLPK=NO
+-DLEMON_ENABLE_COIN=NO
+-DLEMON_ENABLE_ILOG=NO
+
+  Enable optional third party libraries. They are all enabled by default. 
+
+-DLEMON_DEFAULT_LP=GLPK
+
+  Sets the default LP solver backend. The supported values are
+  CPLEX, CLP and GLPK. By default, it is set to the first one which
+  is enabled and succesfully discovered.
+
+-DLEMON_DEFAULT_MIP=GLPK
+
+  Sets the default MIP solver backend. The supported values are
+  CPLEX, CBC and GLPK. By default, it is set to the first one which
+  is enabled and succesfully discovered.
+
+-DGLPK_ROOT_DIR=DIRECTORY
+-DCOIN_ROOT_DIR=DIRECTORY
+-DILOG_ROOT_DIR=DIRECTORY
+
+  Root directory prefixes of optional third party libraries.
+
+Makefile Variables
+==================
+
+make VERBOSE=1
+
+   This results in a more verbose output by showing the full
+   compiler and linker commands.
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5b1c425
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,32 @@
+LEMON code without an explicit copyright notice is covered by the following
+copyright/license.
+
+Copyright (C) 2003-2012 Egervary Jeno Kombinatorikus Optimalizalasi
+Kutatocsoport (Egervary Combinatorial Optimization Research Group,
+EGRES).
+
+===========================================================================
+Boost Software License, Version 1.0
+===========================================================================
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..7908ca3
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,337 @@
+2014-07-07 Version 1.3.1 released
+
+        Bugfix release.
+
+        #484: Require CMAKE 2.8
+        #471, #472, #480: Various clang compatibility fixes
+        #481, #482: Fix shared lib build and versioning
+        #476: Fix invalid map query in NearestNeighborTsp
+        #478: Bugfix in debug checking and lower bound handling
+              in min cost flow algorithms
+        #479, #465: Bugfix in default LP/MIP backend settings
+        #476: Bugfix in tsp_test
+        #487: Add missing include header and std:: namespace spec.
+        #474: Fix division by zero error in NetworkSimplex
+
+2013-08-10 Version 1.3 released
+
+        This is major feature release
+
+        * New data structures
+
+          #69 : Bipartite graph concepts and implementations
+
+        * New algorithms
+
+          #177: Port Edmonds-Karp algorithm
+          #380, #405: Heuristic algorithm for the max clique problem
+          #386: Heuristic algorithms for symmetric TSP
+          ----: Nagamochi-Ibaraki algorithm [5087694945e4]
+          #397, #56: Max. cardinality search
+
+        * Other new features
+
+          #223: Thread safe graph and graph map implementations
+          #442: Different TimeStamp print formats
+          #457: File export functionality to LpBase
+          #362: Bidirectional iterator support for radixSort()
+
+        * Implementation improvements
+
+          ----: Network Simplex
+                #391: Better update process, pivot rule and arc mixing
+                #435: Improved Altering List pivot rule
+          #417: Various fine tunings in CostScaling
+          #438: Optional iteration limit in HowardMmc
+          #436: Ensure strongly polynomial running time for CycleCanceling
+                while keeping the same performance
+          ----: Make the CBC interface be compatible with latest CBC releases
+                [ee581a0ecfbf]
+
+        * CMAKE has become the default build environment (#434)
+
+          ----: Autotool support has been dropped
+          ----: Improved LP/MIP configuration
+                #465: Enable/disable options for LP/MIP backends
+                #446: Better CPLEX discovery
+                #460: Add cmake config to find SoPlex
+          ----: Allow CPACK configuration on all platforms
+          #390: Add 'Maintainer' CMAKE build type
+          #388: Add 'check' target.
+          #401: Add contrib dir
+          #389: Better version string setting in CMAKE
+          #433: Support shared library build    
+          #416: Support testing with valgrind
+  
+        * Doc improvements
+
+          #395: SOURCE_BROWSER Doxygen switch is configurable from CMAKE
+                update-external-tags CMAKE target
+          #455: Optionally use MathJax for rendering the math formulae
+          #402, #437, #459, #456, #463: Various doc improvements
+
+        * Bugfixes (compared to release 1.2):
+
+          #432: Add missing doc/template.h and doc/references.bib to release
+                tarball
+          ----: Intel C++ compatibility fixes
+          #441: Fix buggy reinitialization in _solver_bits::VarIndex::clear()
+          #444: Bugfix in path copy constructors and assignment operators
+          #447: Bugfix in AllArcLookUp<>
+          #448: Bugfix in adaptor_test.cc
+          #449: Fix clang compilation warnings and errors
+          #440: Fix a bug + remove redundant typedefs in dimacs-solver
+          #453: Avoid GCC 4.7 compiler warnings
+          #445: Fix missing initialization in CplexEnv::CplexEnv()
+          #428: Add missing lemon/lemon.pc.cmake to the release tarball
+          #393: Create and install lemon.pc
+          #429: Fix VS warnings
+          #430: Fix LpBase::Constr two-side limit bug
+          #392: Bug fix in Dfs::start(s,t)
+          #414: Fix wrong initialization in Preflow
+          #418: Better Win CodeBlock/MinGW support
+          #419: Build environment improvements
+                - Build of mip_test and lp_test precede the running of the tests
+                - Also search for coin libs under ${COIN_ROOT_DIR}/lib/coin
+                - Do not look for COIN_VOL libraries
+          #382: Allow lgf file without Arc maps
+          #417: Bug fix in CostScaling
+          #366: Fix Pred[Matrix]MapPath::empty()
+          #371: Bug fix in (di)graphCopy()
+                The target graph is cleared before adding nodes and arcs/edges.
+          #364: Add missing UndirectedTags
+          #368: Fix the usage of std::numeric_limits<>::min() in Network Simplex
+          #372: Fix a critical bug in preflow
+          #461: Bugfix in assert.h
+          #470: Fix compilation issues related to various gcc versions
+          #446: Fix #define indicating CPLEX availability
+          #294: Add explicit namespace to
+                ignore_unused_variable_warning() usages
+          #420: Bugfix in IterableValueMap
+          #439: Bugfix in biNodeConnected()
+
+
+2010-03-19 Version 1.2 released
+
+        This is major feature release
+
+        * New algorithms
+          * Bellman-Ford algorithm (#51)
+          * Minimum mean cycle algorithms (#179)
+            * Karp, Hartman-Orlin and Howard algorithms
+          * New minimum cost flow algorithms (#180)
+            * Cost Scaling algorithms
+            * Capacity Scaling algorithm
+            * Cycle-Canceling algorithms
+          * Planarity related algorithms (#62)
+            * Planarity checking algorithm
+            * Planar embedding algorithm
+            * Schnyder's planar drawing algorithm
+            * Coloring planar graphs with five or six colors
+          * Fractional matching algorithms (#314)
+        * New data structures
+          * StaticDigraph structure (#68)
+          * Several new priority queue structures (#50, #301)
+            * Fibonacci, Radix, Bucket, Pairing, Binomial
+              D-ary and fourary heaps (#301)
+          * Iterable map structures (#73)
+        * Other new tools and functionality
+          * Map utility functions (#320)
+          * Reserve functions are added to ListGraph and SmartGraph (#311)
+          * A resize() function is added to HypercubeGraph (#311)
+          * A count() function is added to CrossRefMap (#302)
+          * Support for multiple targets in Suurballe using fullInit() (#181)
+          * Traits class and named parameters for Suurballe (#323)
+          * Separate reset() and resetParams() functions in NetworkSimplex
+            to handle graph changes (#327)
+          * tolerance() functions are added to HaoOrlin (#306)
+        * Implementation improvements
+          * Improvements in weighted matching algorithms (#314)
+            * Jumpstart initialization
+          * ArcIt iteration is based on out-arc lists instead of in-arc lists
+            in ListDigraph (#311)
+          * Faster add row operation in CbcMip (#203)
+          * Better implementation for split() in ListDigraph (#311)
+          * ArgParser can also throw exception instead of exit(1) (#332)
+        * Miscellaneous
+          * A simple interactive bootstrap script
+          * Doc improvements (#62,#180,#299,#302,#303,#304,#307,#311,#331,#315,
+                #316,#319)
+            * BibTeX references in the doc (#184)
+          * Optionally use valgrind when running tests
+          * Also check ReferenceMapTag in concept checks (#312)
+          * dimacs-solver uses long long type by default.
+        * Several bugfixes (compared to release 1.1):
+          #295: Suppress MSVC warnings using pragmas
+          ----: Various CMAKE related improvements
+                * Remove duplications from doc/CMakeLists.txt
+                * Rename documentation install folder from 'docs' to 'html'
+                * Add tools/CMakeLists.txt to the tarball
+                * Generate and install LEMONConfig.cmake
+                * Change the label of the html project in Visual Studio
+                * Fix the check for the 'long long' type
+                * Put the version string into config.h
+                * Minor CMake improvements
+                * Set the version to 'hg-tip' if everything fails
+          #311: Add missing 'explicit' keywords
+          #302: Fix the implementation and doc of CrossRefMap
+          #308: Remove duplicate list_graph.h entry from source list
+          #307: Bugfix in Preflow and Circulation
+          #305: Bugfix and extension in the rename script
+          #312: Also check ReferenceMapTag in concept checks
+          #250: Bugfix in pathSource() and pathTarget()
+          #321: Use pathCopy(from,to) instead of copyPath(to,from)
+          #322: Distribure LEMONConfig.cmake.in
+          #330: Bug fix in map_extender.h
+          #336: Fix the date field comment of graphToEps() output
+          #323: Bug fix in Suurballe
+          #335: Fix clear() function in ExtendFindEnum
+          #337: Use void* as the LPX object pointer
+          #317: Fix (and improve) error message in mip_test.cc
+                Remove unnecessary OsiCbc dependency
+          #356: Allow multiple executions of weighted matching algorithms (#356)
+
+2009-05-13 Version 1.1 released
+
+        This is the second stable release of the 1.x series. It
+        features a better coverage of the tools available in the 0.x
+        series, a thoroughly reworked LP/MIP interface plus various
+        improvements in the existing tools.
+
+        * Much improved M$ Windows support
+          * Various improvements in the CMAKE build system
+          * Compilation warnings are fixed/suppressed
+        * Support IBM xlC compiler
+        * New algorithms
+          * Connectivity related algorithms (#61)
+          * Euler walks (#65)
+          * Preflow push-relabel max. flow algorithm (#176)
+          * Circulation algorithm (push-relabel based) (#175)
+          * Suurballe algorithm (#47)
+          * Gomory-Hu algorithm (#66)
+          * Hao-Orlin algorithm (#58)
+          * Edmond's maximum cardinality and weighted matching algorithms
+            in general graphs (#48,#265)
+          * Minimum cost arborescence/branching (#60)
+          * Network Simplex min. cost flow algorithm (#234)
+        * New data structures
+          * Full graph structure (#57)
+          * Grid graph structure (#57)
+          * Hypercube graph structure (#57)
+          * Graph adaptors (#67)
+          * ArcSet and EdgeSet classes (#67)
+          * Elevator class (#174)
+        * Other new tools
+          * LP/MIP interface (#44)
+            * Support for GLPK, CPLEX, Soplex, COIN-OR CLP and CBC
+          * Reader for the Nauty file format (#55)
+          * DIMACS readers (#167)
+          * Radix sort algorithms (#72)
+          * RangeIdMap and CrossRefMap (#160)
+        * New command line tools
+          * DIMACS to LGF converter (#182)
+          * lgf-gen - a graph generator (#45)
+          * DIMACS solver utility (#226)
+        * Other code improvements
+          * Lognormal distribution added to Random (#102)
+          * Better (i.e. O(1) time) item counting in SmartGraph (#3)
+          * The standard maps of graphs are guaranteed to be
+            reference maps (#190)
+        * Miscellaneous
+          * Various doc improvements
+          * Improved 0.x -> 1.x converter script
+
+        * Several bugfixes (compared to release 1.0):
+          #170: Bugfix SmartDigraph::split()
+          #171: Bugfix in SmartGraph::restoreSnapshot()
+          #172: Extended test cases for graphs and digraphs
+          #173: Bugfix in Random
+                * operator()s always return a double now
+                * the faulty real<Num>(Num) and real<Num>(Num,Num)
+                  have been removed
+          #187: Remove DijkstraWidestPathOperationTraits
+          #61:  Bugfix in DfsVisit
+          #193: Bugfix in GraphReader::skipSection()
+          #195: Bugfix in ConEdgeIt()
+          #197: Bugfix in heap unionfind
+                * This bug affects Edmond's general matching algorithms
+          #207: Fix 'make install' without 'make html' using CMAKE
+          #208: Suppress or fix VS2008 compilation warnings
+          ----: Update the LEMON icon
+          ----: Enable the component-based installer
+                (in installers made by CPACK)
+          ----: Set the proper version for CMAKE in the tarballs
+                (made by autotools)
+          ----: Minor clarification in the LICENSE file
+          ----: Add missing unistd.h include to time_measure.h
+          #204: Compilation bug fixed in graph_to_eps.h with VS2005
+          #214,#215: windows.h should never be included by LEMON headers
+          #230: Build systems check the availability of 'long long' type
+          #229: Default implementation of Tolerance<> is used for integer types
+          #211,#212: Various fixes for compiling on AIX
+          ----: Improvements in CMAKE config
+                - docs is installed in share/doc/
+                - detects newer versions of Ghostscript
+          #239: Fix missing 'inline' specifier in time_measure.h
+          #274,#280: Install lemon/config.h
+          #275: Prefix macro names with LEMON_ in lemon/config.h
+          ----: Small script for making the release tarballs added
+          ----: Minor improvement in unify-sources.sh (a76f55d7d397)
+
+2009-03-27 LEMON joins to the COIN-OR initiative
+
+        COIN-OR (Computational Infrastructure for Operations Research,
+        http://www.coin-or.org) project is an initiative to spur the
+        development of open-source software for the operations research
+        community.
+
+2008-10-13 Version 1.0 released
+
+        This is the first stable release of LEMON. Compared to the 0.x
+        release series, it features a considerably smaller but more
+        matured set of tools. The API has also completely revised and
+        changed in several places.
+
+        * The major name changes compared to the 0.x series (see the
+          Migration Guide in the doc for more details)
+          * Graph -> Digraph, UGraph -> Graph
+          * Edge -> Arc, UEdge -> Edge
+          * source(UEdge)/target(UEdge) -> u(Edge)/v(Edge)
+        * Other improvements
+          * Better documentation
+          * Reviewed and cleaned up codebase
+          * CMake based build system (along with the autotools based one)
+        * Contents of the library (ported from 0.x)
+          * Algorithms
+            * breadth-first search (bfs.h)
+            * depth-first search (dfs.h)
+            * Dijkstra's algorithm (dijkstra.h)
+            * Kruskal's algorithm (kruskal.h)
+          * Data structures
+            * graph data structures (list_graph.h, smart_graph.h)
+            * path data structures (path.h)
+            * binary heap data structure (bin_heap.h)
+            * union-find data structures (unionfind.h)
+            * miscellaneous property maps (maps.h)
+            * two dimensional vector and bounding box (dim2.h)
+          * Concepts
+            * graph structure concepts (concepts/digraph.h, concepts/graph.h,
+              concepts/graph_components.h)
+            * concepts for other structures (concepts/heap.h, concepts/maps.h,
+              concepts/path.h)
+          * Tools
+            * Mersenne twister random number generator (random.h)
+            * tools for measuring cpu and wall clock time (time_measure.h)
+            * tools for counting steps and events (counter.h)
+            * tool for parsing command line arguments (arg_parser.h)
+            * tool for visualizing graphs (graph_to_eps.h)
+            * tools for reading and writing data in LEMON Graph Format
+              (lgf_reader.h, lgf_writer.h)
+            * tools to handle the anomalies of calculations with
+              floating point numbers (tolerance.h)
+            * tools to manage RGB colors (color.h)
+          * Infrastructure
+            * extended assertion handling (assert.h)
+            * exception classes and error handling (error.h)
+            * concept checking (concept_check.h)
+            * commonly used mathematical constants (math.h)
diff --git a/README b/README
new file mode 100644
index 0000000..52a768c
--- /dev/null
+++ b/README
@@ -0,0 +1,50 @@
+=====================================================================
+LEMON - a Library for Efficient Modeling and Optimization in Networks
+=====================================================================
+
+LEMON is an open source library written in C++. It provides
+easy-to-use implementations of common data structures and algorithms
+in the area of optimization and helps implementing new ones. The main
+focus is on graphs and graph algorithms, thus it is especially
+suitable for solving design and optimization problems of
+telecommunication networks. To achieve wide usability its data
+structures and algorithms provide generic interfaces.
+
+Contents
+========
+
+LICENSE
+
+   Copying, distribution and modification conditions and terms.
+
+NEWS
+
+   News and version history.
+
+INSTALL
+
+   General building and installation instructions.
+
+lemon/
+
+   Source code of LEMON library.
+
+doc/
+
+   Documentation of LEMON. The starting page is doc/html/index.html.
+
+demo/
+
+   Some example programs to make you easier to get familiar with LEMON.
+
+scripts/
+
+   Scripts that make it easier to develop LEMON.
+
+test/
+
+   Programs to check the integrity and correctness of LEMON.
+
+tools/
+
+   Various utilities related to LEMON.
diff --git a/cmake/FindCOIN.cmake b/cmake/FindCOIN.cmake
new file mode 100644
index 0000000..d4ed735
--- /dev/null
+++ b/cmake/FindCOIN.cmake
@@ -0,0 +1,110 @@
+SET(COIN_ROOT_DIR "" CACHE PATH "COIN root directory")
+
+FIND_PATH(COIN_INCLUDE_DIR coin/CoinUtilsConfig.h
+  HINTS ${COIN_ROOT_DIR}/include
+)
+FIND_LIBRARY(COIN_CBC_LIBRARY
+  NAMES Cbc libCbc
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY
+  NAMES CbcSolver libCbcSolver
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_CGL_LIBRARY
+  NAMES Cgl libCgl
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_CLP_LIBRARY
+  NAMES Clp libClp
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY
+  NAMES CoinUtils libCoinUtils
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_OSI_LIBRARY
+  NAMES Osi libOsi
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_OSI_CBC_LIBRARY
+  NAMES OsiCbc libOsiCbc
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_OSI_CLP_LIBRARY
+  NAMES OsiClp libOsiClp
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_OSI_VOL_LIBRARY
+  NAMES OsiVol libOsiVol
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_VOL_LIBRARY
+  NAMES Vol libVol
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+
+FIND_LIBRARY(COIN_ZLIB_LIBRARY
+  NAMES z libz
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_BZ2_LIBRARY
+  NAMES bz2 libbz2
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG
+  COIN_INCLUDE_DIR
+  COIN_CBC_LIBRARY
+  COIN_CBC_SOLVER_LIBRARY
+  COIN_CGL_LIBRARY
+  COIN_CLP_LIBRARY
+  COIN_COIN_UTILS_LIBRARY
+  COIN_OSI_LIBRARY
+  COIN_OSI_CBC_LIBRARY
+  COIN_OSI_CLP_LIBRARY
+  # COIN_OSI_VOL_LIBRARY
+  # COIN_VOL_LIBRARY
+)
+
+IF(COIN_FOUND)
+  SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
+  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY}")
+  IF(COIN_ZLIB_LIBRARY)
+    SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_ZLIB_LIBRARY}")
+  ENDIF(COIN_ZLIB_LIBRARY)
+   IF(COIN_BZ2_LIBRARY)
+    SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_BZ2_LIBRARY}")
+  ENDIF(COIN_BZ2_LIBRARY)
+  SET(COIN_CBC_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY};${COIN_CLP_LIBRARIES}")
+  SET(COIN_LIBRARIES ${COIN_CBC_LIBRARIES})
+ENDIF(COIN_FOUND)
+
+MARK_AS_ADVANCED(
+  COIN_INCLUDE_DIR
+  COIN_CBC_LIBRARY
+  COIN_CBC_SOLVER_LIBRARY
+  COIN_CGL_LIBRARY
+  COIN_CLP_LIBRARY
+  COIN_COIN_UTILS_LIBRARY
+  COIN_OSI_LIBRARY
+  COIN_OSI_CBC_LIBRARY
+  COIN_OSI_CLP_LIBRARY
+  COIN_OSI_VOL_LIBRARY
+  COIN_VOL_LIBRARY
+  COIN_ZLIB_LIBRARY
+  COIN_BZ2_LIBRARY
+)
diff --git a/cmake/FindGLPK.cmake b/cmake/FindGLPK.cmake
new file mode 100644
index 0000000..55e5e3e
--- /dev/null
+++ b/cmake/FindGLPK.cmake
@@ -0,0 +1,55 @@
+SET(GLPK_ROOT_DIR "" CACHE PATH "GLPK root directory")
+
+SET(GLPK_REGKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Glpk;InstallPath]")
+GET_FILENAME_COMPONENT(GLPK_ROOT_PATH ${GLPK_REGKEY} ABSOLUTE)
+
+FIND_PATH(GLPK_INCLUDE_DIR
+  glpk.h
+  PATHS ${GLPK_REGKEY}/include
+  HINTS ${GLPK_ROOT_DIR}/include
+)
+FIND_LIBRARY(GLPK_LIBRARY
+  glpk
+  PATHS ${GLPK_REGKEY}/lib
+  HINTS ${GLPK_ROOT_DIR}/lib
+)
+
+IF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
+  FILE(READ ${GLPK_INCLUDE_DIR}/glpk.h GLPK_GLPK_H)
+
+  STRING(REGEX MATCH "define[ ]+GLP_MAJOR_VERSION[ ]+[0-9]+" GLPK_MAJOR_VERSION_LINE "${GLPK_GLPK_H}")
+  STRING(REGEX REPLACE "define[ ]+GLP_MAJOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MAJOR "${GLPK_MAJOR_VERSION_LINE}")
+
+  STRING(REGEX MATCH "define[ ]+GLP_MINOR_VERSION[ ]+[0-9]+" GLPK_MINOR_VERSION_LINE "${GLPK_GLPK_H}")
+  STRING(REGEX REPLACE "define[ ]+GLP_MINOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MINOR "${GLPK_MINOR_VERSION_LINE}")
+
+  SET(GLPK_VERSION_STRING "${GLPK_VERSION_MAJOR}.${GLPK_VERSION_MINOR}")
+
+  IF(GLPK_FIND_VERSION)
+    IF(GLPK_FIND_VERSION_COUNT GREATER 2)
+      MESSAGE(SEND_ERROR "unexpected version string")
+    ENDIF(GLPK_FIND_VERSION_COUNT GREATER 2)
+
+    MATH(EXPR GLPK_REQUESTED_VERSION "${GLPK_FIND_VERSION_MAJOR}*100 + ${GLPK_FIND_VERSION_MINOR}")
+    MATH(EXPR GLPK_FOUND_VERSION "${GLPK_VERSION_MAJOR}*100 + ${GLPK_VERSION_MINOR}")
+
+    IF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
+      SET(GLPK_PROPER_VERSION_FOUND FALSE)
+    ELSE(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
+      SET(GLPK_PROPER_VERSION_FOUND TRUE)
+    ENDIF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
+  ELSE(GLPK_FIND_VERSION)
+    SET(GLPK_PROPER_VERSION_FOUND TRUE)
+  ENDIF(GLPK_FIND_VERSION)
+ENDIF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_PROPER_VERSION_FOUND)
+
+IF(GLPK_FOUND)
+  SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR})
+  SET(GLPK_LIBRARIES ${GLPK_LIBRARY})
+  SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin)
+ENDIF(GLPK_FOUND)
+
+MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
diff --git a/cmake/FindGhostscript.cmake b/cmake/FindGhostscript.cmake
new file mode 100644
index 0000000..3366a00
--- /dev/null
+++ b/cmake/FindGhostscript.cmake
@@ -0,0 +1,10 @@
+INCLUDE(FindPackageHandleStandardArgs)
+
+FIND_PROGRAM(GHOSTSCRIPT_EXECUTABLE
+  NAMES gs gswin32c
+  PATHS "$ENV{ProgramFiles}/gs"
+  PATH_SUFFIXES gs8.61/bin gs8.62/bin gs8.63/bin gs8.64/bin gs8.65/bin
+  DOC "Ghostscript: PostScript and PDF language interpreter and previewer."
+)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ghostscript DEFAULT_MSG GHOSTSCRIPT_EXECUTABLE)
diff --git a/cmake/FindILOG.cmake b/cmake/FindILOG.cmake
new file mode 100644
index 0000000..a09fc9a
--- /dev/null
+++ b/cmake/FindILOG.cmake
@@ -0,0 +1,102 @@
+FIND_PATH(ILOG_ROOT_DIR
+  NAMES cplex
+  DOC "CPLEX STUDIO root directory"
+  PATHS /opt/ibm/ILOG /usr/local/ibm/ILOG /usr/local/ILOG /usr/local/ilog
+  PATHS "$ENV{HOME}/ILOG" "$ENV{HOME}/.local/ILOG"
+  PATHS "$ENV{HOME}/ibm/ILOG" "$ENV{HOME}/.local/ibm/ILOG"
+  PATHS "C:/Program Files/IBM/ILOG" 
+  PATH_SUFFIXES "CPLEX_Studio126" "CPLEX_Studio125"
+  "CPLEX_Studio124" "CPLEX_Studio123" "CPLEX_Studio122"
+  NO_DEFAULT_PATH
+)
+
+IF(WIN32)
+  IF(MSVC_VERSION STREQUAL "1400")
+    SET(ILOG_WIN_COMPILER "windows_vs2005")
+  ELSEIF(MSVC_VERSION STREQUAL "1500")
+    SET(ILOG_WIN_COMPILER "windows_vs2008")
+  ELSEIF(MSVC_VERSION STREQUAL "1600")
+    SET(ILOG_WIN_COMPILER "windows_vs2010")
+  ELSE()
+    SET(ILOG_WIN_COMPILER "windows_vs2008")
+  ENDIF()
+  IF(CMAKE_CL_64)
+    SET(ILOG_WIN_COMPILER "x64_${ILOG_WIN_COMPILER}")
+    SET(ILOG_WIN_PLATFORM "x64_win32")
+  ELSE()
+    SET(ILOG_WIN_COMPILER "x86_${ILOG_WIN_COMPILER}")
+    SET(ILOG_WIN_PLATFORM "x86_win32")
+  ENDIF()
+ENDIF()
+
+FIND_PATH(ILOG_CPLEX_ROOT_DIR
+  NAMES include/ilcplex
+  HINTS ${ILOG_ROOT_DIR}/cplex ${ILOG_ROOT_DIR}/cplex121
+  ${ILOG_ROOT_DIR}/cplex122 ${ILOG_ROOT_DIR}/cplex123
+  DOC "CPLEX root directory"
+  NO_DEFAULT_PATH
+)
+
+FIND_PATH(ILOG_CONCERT_ROOT_DIR
+  NAMES include/ilconcert
+  HINTS ${ILOG_ROOT_DIR}/concert ${ILOG_ROOT_DIR}/concert29
+  DOC "CONCERT root directory"
+  NO_DEFAULT_PATH
+)
+
+FIND_PATH(ILOG_CPLEX_INCLUDE_DIR
+  ilcplex/cplex.h
+  HINTS ${ILOG_CPLEX_ROOT_DIR}/include
+  NO_DEFAULT_PATH
+)
+
+FIND_PATH(ILOG_CONCERT_INCLUDE_DIR
+  ilconcert/ilobasic.h
+  HINTS ${ILOG_CONCERT_ROOT_DIR}/include
+  NO_DEFAULT_PATH
+)
+
+FIND_LIBRARY(ILOG_CPLEX_LIBRARY
+  cplex cplex121 cplex122 cplex123 cplex124
+  HINTS ${ILOG_CPLEX_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
+  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
+  ${ILOG_CPLEX_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
+  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
+  ${ILOG_CPLEX_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
+  NO_DEFAULT_PATH
+  )
+
+FIND_LIBRARY(ILOG_CONCERT_LIBRARY
+  concert
+  HINTS ${ILOG_CONCERT_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
+  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
+  ${ILOG_CONCERT_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
+  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
+  ${ILOG_CONCERT_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
+  NO_DEFAULT_PATH
+  )
+
+FIND_FILE(ILOG_CPLEX_DLL
+  cplex121.dll cplex122.dll cplex123.dll cplex124.dll
+  HINTS ${ILOG_CPLEX_ROOT_DIR}/bin/${ILOG_WIN_PLATFORM}
+  NO_DEFAULT_PATH
+  )
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ILOG
+  DEFAULT_MSG ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR
+  )
+
+IF(ILOG_FOUND)
+  SET(ILOG_INCLUDE_DIRS ${ILOG_CPLEX_INCLUDE_DIR} ${ILOG_CONCERT_INCLUDE_DIR})
+  SET(ILOG_LIBRARIES ${ILOG_CPLEX_LIBRARY} ${ILOG_CONCERT_LIBRARY})
+  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    # SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
+    SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread")
+  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ENDIF(ILOG_FOUND)
+
+MARK_AS_ADVANCED(
+  ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR ILOG_CPLEX_DLL
+  ILOG_CONCERT_LIBRARY ILOG_CONCERT_INCLUDE_DIR ILOG_CONCERT_DLL
+  )
diff --git a/cmake/FindSOPLEX.cmake b/cmake/FindSOPLEX.cmake
new file mode 100644
index 0000000..d27cff0
--- /dev/null
+++ b/cmake/FindSOPLEX.cmake
@@ -0,0 +1,23 @@
+SET(SOPLEX_ROOT_DIR "" CACHE PATH "SoPlex root directory")
+
+FIND_PATH(SOPLEX_INCLUDE_DIR
+  soplex.h
+  HINTS ${SOPLEX_ROOT_DIR}/src
+)
+FIND_LIBRARY(SOPLEX_LIBRARY
+  soplex
+  HINTS ${SOPLEX_ROOT_DIR}/lib
+)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SOPLEX DEFAULT_MSG SOPLEX_LIBRARY SOPLEX_INCLUDE_DIR)
+
+IF(SOPLEX_FOUND)
+  SET(SOPLEX_INCLUDE_DIRS ${SOPLEX_INCLUDE_DIR})
+  SET(SOPLEX_LIBRARIES ${SOPLEX_LIBRARY})
+  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    SET(SOPLEX_LIBRARIES "${SOPLEX_LIBRARIES};z")
+  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ENDIF(SOPLEX_FOUND)
+
+MARK_AS_ADVANCED(SOPLEX_LIBRARY SOPLEX_INCLUDE_DIR)
diff --git a/cmake/LEMONConfig.cmake.in b/cmake/LEMONConfig.cmake.in
new file mode 100644
index 0000000..b0d2d8b
--- /dev/null
+++ b/cmake/LEMONConfig.cmake.in
@@ -0,0 +1,13 @@
+SET(LEMON_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include" CACHE PATH "LEMON include directory")
+SET(LEMON_INCLUDE_DIRS "${LEMON_INCLUDE_DIR}")
+
+IF(UNIX)
+  SET(LEMON_LIB_NAME "libemon.a")
+ELSEIF(WIN32)
+  SET(LEMON_LIB_NAME "lemon.lib")
+ENDIF(UNIX)
+
+SET(LEMON_LIBRARY "@CMAKE_INSTALL_PREFIX@/lib/${LEMON_LIB_NAME}" CACHE FILEPATH "LEMON library")
+SET(LEMON_LIBRARIES "${LEMON_LIBRARY}")
+
+MARK_AS_ADVANCED(LEMON_LIBRARY LEMON_INCLUDE_DIR)
diff --git a/cmake/nsis/lemon.ico b/cmake/nsis/lemon.ico
new file mode 100644
index 0000000..bbfd8c1
Binary files /dev/null and b/cmake/nsis/lemon.ico differ
diff --git a/cmake/nsis/uninstall.ico b/cmake/nsis/uninstall.ico
new file mode 100644
index 0000000..7495f7c
Binary files /dev/null and b/cmake/nsis/uninstall.ico differ
diff --git a/cmake/version.cmake b/cmake/version.cmake
new file mode 100644
index 0000000..91369e1
--- /dev/null
+++ b/cmake/version.cmake
@@ -0,0 +1 @@
+SET(LEMON_VERSION "1.3.1" CACHE STRING "LEMON version string.")
diff --git a/cmake/version.cmake.in b/cmake/version.cmake.in
new file mode 100644
index 0000000..7cd4b68
--- /dev/null
+++ b/cmake/version.cmake.in
@@ -0,0 +1 @@
+SET(LEMON_VERSION "@LEMON_VERSION@" CACHE STRING "LEMON version string.")
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
new file mode 100644
index 0000000..b6c11e2
--- /dev/null
+++ b/contrib/CMakeLists.txt
@@ -0,0 +1,19 @@
+INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}
+  ${PROJECT_BINARY_DIR}
+)
+
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
+
+# Uncomment (and adjust) the following two lines. 'myprog' is the name
+# of the final executable ('.exe' will automatically be added to the
+# name on Windows) and 'myprog-main.cc' is the source code it is
+# compiled from. You can add more source files separated by
+# whitespaces. Moreover, you can add multiple similar blocks if you
+# want to build more than one executables.
+
+# ADD_EXECUTABLE(myprog myprog-main.cc)
+# TARGET_LINK_LIBRARIES(myprog lemon)
+
diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt
new file mode 100644
index 0000000..e0566f4
--- /dev/null
+++ b/demo/CMakeLists.txt
@@ -0,0 +1,19 @@
+INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}
+  ${PROJECT_BINARY_DIR}
+)
+
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
+
+SET(DEMOS
+  arg_parser_demo
+  graph_to_eps_demo
+  lgf_demo
+)
+
+FOREACH(DEMO_NAME ${DEMOS})
+  ADD_EXECUTABLE(${DEMO_NAME} ${DEMO_NAME}.cc)
+  TARGET_LINK_LIBRARIES(${DEMO_NAME} lemon)
+ENDFOREACH()
diff --git a/demo/arg_parser_demo.cc b/demo/arg_parser_demo.cc
new file mode 100644
index 0000000..1bafac0
--- /dev/null
+++ b/demo/arg_parser_demo.cc
@@ -0,0 +1,112 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup demos
+///\file
+///\brief Argument parser demo
+///
+/// This example shows how the argument parser can be used.
+///
+/// \include arg_parser_demo.cc
+
+#include <lemon/arg_parser.h>
+
+using namespace lemon;
+int main(int argc, char **argv)
+{
+  // Initialize the argument parser
+  ArgParser ap(argc, argv);
+  int i;
+  std::string s;
+  double d = 1.0;
+  bool b, nh;
+  bool g1, g2, g3;
+
+  // Add a mandatory integer option with storage reference
+  ap.refOption("n", "An integer input.", i, true);
+  // Add a double option with storage reference (the default value is 1.0)
+  ap.refOption("val", "A double input.", d);
+  // Add a double option without storage reference (the default value is 3.14)
+  ap.doubleOption("val2", "A double input.", 3.14);
+  // Set synonym for -val option
+  ap.synonym("vals", "val");
+  // Add a string option
+  ap.refOption("name", "A string input.", s);
+  // Add bool options
+  ap.refOption("f", "A switch.", b)
+    .refOption("nohelp", "", nh)
+    .refOption("gra", "Choice A", g1)
+    .refOption("grb", "Choice B", g2)
+    .refOption("grc", "Choice C", g3);
+  // Bundle -gr* options into a group
+  ap.optionGroup("gr", "gra")
+    .optionGroup("gr", "grb")
+    .optionGroup("gr", "grc");
+  // Set the group mandatory
+  ap.mandatoryGroup("gr");
+  // Set the options of the group exclusive (only one option can be given)
+  ap.onlyOneGroup("gr");
+  // Add non-parsed arguments (e.g. input files)
+  ap.other("infile", "The input file.")
+    .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)
+  // 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
+  std::cout << "Parameters of '" << ap.commandName() << "':\n";
+
+  std::cout << "  Value of -n: " << i << std::endl;
+  if(ap.given("val")) std::cout << "  Value of -val: " << d << std::endl;
+  if(ap.given("val2")) {
+    d = ap["val2"];
+    std::cout << "  Value of -val2: " << d << std::endl;
+  }
+  if(ap.given("name")) std::cout << "  Value of -name: " << s << std::endl;
+  if(ap.given("f")) std::cout << "  -f is given\n";
+  if(ap.given("nohelp")) std::cout << "  Value of -nohelp: " << nh << std::endl;
+  if(ap.given("gra")) std::cout << "  -gra is given\n";
+  if(ap.given("grb")) std::cout << "  -grb is given\n";
+  if(ap.given("grc")) std::cout << "  -grc is given\n";
+
+  switch(ap.files().size()) {
+  case 0:
+    std::cout << "  No file argument was given.\n";
+    break;
+  case 1:
+    std::cout << "  1 file argument was given. It is:\n";
+    break;
+  default:
+    std::cout << "  "
+              << ap.files().size() << " file arguments were given. They are:\n";
+  }
+  for(unsigned int i=0;i<ap.files().size();++i)
+    std::cout << "    '" << ap.files()[i] << "'\n";
+
+  return 0;
+}
diff --git a/demo/digraph.lgf b/demo/digraph.lgf
new file mode 100644
index 0000000..83ba7da
--- /dev/null
+++ b/demo/digraph.lgf
@@ -0,0 +1,29 @@
+ at nodes
+label
+0
+1
+2
+3
+4
+5
+6
+7
+ at arcs
+		label capacity
+0 	1 	0  	  16
+0 	2 	1 	  12
+0 	3 	2 	  20
+1 	2 	3 	  10
+1 	4 	4 	  10
+1 	5 	5 	  13
+2 	3 	6 	  10
+2 	4 	7 	  8
+2 	6 	8 	  8
+5 	3 	9 	  20
+3 	6 	10 	  25
+4 	7 	11 	  15
+5 	7 	12 	  15
+6 	7 	13 	  18
+ at attributes
+source 0
+target 7
diff --git a/demo/graph_to_eps_demo.cc b/demo/graph_to_eps_demo.cc
new file mode 100644
index 0000000..f2f55a9
--- /dev/null
+++ b/demo/graph_to_eps_demo.cc
@@ -0,0 +1,206 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+/// \ingroup demos
+/// \file
+/// \brief Demo of the graph drawing function \ref graphToEps()
+///
+/// This demo program shows examples how to use the function \ref
+/// graphToEps(). It takes no input but simply creates seven
+/// <tt>.eps</tt> files demonstrating the capability of \ref
+/// graphToEps(), and showing how to draw directed graphs,
+/// how to handle parallel egdes, how to change the properties (like
+/// color, shape, size, title etc.) of nodes and arcs individually
+/// using appropriate graph maps.
+///
+/// \include graph_to_eps_demo.cc
+
+#include<lemon/list_graph.h>
+#include<lemon/graph_to_eps.h>
+#include<lemon/math.h>
+
+using namespace std;
+using namespace lemon;
+
+int main()
+{
+  Palette palette;
+  Palette paletteW(true);
+
+  // Create a small digraph
+  ListDigraph g;
+  typedef ListDigraph::Node Node;
+  typedef ListDigraph::NodeIt NodeIt;
+  typedef ListDigraph::Arc Arc;
+  typedef dim2::Point<int> Point;
+
+  Node n1=g.addNode();
+  Node n2=g.addNode();
+  Node n3=g.addNode();
+  Node n4=g.addNode();
+  Node n5=g.addNode();
+
+  ListDigraph::NodeMap<Point> coords(g);
+  ListDigraph::NodeMap<double> sizes(g);
+  ListDigraph::NodeMap<int> colors(g);
+  ListDigraph::NodeMap<int> shapes(g);
+  ListDigraph::ArcMap<int> acolors(g);
+  ListDigraph::ArcMap<int> widths(g);
+
+  coords[n1]=Point(50,50);  sizes[n1]=1; colors[n1]=1; shapes[n1]=0;
+  coords[n2]=Point(50,70);  sizes[n2]=2; colors[n2]=2; shapes[n2]=2;
+  coords[n3]=Point(70,70);  sizes[n3]=1; colors[n3]=3; shapes[n3]=0;
+  coords[n4]=Point(70,50);  sizes[n4]=2; colors[n4]=4; shapes[n4]=1;
+  coords[n5]=Point(85,60);  sizes[n5]=3; colors[n5]=5; shapes[n5]=2;
+
+  Arc a;
+
+  a=g.addArc(n1,n2); acolors[a]=0; widths[a]=1;
+  a=g.addArc(n2,n3); acolors[a]=0; widths[a]=1;
+  a=g.addArc(n3,n5); acolors[a]=0; widths[a]=3;
+  a=g.addArc(n5,n4); acolors[a]=0; widths[a]=1;
+  a=g.addArc(n4,n1); acolors[a]=0; widths[a]=1;
+  a=g.addArc(n2,n4); acolors[a]=1; widths[a]=2;
+  a=g.addArc(n3,n4); acolors[a]=2; widths[a]=1;
+
+  IdMap<ListDigraph,Node> id(g);
+
+  // Create .eps files showing the digraph with different options
+  cout << "Create 'graph_to_eps_demo_out_1_pure.eps'" << endl;
+  graphToEps(g,"graph_to_eps_demo_out_1_pure.eps").
+    coords(coords).
+    title("Sample .eps figure").
+    copyright("(C) 2003-2009 LEMON Project").
+    run();
+
+  cout << "Create 'graph_to_eps_demo_out_2.eps'" << endl;
+  graphToEps(g,"graph_to_eps_demo_out_2.eps").
+    coords(coords).
+    title("Sample .eps figure").
+    copyright("(C) 2003-2009 LEMON Project").
+    absoluteNodeSizes().absoluteArcWidths().
+    nodeScale(2).nodeSizes(sizes).
+    nodeShapes(shapes).
+    nodeColors(composeMap(palette,colors)).
+    arcColors(composeMap(palette,acolors)).
+    arcWidthScale(.4).arcWidths(widths).
+    nodeTexts(id).nodeTextSize(3).
+    run();
+
+  cout << "Create 'graph_to_eps_demo_out_3_arr.eps'" << endl;
+  graphToEps(g,"graph_to_eps_demo_out_3_arr.eps").
+    title("Sample .eps figure (with arrowheads)").
+    copyright("(C) 2003-2009 LEMON Project").
+    absoluteNodeSizes().absoluteArcWidths().
+    nodeColors(composeMap(palette,colors)).
+    coords(coords).
+    nodeScale(2).nodeSizes(sizes).
+    nodeShapes(shapes).
+    arcColors(composeMap(palette,acolors)).
+    arcWidthScale(.4).arcWidths(widths).
+    nodeTexts(id).nodeTextSize(3).
+    drawArrows().arrowWidth(2).arrowLength(2).
+    run();
+
+  // Add more arcs to the digraph
+  a=g.addArc(n1,n4); acolors[a]=2; widths[a]=1;
+  a=g.addArc(n4,n1); acolors[a]=1; widths[a]=2;
+
+  a=g.addArc(n1,n2); acolors[a]=1; widths[a]=1;
+  a=g.addArc(n1,n2); acolors[a]=2; widths[a]=1;
+  a=g.addArc(n1,n2); acolors[a]=3; widths[a]=1;
+  a=g.addArc(n1,n2); acolors[a]=4; widths[a]=1;
+  a=g.addArc(n1,n2); acolors[a]=5; widths[a]=1;
+  a=g.addArc(n1,n2); acolors[a]=6; widths[a]=1;
+  a=g.addArc(n1,n2); acolors[a]=7; widths[a]=1;
+
+  cout << "Create 'graph_to_eps_demo_out_4_par.eps'" << endl;
+  graphToEps(g,"graph_to_eps_demo_out_4_par.eps").
+    title("Sample .eps figure (parallel arcs)").
+    copyright("(C) 2003-2009 LEMON Project").
+    absoluteNodeSizes().absoluteArcWidths().
+    nodeShapes(shapes).
+    coords(coords).
+    nodeScale(2).nodeSizes(sizes).
+    nodeColors(composeMap(palette,colors)).
+    arcColors(composeMap(palette,acolors)).
+    arcWidthScale(.4).arcWidths(widths).
+    nodeTexts(id).nodeTextSize(3).
+    enableParallel().parArcDist(1.5).
+    run();
+
+  cout << "Create 'graph_to_eps_demo_out_5_par_arr.eps'" << endl;
+  graphToEps(g,"graph_to_eps_demo_out_5_par_arr.eps").
+    title("Sample .eps figure (parallel arcs and arrowheads)").
+    copyright("(C) 2003-2009 LEMON Project").
+    absoluteNodeSizes().absoluteArcWidths().
+    nodeScale(2).nodeSizes(sizes).
+    coords(coords).
+    nodeShapes(shapes).
+    nodeColors(composeMap(palette,colors)).
+    arcColors(composeMap(palette,acolors)).
+    arcWidthScale(.3).arcWidths(widths).
+    nodeTexts(id).nodeTextSize(3).
+    enableParallel().parArcDist(1).
+    drawArrows().arrowWidth(1).arrowLength(1).
+    run();
+
+  cout << "Create 'graph_to_eps_demo_out_6_par_arr_a4.eps'" << endl;
+  graphToEps(g,"graph_to_eps_demo_out_6_par_arr_a4.eps").
+    title("Sample .eps figure (fits to A4)").
+    copyright("(C) 2003-2009 LEMON Project").
+    scaleToA4().
+    absoluteNodeSizes().absoluteArcWidths().
+    nodeScale(2).nodeSizes(sizes).
+    coords(coords).
+    nodeShapes(shapes).
+    nodeColors(composeMap(palette,colors)).
+    arcColors(composeMap(palette,acolors)).
+    arcWidthScale(.3).arcWidths(widths).
+    nodeTexts(id).nodeTextSize(3).
+    enableParallel().parArcDist(1).
+    drawArrows().arrowWidth(1).arrowLength(1).
+    run();
+
+  // Create an .eps file showing the colors of a default Palette
+  ListDigraph h;
+  ListDigraph::NodeMap<int> hcolors(h);
+  ListDigraph::NodeMap<Point> hcoords(h);
+
+  int cols=int(std::sqrt(double(palette.size())));
+  for(int i=0;i<int(paletteW.size());i++) {
+    Node n=h.addNode();
+    hcoords[n]=Point(1+i%cols,1+i/cols);
+    hcolors[n]=i;
+  }
+
+  cout << "Create 'graph_to_eps_demo_out_7_colors.eps'" << endl;
+  graphToEps(h,"graph_to_eps_demo_out_7_colors.eps").
+    scale(60).
+    title("Sample .eps figure (Palette demo)").
+    copyright("(C) 2003-2009 LEMON Project").
+    coords(hcoords).
+    absoluteNodeSizes().absoluteArcWidths().
+    nodeScale(.45).
+    distantColorNodeTexts().
+    nodeTexts(hcolors).nodeTextSize(.6).
+    nodeColors(composeMap(paletteW,hcolors)).
+    run();
+
+  return 0;
+}
diff --git a/demo/lgf_demo.cc b/demo/lgf_demo.cc
new file mode 100644
index 0000000..e2d31cd
--- /dev/null
+++ b/demo/lgf_demo.cc
@@ -0,0 +1,70 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup demos
+///\file
+///\brief Demonstrating graph input and output
+///
+/// This program gives an example of how to read and write a digraph
+/// and additional maps from/to a stream or a file using the
+/// \ref lgf-format "LGF" format.
+///
+/// The \c "digraph.lgf" file:
+/// \include digraph.lgf
+///
+/// And the program which reads it and prints the digraph to the
+/// standard output:
+/// \include lgf_demo.cc
+
+#include <iostream>
+#include <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/lgf_writer.h>
+
+using namespace lemon;
+
+int main() {
+  SmartDigraph g;
+  SmartDigraph::ArcMap<int> cap(g);
+  SmartDigraph::Node s, t;
+
+  try {
+    digraphReader(g, "digraph.lgf"). // read the directed graph into g
+      arcMap("capacity", cap).       // read the 'capacity' arc map into cap
+      node("source", s).             // read 'source' node to s
+      node("target", t).             // read 'target' node to t
+      run();
+  } catch (Exception& error) { // check if there was any error
+    std::cerr << "Error: " << error.what() << std::endl;
+    return -1;
+  }
+
+  std::cout << "A digraph is read from 'digraph.lgf'." << std::endl;
+  std::cout << "Number of nodes: " << countNodes(g) << std::endl;
+  std::cout << "Number of arcs: " << countArcs(g) << std::endl;
+
+  std::cout << "We can write it to the standard output:" << std::endl;
+
+  digraphWriter(g).                // write g to the standard output
+    arcMap("capacity", cap).       // write cap into 'capacity'
+    node("source", s).             // write s to 'source'
+    node("target", t).             // write t to 'target'
+    run();
+
+  return 0;
+}
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
new file mode 100644
index 0000000..ba38165
--- /dev/null
+++ b/doc/CMakeLists.txt
@@ -0,0 +1,86 @@
+SET(PACKAGE_NAME ${PROJECT_NAME})
+SET(PACKAGE_VERSION ${PROJECT_VERSION})
+SET(abs_top_srcdir ${PROJECT_SOURCE_DIR})
+SET(abs_top_builddir ${PROJECT_BINARY_DIR})
+
+SET(LEMON_DOC_SOURCE_BROWSER "NO" CACHE STRING "Include source into the doc (YES/NO).")
+SET(LEMON_DOC_USE_MATHJAX "NO" CACHE STRING "Use MathJax to display math formulae (YES/NO).")
+SET(LEMON_DOC_MATHJAX_RELPATH "http://www.mathjax.org/mathjax" CACHE STRING "MathJax library location.")
+
+SET(LEMON_DOC_LIBSTDC++_URL
+  "http://gcc.gnu.org/onlinedocs/gcc-4.7.3/libstdc++/api"
+  CACHE STRING "GCC libstdc++ doxygen doc url.")
+
+
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
+  ${PROJECT_BINARY_DIR}/doc/Doxyfile
+  @ONLY
+)
+
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/doc/mainpage.dox.in
+  ${PROJECT_BINARY_DIR}/doc/mainpage.dox
+  @ONLY
+)
+
+# Copy doc from source (if exists)
+IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/html AND 
+    NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html/index.html)
+  MESSAGE(STATUS "Copy doc from source tree")
+  EXECUTE_PROCESS(
+    COMMAND cmake -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/html ${CMAKE_CURRENT_BINARY_DIR}/html
+    )
+ENDIF()
+
+IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
+  FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
+  SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
+  ADD_CUSTOM_TARGET(html
+    COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
+    COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r20 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/adaptors2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/adaptors2.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r40 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/tsp.png ${CMAKE_CURRENT_SOURCE_DIR}/images/tsp.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
+    COMMAND ${CMAKE_COMMAND} -E remove_directory html
+    COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  )
+
+  SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC)
+
+  IF(UNIX)
+    INSTALL(
+      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
+      DESTINATION share/doc/lemon/html
+      COMPONENT html_documentation
+    )
+  ELSEIF(WIN32)
+    INSTALL(
+      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
+      DESTINATION doc
+      COMPONENT html_documentation
+    )
+  ENDIF()
+
+ENDIF()
+
+IF(WGET_FOUND)
+ADD_CUSTOM_TARGET(update-external-tags
+  COMMAND ${WGET_EXECUTABLE} -N ${LEMON_DOC_LIBSTDC++_URL}/libstdc++.tag
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  )
+ENDIF()
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
new file mode 100644
index 0000000..0fdd04e
--- /dev/null
+++ b/doc/Doxyfile.in
@@ -0,0 +1,292 @@
+# Doxyfile 1.7.3
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING      = UTF-8
+PROJECT_NAME           = 
+PROJECT_NUMBER         = 
+PROJECT_BRIEF          =
+PROJECT_LOGO           =
+OUTPUT_DIRECTORY       = 
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = NO
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        = "@abs_top_srcdir@"
+STRIP_FROM_INC_PATH    = "@abs_top_srcdir@"
+SHORT_NAMES            = YES
+JAVADOC_AUTOBRIEF      = NO
+QT_AUTOBRIEF           = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS           = NO
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+OPTIMIZE_FOR_FORTRAN   = NO
+OPTIMIZE_OUTPUT_VHDL   = NO
+EXTENSION_MAPPING      =
+BUILTIN_STL_SUPPORT    = YES
+CPP_CLI_SUPPORT        = NO
+SIP_SUPPORT            = NO
+IDL_PROPERTY_SUPPORT   = YES
+DISTRIBUTE_GROUP_DOC   = NO
+SUBGROUPING            = YES
+TYPEDEF_HIDES_STRUCT   = NO
+SYMBOL_CACHE_SIZE      = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = NO
+EXTRACT_LOCAL_METHODS  = NO
+EXTRACT_ANON_NSPACES   = NO
+HIDE_UNDOC_MEMBERS     = YES
+HIDE_UNDOC_CLASSES     = YES
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = YES
+SHOW_INCLUDE_FILES     = YES
+FORCE_LOCAL_INCLUDES   = NO
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = NO
+SORT_BRIEF_DOCS        = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES       = NO
+SORT_BY_SCOPE_NAME     = NO
+STRICT_PROTO_MATCHING  = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 5
+SHOW_USED_FILES        = NO
+SHOW_DIRECTORIES       = YES
+SHOW_FILES             = YES
+SHOW_NAMESPACES        = YES
+FILE_VERSION_FILTER    = 
+LAYOUT_FILE            = "@abs_top_srcdir@/doc/DoxygenLayout.xml"
+CITE_BIB_FILES         = "@abs_top_srcdir@/doc/references.bib"
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = doxygen.log
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = "@abs_top_srcdir@/doc" \
+                         "@abs_top_srcdir@/lemon" \
+                         "@abs_top_srcdir@/lemon/bits" \
+                         "@abs_top_srcdir@/lemon/concepts" \
+                         "@abs_top_srcdir@/demo" \
+                         "@abs_top_srcdir@/contrib" \
+                         "@abs_top_srcdir@/tools" \
+                         "@abs_top_srcdir@/test/test_tools.h" \
+                         "@abs_top_builddir@/doc/mainpage.dox"
+INPUT_ENCODING         = UTF-8
+FILE_PATTERNS          = *.h \
+                         *.cc \
+                         *.dox
+RECURSIVE              = NO
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXCLUDE_SYMBOLS        = 
+EXAMPLE_PATH           = "@abs_top_srcdir@/demo" \
+                         "@abs_top_srcdir@/LICENSE" \
+                         "@abs_top_srcdir@/doc"
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = "@abs_top_srcdir@/doc/images" \
+                         "@abs_top_builddir@/doc/gen-images"
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+FILTER_SOURCE_PATTERNS =
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = @LEMON_DOC_SOURCE_BROWSER@
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 2
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_COLORSTYLE_HUE    = 220
+HTML_COLORSTYLE_SAT    = 100
+HTML_COLORSTYLE_GAMMA  = 80
+HTML_TIMESTAMP         = YES
+HTML_ALIGN_MEMBERS     = YES
+HTML_DYNAMIC_SECTIONS  = YES
+GENERATE_DOCSET        = NO
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME  = Publisher
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+CHM_INDEX_ENCODING     = 
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+GENERATE_QHP           = NO
+QCH_FILE               = 
+QHP_NAMESPACE          = org.doxygen.Project
+QHP_VIRTUAL_FOLDER     = doc
+QHP_CUST_FILTER_NAME   =
+QHP_CUST_FILTER_ATTRS  =
+QHP_SECT_FILTER_ATTRS  =
+QHG_LOCATION           = 
+GENERATE_ECLIPSEHELP   = NO
+ECLIPSE_DOC_ID         = org.doxygen.Project
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+USE_INLINE_TREES       = NO
+TREEVIEW_WIDTH         = 250
+EXT_LINKS_IN_WINDOW    = NO
+FORMULA_FONTSIZE       = 10
+FORMULA_TRANSPARENT    = YES
+USE_MATHJAX            = @LEMON_DOC_USE_MATHJAX@
+MATHJAX_RELPATH        = @LEMON_DOC_MATHJAX_RELPATH@
+SEARCHENGINE           = YES
+SERVER_BASED_SEARCH    = NO
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = YES
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = amsmath \
+                         amssymb
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = YES
+USE_PDFLATEX           = YES
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+LATEX_SOURCE_CODE      = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = DOXYGEN
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES               = "@abs_top_builddir@/doc/libstdc++.tag = @LEMON_DOC_LIBSTDC++_URL@"
+GENERATE_TAGFILE       = html/lemon.tag
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = NO
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+MSCGEN_PATH            = 
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = YES
+DOT_NUM_THREADS        = 0
+DOT_FONTNAME           = FreeSans
+DOT_FONTSIZE           = 10
+DOT_FONTPATH           = 
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = NO
+GROUP_GRAPHS           = NO
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = NO
+INCLUDED_BY_GRAPH      = NO
+CALL_GRAPH             = NO
+CALLER_GRAPH           = NO
+GRAPHICAL_HIERARCHY    = NO
+DIRECTORY_GRAPH        = NO
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MSCFILE_DIRS           =
+DOT_GRAPH_MAX_NODES    = 50
+MAX_DOT_GRAPH_DEPTH    = 0
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
diff --git a/doc/DoxygenLayout.xml b/doc/DoxygenLayout.xml
new file mode 100644
index 0000000..8a01ef4
--- /dev/null
+++ b/doc/DoxygenLayout.xml
@@ -0,0 +1,181 @@
+<doxygenlayout version="1.0">
+  <!-- Navigation index tabs for HTML output -->
+  <navindex>
+    <tab type="mainpage" visible="yes" title=""/>
+    <tab type="modules" visible="yes" title="" intro=""/>
+    <tab type="classes" visible="yes" title="">
+      <tab type="classes" visible="yes" title="" intro=""/>
+      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="hierarchy" visible="yes" title="" intro=""/>
+      <tab type="classmembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="namespaces" visible="yes" title="">
+      <tab type="namespaces" visible="yes" title="" intro=""/>
+      <tab type="namespacemembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="files" visible="yes" title="">
+      <tab type="files" visible="yes" title="" intro=""/>
+      <tab type="globals" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="examples" visible="yes" title="" intro=""/>
+    <tab type="pages" visible="yes" title="" intro=""/>
+  </navindex>
+
+  <!-- Layout definition for a class page -->
+  <class>
+    <briefdescription visible="no"/>
+    <detaileddescription title=""/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <inheritancegraph visible="$CLASS_GRAPH"/>
+    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+    <allmemberslink visible="yes"/>
+    <memberdecl>
+      <membergroups visible="yes"/>
+      <nestedclasses visible="yes" title=""/>
+      <publictypes title=""/>
+      <publicslots title=""/>
+      <signals title=""/>
+      <publicmethods title=""/>
+      <publicstaticmethods title=""/>
+      <publicattributes title=""/>
+      <publicstaticattributes title=""/>
+      <protectedtypes title=""/>
+      <protectedslots title=""/>
+      <protectedmethods title=""/>
+      <protectedstaticmethods title=""/>
+      <protectedattributes title=""/>
+      <protectedstaticattributes title=""/>
+      <packagetypes title=""/>
+      <packagemethods title=""/>
+      <packagestaticmethods title=""/>
+      <packageattributes title=""/>
+      <packagestaticattributes title=""/>
+      <properties title=""/>
+      <events title=""/>
+      <privatetypes title=""/>
+      <privateslots title=""/>
+      <privatemethods title=""/>
+      <privatestaticmethods title=""/>
+      <privateattributes title=""/>
+      <privatestaticattributes title=""/>
+      <friends title=""/>
+      <related title="" subtitle=""/>
+    </memberdecl>
+    <memberdef>
+      <typedefs title=""/>
+      <enums title=""/>
+      <constructors title=""/>
+      <functions title=""/>
+      <related title=""/>
+      <variables title=""/>
+      <properties title=""/>
+      <events title=""/>
+    </memberdef>
+    <usedfiles visible="$SHOW_USED_FILES"/>
+    <authorsection visible="yes"/>
+  </class>
+
+  <!-- Layout definition for a namespace page -->
+  <namespace>
+    <briefdescription visible="no"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <nestednamespaces visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <membergroups visible="yes"/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdecl>
+    <memberdef>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </namespace>
+
+  <!-- Layout definition for a file page -->
+  <file>
+    <briefdescription visible="no"/>
+    <detaileddescription title=""/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <includegraph visible="$INCLUDE_GRAPH"/>
+    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+    <sourcelink visible="yes"/>
+    <memberdecl>
+      <classes visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdecl>
+    <memberdef>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection/>
+  </file>
+
+  <!-- Layout definition for a group page -->
+  <group>
+    <briefdescription visible="no"/>
+    <detaileddescription title=""/>
+    <groupgraph visible="$GROUP_GRAPHS"/>
+    <memberdecl>
+      <classes visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <dirs visible="yes" title=""/>
+      <nestedgroups visible="yes" title=""/>
+      <files visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+    </memberdecl>
+    <memberdef>
+      <pagedocs/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </group>
+
+  <!-- Layout definition for a directory page -->
+  <directory>
+    <briefdescription visible="no"/>
+    <detaileddescription title=""/>
+    <directorygraph visible="yes"/>
+    <memberdecl>
+      <dirs visible="yes"/>
+      <files visible="yes"/>
+    </memberdecl>
+  </directory>
+</doxygenlayout>
diff --git a/doc/coding_style.dox b/doc/coding_style.dox
new file mode 100644
index 0000000..80f1050
--- /dev/null
+++ b/doc/coding_style.dox
@@ -0,0 +1,127 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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.
+ *
+ */
+
+/*!
+
+\page coding_style LEMON Coding Style
+
+\section naming_conv Naming Conventions
+
+In order to make development easier we have made some conventions
+according to coding style. These include names of types, classes,
+functions, variables, constants and exceptions. If these conventions
+are met in one's code then it is easier to read and maintain
+it. Please comply with these conventions if you want to contribute
+developing LEMON library.
+
+\note When the coding style requires the capitalization of an abbreviation,
+only the first letter should be upper case.
+
+\code
+XmlReader
+\endcode
+
+
+\warning In some cases we diverge from these rules.
+This is primary done because STL uses different naming convention and
+in certain cases
+it is beneficial to provide STL compatible interface.
+
+\subsection cs-files File Names
+
+The header file names should look like the following.
+
+\code
+header_file.h
+\endcode
+
+Note that all standard LEMON headers are located in the \c lemon subdirectory,
+so you should include them from C++ source like this:
+
+\code
+#include <lemon/header_file.h>
+\endcode
+
+The source code files use the same style and they have '.cc' extension.
+
+\code
+source_code.cc
+\endcode
+
+\subsection cs-class Classes and other types
+
+The name of a class or any type should look like the following.
+
+\code
+AllWordsCapitalizedWithoutUnderscores
+\endcode
+
+\subsection cs-func Methods and other functions
+
+The name of a function should look like the following.
+
+\code
+firstWordLowerCaseRestCapitalizedWithoutUnderscores
+\endcode
+
+\subsection cs-funcs Constants, Macros
+
+The names of constants and macros should look like the following.
+
+\code
+ALL_UPPER_CASE_WITH_UNDERSCORES
+\endcode
+
+\subsection cs-loc-var Class and instance member variables, auto variables
+
+The names of class and instance member variables and auto variables
+(=variables used locally in methods) should look like the following.
+
+\code
+all_lower_case_with_underscores
+\endcode
+
+\subsection pri-loc-var Private member variables
+
+Private member variables should start with underscore.
+
+\code
+_start_with_underscore
+\endcode
+
+\subsection cs-excep Exceptions
+
+When writing exceptions please comply the following naming conventions.
+
+\code
+ClassNameEndsWithException
+\endcode
+
+or
+
+\code
+ClassNameEndsWithError
+\endcode
+
+\section header-template Template Header File
+
+Each LEMON header file should look like this:
+
+\include template.h
+
+*/
diff --git a/doc/dirs.dox b/doc/dirs.dox
new file mode 100644
index 0000000..8139060
--- /dev/null
+++ b/doc/dirs.dox
@@ -0,0 +1,90 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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.
+ *
+ */
+
+/**
+\dir demo
+\brief A collection of demo applications.
+
+This directory contains several simple demo applications, mainly
+for educational purposes.
+*/
+
+/**
+\dir doc
+\brief Auxiliary (and the whole generated) documentation.
+
+This directory contains some auxiliary pages and the whole generated
+documentation.
+*/
+
+/**
+\dir contrib
+\brief Directory for user contributed source codes.
+
+You can place your own C++ code using LEMON into this directory, which
+will compile to an executable along with LEMON when you build the
+library. This is probably the easiest way of compiling short to medium
+codes, for this does require neither a LEMON installed system-wide nor
+adding several paths to the compiler.
+
+Please have a look at <tt>contrib/CMakeLists.txt</tt> for
+instruction on how to add your own files into the build process.  */
+
+/**
+\dir test
+\brief Test programs.
+
+This directory contains several test programs that check the consistency
+of the code.
+*/
+
+/**
+\dir tools
+\brief Some useful executables.
+
+This directory contains the sources of some useful complete executables.
+*/
+
+/**
+\dir lemon
+\brief Base include directory of LEMON.
+
+This is the base directory of LEMON includes, so each include file must be
+prefixed with this, e.g.
+\code
+#include<lemon/list_graph.h>
+#include<lemon/dijkstra.h>
+\endcode
+*/
+
+/**
+\dir concepts
+\brief Concept descriptors and checking classes.
+
+This directory contains the concept descriptors and concept checking tools.
+For more information see the \ref concept "Concepts" module.
+*/
+
+/**
+\dir bits
+\brief Auxiliary tools for implementation.
+
+This directory contains some auxiliary classes for implementing graphs,
+maps and some other classes.
+As a user you typically don't have to deal with these files.
+*/
diff --git a/doc/groups.dox b/doc/groups.dox
new file mode 100644
index 0000000..57bfee9
--- /dev/null
+++ b/doc/groups.dox
@@ -0,0 +1,777 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+namespace lemon {
+
+/**
+ at defgroup datas Data Structures
+This group contains the several data structures implemented in LEMON.
+*/
+
+/**
+ at defgroup graphs Graph Structures
+ at ingroup datas
+\brief Graph structures implemented in LEMON.
+
+The implementation of combinatorial algorithms heavily relies on
+efficient graph implementations. LEMON offers data structures which are
+planned to be easily used in an experimental phase of implementation studies,
+and thereafter the program code can be made efficient by small modifications.
+
+The most efficient implementation of diverse applications require the
+usage of different physical graph implementations. These differences
+appear in the size of graph we require to handle, memory or time usage
+limitations or in the set of operations through which the graph can be
+accessed.  LEMON provides several physical graph structures to meet
+the diverging requirements of the possible users.  In order to save on
+running time or on memory usage, some structures may fail to provide
+some graph features like arc/edge or node deletion.
+
+Alteration of standard containers need a very limited number of
+operations, these together satisfy the everyday requirements.
+In the case of graph structures, different operations are needed which do
+not alter the physical graph, but gives another view. If some nodes or
+arcs have to be hidden or the reverse oriented graph have to be used, then
+this is the case. It also may happen that in a flow implementation
+the residual graph can be accessed by another algorithm, or a node-set
+is to be shrunk for another algorithm.
+LEMON also provides a variety of graphs for these requirements called
+\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only
+in conjunction with other graph representations.
+
+You are free to use the graph structure that fit your requirements
+the best, most graph algorithms and auxiliary data structures can be used
+with any graph structure.
+
+<b>See also:</b> \ref graph_concepts "Graph Structure Concepts".
+*/
+
+/**
+ at defgroup graph_adaptors Adaptor Classes for Graphs
+ at ingroup graphs
+\brief Adaptor classes for digraphs and graphs
+
+This group contains several useful adaptor classes for digraphs and graphs.
+
+The main parts of LEMON are the different graph structures, generic
+graph algorithms, graph concepts, which couple them, and graph
+adaptors. While the previous notions are more or less clear, the
+latter one needs further explanation. Graph adaptors are graph classes
+which serve for considering graph structures in different ways.
+
+A short example makes this much clearer.  Suppose that we have an
+instance \c g of a directed graph type, say ListDigraph and an algorithm
+\code
+template <typename Digraph>
+int algorithm(const Digraph&);
+\endcode
+is needed to run on the reverse oriented graph.  It may be expensive
+(in time or in memory usage) to copy \c g with the reversed
+arcs.  In this case, an adaptor class is used, which (according
+to LEMON \ref concepts::Digraph "digraph concepts") works as a digraph.
+The adaptor uses the original digraph structure and digraph operations when
+methods of the reversed oriented graph are called.  This means that the adaptor
+have minor memory usage, and do not perform sophisticated algorithmic
+actions.  The purpose of it is to give a tool for the cases when a
+graph have to be used in a specific alteration.  If this alteration is
+obtained by a usual construction like filtering the node or the arc set or
+considering a new orientation, then an adaptor is worthwhile to use.
+To come back to the reverse oriented graph, in this situation
+\code
+template<typename Digraph> class ReverseDigraph;
+\endcode
+template class can be used. The code looks as follows
+\code
+ListDigraph g;
+ReverseDigraph<ListDigraph> rg(g);
+int result = algorithm(rg);
+\endcode
+During running the algorithm, the original digraph \c g is untouched.
+This techniques give rise to an elegant code, and based on stable
+graph adaptors, complex algorithms can be implemented easily.
+
+In flow, circulation and matching problems, the residual
+graph is of particular importance. Combining an adaptor implementing
+this with shortest path algorithms or minimum mean cycle algorithms,
+a range of weighted and cardinality optimization algorithms can be
+obtained. For other examples, the interested user is referred to the
+detailed documentation of particular adaptors.
+
+Since the adaptor classes conform to the \ref graph_concepts "graph concepts",
+an adaptor can even be applied to another one.
+The following image illustrates a situation when a \ref SubDigraph adaptor
+is applied on a digraph and \ref Undirector is applied on the subgraph.
+
+\image html adaptors2.png
+\image latex adaptors2.eps "Using graph adaptors" width=\textwidth
+
+The behavior of graph adaptors can be very different. Some of them keep
+capabilities of the original graph while in other cases this would be
+meaningless. This means that the concepts that they meet depend
+on the graph adaptor, and the wrapped graph.
+For example, if an arc of a reversed digraph is deleted, this is carried
+out by deleting the corresponding arc of the original digraph, thus the
+adaptor modifies the original digraph.
+However in case of a residual digraph, this operation has no sense.
+
+Let us stand one more example here to simplify your work.
+ReverseDigraph has constructor
+\code
+ReverseDigraph(Digraph& digraph);
+\endcode
+This means that in a situation, when a <tt>const %ListDigraph&</tt>
+reference to a graph is given, then it have to be instantiated with
+<tt>Digraph=const %ListDigraph</tt>.
+\code
+int algorithm1(const ListDigraph& g) {
+  ReverseDigraph<const ListDigraph> rg(g);
+  return algorithm2(rg);
+}
+\endcode
+*/
+
+/**
+ at defgroup maps Maps
+ at ingroup datas
+\brief Map structures implemented in LEMON.
+
+This group contains the map structures implemented in LEMON.
+
+LEMON provides several special purpose maps and map adaptors that e.g. combine
+new maps from existing ones.
+
+<b>See also:</b> \ref map_concepts "Map Concepts".
+*/
+
+/**
+ at defgroup graph_maps Graph Maps
+ at ingroup maps
+\brief Special graph-related maps.
+
+This group contains maps that are specifically designed to assign
+values to the nodes and arcs/edges of graphs.
+
+If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
+\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts".
+*/
+
+/**
+\defgroup map_adaptors Map Adaptors
+\ingroup maps
+\brief Tools to create new maps from existing ones
+
+This group contains map adaptors that are used to create "implicit"
+maps from other maps.
+
+Most of them are \ref concepts::ReadMap "read-only maps".
+They can make arithmetic and logical operations between one or two maps
+(negation, shifting, addition, multiplication, logical 'and', 'or',
+'not' etc.) or e.g. convert a map to another one of different Value type.
+
+The typical usage of this classes is passing implicit maps to
+algorithms.  If a function type algorithm is called then the function
+type map adaptors can be used comfortable. For example let's see the
+usage of map adaptors with the \c graphToEps() function.
+\code
+  Color nodeColor(int deg) {
+    if (deg >= 2) {
+      return Color(0.5, 0.0, 0.5);
+    } else if (deg == 1) {
+      return Color(1.0, 0.5, 1.0);
+    } else {
+      return Color(0.0, 0.0, 0.0);
+    }
+  }
+
+  Digraph::NodeMap<int> degree_map(graph);
+
+  graphToEps(graph, "graph.eps")
+    .coords(coords).scaleToA4().undirected()
+    .nodeColors(composeMap(functorToMap(nodeColor), degree_map))
+    .run();
+\endcode
+The \c functorToMap() function makes an \c int to \c Color map from the
+\c nodeColor() function. The \c composeMap() compose the \c degree_map
+and the previously created map. The composed map is a proper function to
+get the color of each node.
+
+The usage with class type algorithms is little bit harder. In this
+case the function type map adaptors can not be used, because the
+function map adaptors give back temporary objects.
+\code
+  Digraph graph;
+
+  typedef Digraph::ArcMap<double> DoubleArcMap;
+  DoubleArcMap length(graph);
+  DoubleArcMap speed(graph);
+
+  typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap;
+  TimeMap time(length, speed);
+
+  Dijkstra<Digraph, TimeMap> dijkstra(graph, time);
+  dijkstra.run(source, target);
+\endcode
+We have a length map and a maximum speed map on the arcs of a digraph.
+The minimum time to pass the arc can be calculated as the division of
+the two maps which can be done implicitly with the \c DivMap template
+class. We use the implicit minimum time map as the length map of the
+\c Dijkstra algorithm.
+*/
+
+/**
+ at defgroup paths Path Structures
+ at ingroup datas
+\brief %Path structures implemented in LEMON.
+
+This group contains the path structures implemented in LEMON.
+
+LEMON provides flexible data structures to work with paths.
+All of them have similar interfaces and they can be copied easily with
+assignment operators and copy constructors. This makes it easy and
+efficient to have e.g. the Dijkstra algorithm to store its result in
+any kind of path structure.
+
+\sa \ref concepts::Path "Path concept"
+*/
+
+/**
+ at defgroup heaps Heap Structures
+ at ingroup datas
+\brief %Heap structures implemented in LEMON.
+
+This group contains the heap structures implemented in LEMON.
+
+LEMON provides several heap classes. They are efficient implementations
+of the abstract data type \e priority \e queue. They store items with
+specified values called \e priorities in such a way that finding and
+removing the item with minimum priority are efficient.
+The basic operations are adding and erasing items, changing the priority
+of an item, etc.
+
+Heaps are crucial in several algorithms, such as Dijkstra and Prim.
+The heap implementations have the same interface, thus any of them can be
+used easily in such algorithms.
+
+\sa \ref concepts::Heap "Heap concept"
+*/
+
+/**
+ at defgroup auxdat Auxiliary Data Structures
+ at ingroup datas
+\brief Auxiliary data structures implemented in LEMON.
+
+This group contains some data structures implemented in LEMON in
+order to make it easier to implement combinatorial algorithms.
+*/
+
+/**
+ at defgroup geomdat Geometric Data Structures
+ at ingroup auxdat
+\brief Geometric data structures implemented in LEMON.
+
+This group contains geometric data structures implemented in LEMON.
+
+ - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
+   vector with the usual operations.
+ - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
+   rectangular bounding box of a set of \ref lemon::dim2::Point
+   "dim2::Point"'s.
+*/
+
+/**
+ at defgroup algs Algorithms
+\brief This group contains the several algorithms
+implemented in LEMON.
+
+This group contains the several algorithms
+implemented in LEMON.
+*/
+
+/**
+ at defgroup search Graph Search
+ at ingroup algs
+\brief Common graph search algorithms.
+
+This group contains the common graph search algorithms, namely
+\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
+\cite clrs01algorithms.
+*/
+
+/**
+ at defgroup shortest_path Shortest Path Algorithms
+ at ingroup algs
+\brief Algorithms for finding shortest paths.
+
+This group contains the algorithms for finding shortest paths in digraphs
+\cite clrs01algorithms.
+
+ - \ref Dijkstra algorithm for finding shortest paths from a source node
+   when all arc lengths are non-negative.
+ - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
+   from a source node when arc lenghts can be either positive or negative,
+   but the digraph should not contain directed cycles with negative total
+   length.
+ - \ref Suurballe A successive shortest path algorithm for finding
+   arc-disjoint paths between two nodes having minimum total length.
+*/
+
+/**
+ at defgroup spantree Minimum Spanning Tree Algorithms
+ at ingroup algs
+\brief Algorithms for finding minimum cost spanning trees and arborescences.
+
+This group contains the algorithms for finding minimum cost spanning
+trees and arborescences \cite clrs01algorithms.
+*/
+
+/**
+ at defgroup max_flow Maximum Flow Algorithms
+ at ingroup algs
+\brief Algorithms for finding maximum flows.
+
+This group contains the algorithms for finding maximum flows and
+feasible circulations \cite clrs01algorithms, \cite amo93networkflows.
+
+The \e maximum \e flow \e problem is to find a flow of maximum value between
+a single source and a single target. Formally, there is a \f$G=(V,A)\f$
+digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
+\f$s, t \in V\f$ source and target nodes.
+A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
+following optimization problem.
+
+\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
+\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
+    \quad \forall u\in V\setminus\{s,t\} \f]
+\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
+
+\ref Preflow is an efficient implementation of Goldberg-Tarjan's
+preflow push-relabel algorithm \cite goldberg88newapproach for finding
+maximum flows. It also provides functions to query the minimum cut,
+which is the dual problem of maximum flow.
+
+\ref Circulation is a preflow push-relabel algorithm implemented directly
+for finding feasible circulations, which is a somewhat different problem,
+but it is strongly related to maximum flow.
+For more information, see \ref Circulation.
+*/
+
+/**
+ at defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
+ at ingroup algs
+
+\brief Algorithms for finding minimum cost flows and circulations.
+
+This group contains the algorithms for finding minimum cost flows and
+circulations \cite 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 \cite dantzig63linearprog, \cite kellyoneill91netsimplex.
+ - \ref CostScaling Cost Scaling algorithm based on push/augment and
+   relabel operations \cite goldberg90approximation, \cite goldberg97efficient,
+   \cite bunnagel98efficient.
+ - \ref CapacityScaling Capacity Scaling algorithm based on the successive
+   shortest path method \cite edmondskarp72theoretical.
+ - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
+   strongly polynomial \cite klein67primal, \cite goldberg89cyclecanceling.
+
+In general, \ref NetworkSimplex and \ref CostScaling are the most efficient
+implementations.
+\ref NetworkSimplex is usually the fastest on relatively small graphs (up to
+several thousands of nodes) and on dense graphs, while \ref CostScaling is
+typically more efficient on large graphs (e.g. hundreds of thousands of
+nodes or above), especially if they are sparse.
+However, other algorithms could be faster in special cases.
+For example, if the total supply and/or capacities are rather small,
+\ref CapacityScaling is usually the fastest algorithm
+(without effective scaling).
+
+These classes are intended to be used with integer-valued input data
+(capacities, supply values, and costs), except for \ref CapacityScaling,
+which is capable of handling real-valued arc costs (other numerical
+data are required to be integer).
+
+For more details about these implementations and for a comprehensive
+experimental study, see the paper \cite KiralyKovacs12MCF.
+It also compares these codes to other publicly available
+minimum cost flow solvers.
+*/
+
+/**
+ at defgroup min_cut Minimum Cut Algorithms
+ at ingroup algs
+
+\brief Algorithms for finding minimum cut in graphs.
+
+This group contains the algorithms for finding minimum cut in graphs.
+
+The \e minimum \e cut \e problem is to find a non-empty and non-complete
+\f$X\f$ subset of the nodes with minimum overall capacity on
+outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
+\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
+cut is the \f$X\f$ solution of the next optimization problem:
+
+\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
+    \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
+
+LEMON contains several algorithms related to minimum cut problems:
+
+- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
+  in directed graphs.
+- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
+  calculating minimum cut in undirected graphs.
+- \ref GomoryHu "Gomory-Hu tree computation" for calculating
+  all-pairs minimum cut in undirected graphs.
+
+If you want to find minimum cut just between two distinict nodes,
+see the \ref max_flow "maximum flow problem".
+*/
+
+/**
+ at defgroup min_mean_cycle Minimum Mean Cycle Algorithms
+ at ingroup algs
+\brief Algorithms for finding minimum mean cycles.
+
+This group contains the algorithms for finding minimum mean cycles
+\cite amo93networkflows, \cite karp78characterization.
+
+The \e minimum \e mean \e cycle \e problem is to find a directed cycle
+of minimum mean length (cost) in a digraph.
+The mean length of a cycle is the average length of its arcs, i.e. the
+ratio between the total length of the cycle and the number of arcs on it.
+
+This problem has an important connection to \e conservative \e length
+\e functions, too. A length function on the arcs of a digraph is called
+conservative if and only if there is no directed cycle of negative total
+length. For an arbitrary length function, the negative of the minimum
+cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
+arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
+function.
+
+LEMON contains three algorithms for solving the minimum mean cycle problem:
+- \ref KarpMmc Karp's original algorithm \cite karp78characterization.
+- \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
+  version of Karp's algorithm \cite hartmann93finding.
+- \ref HowardMmc Howard's policy iteration algorithm
+  \cite dasdan98minmeancycle, \cite dasdan04experimental.
+
+In practice, the \ref HowardMmc "Howard" algorithm turned out to be by far the
+most efficient one, though the best known theoretical bound on its running
+time is exponential.
+Both \ref KarpMmc "Karp" and \ref HartmannOrlinMmc "Hartmann-Orlin" algorithms
+run in time O(nm) and use space O(n<sup>2</sup>+m).
+*/
+
+/**
+ at defgroup matching Matching Algorithms
+ at ingroup algs
+\brief Algorithms for finding matchings in graphs and bipartite graphs.
+
+This group contains the algorithms for calculating
+matchings in graphs and bipartite graphs. The general matching problem is
+finding a subset of the edges for which each node has at most one incident
+edge.
+
+There are several different algorithms for calculate matchings in
+graphs.  The matching problems in bipartite graphs are generally
+easier than in general graphs. The goal of the matching optimization
+can be finding maximum cardinality, maximum weight or minimum cost
+matching. The search can be constrained to find perfect or
+maximum cardinality matching.
+
+The matching algorithms implemented in LEMON:
+- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
+  maximum cardinality matching in general graphs.
+- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
+  maximum weighted matching in general graphs.
+- \ref MaxWeightedPerfectMatching
+  Edmond's blossom shrinking algorithm for calculating maximum weighted
+  perfect matching in general graphs.
+- \ref MaxFractionalMatching Push-relabel algorithm for calculating
+  maximum cardinality fractional matching in general graphs.
+- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
+  maximum weighted fractional matching in general graphs.
+- \ref MaxWeightedPerfectFractionalMatching
+  Augmenting path algorithm for calculating maximum weighted
+  perfect fractional matching in general graphs.
+
+\image html matching.png
+\image latex matching.eps "Min Cost Perfect Matching" width=\textwidth
+*/
+
+/**
+ at defgroup graph_properties Connectivity and Other Graph Properties
+ at ingroup algs
+\brief Algorithms for discovering the graph properties
+
+This group contains the algorithms for discovering the graph properties
+like connectivity, bipartiteness, euler property, simplicity etc.
+
+\image html connected_components.png
+\image latex connected_components.eps "Connected components" width=\textwidth
+*/
+
+/**
+ at defgroup planar Planar Embedding and Drawing
+ at ingroup algs
+\brief Algorithms for planarity checking, embedding and drawing
+
+This group contains the algorithms for planarity checking,
+embedding and drawing.
+
+\image html planar.png
+\image latex planar.eps "Plane graph" width=\textwidth
+*/
+
+/**
+ at defgroup tsp Traveling Salesman Problem
+ at ingroup algs
+\brief Algorithms for the symmetric traveling salesman problem
+
+This group contains basic heuristic algorithms for the the symmetric
+\e traveling \e salesman \e problem (TSP).
+Given an \ref FullGraph "undirected full graph" with a cost map on its edges,
+the problem is to find a shortest possible tour that visits each node exactly
+once (i.e. the minimum cost Hamiltonian cycle).
+
+These TSP algorithms are intended to be used with a \e metric \e cost
+\e function, i.e. the edge costs should satisfy the triangle inequality.
+Otherwise the algorithms could yield worse results.
+
+LEMON provides five well-known heuristics for solving symmetric TSP:
+ - \ref NearestNeighborTsp Neareast neighbor algorithm
+ - \ref GreedyTsp Greedy algorithm
+ - \ref InsertionTsp Insertion heuristic (with four selection methods)
+ - \ref ChristofidesTsp Christofides algorithm
+ - \ref Opt2Tsp 2-opt algorithm
+
+\ref NearestNeighborTsp, \ref GreedyTsp, and \ref InsertionTsp are the fastest
+solution methods. Furthermore, \ref InsertionTsp is usually quite effective.
+
+\ref ChristofidesTsp is somewhat slower, but it has the best guaranteed
+approximation factor: 3/2.
+
+\ref Opt2Tsp usually provides the best results in practice, but
+it is the slowest method. It can also be used to improve given tours,
+for example, the results of other algorithms.
+
+\image html tsp.png
+\image latex tsp.eps "Traveling salesman problem" width=\textwidth
+*/
+
+/**
+ at defgroup approx_algs Approximation Algorithms
+ at ingroup algs
+\brief Approximation algorithms.
+
+This group contains the approximation and heuristic algorithms
+implemented in LEMON.
+
+<b>Maximum Clique Problem</b>
+  - \ref GrossoLocatelliPullanMc An efficient heuristic algorithm of
+    Grosso, Locatelli, and Pullan.
+*/
+
+/**
+ at defgroup auxalg Auxiliary Algorithms
+ at ingroup algs
+\brief Auxiliary algorithms implemented in LEMON.
+
+This group contains some algorithms implemented in LEMON
+in order to make it easier to implement complex algorithms.
+*/
+
+/**
+ at defgroup gen_opt_group General Optimization Tools
+\brief This group contains some general optimization frameworks
+implemented in LEMON.
+
+This group contains some general optimization frameworks
+implemented in LEMON.
+*/
+
+/**
+ at defgroup lp_group LP and MIP Solvers
+ at ingroup gen_opt_group
+\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 \cite glpk, \cite clp, \cite cbc,
+\cite cplex, \cite soplex.
+*/
+
+/**
+ at defgroup utils Tools and Utilities
+\brief Tools and utilities for programming in LEMON
+
+Tools and utilities for programming in LEMON.
+*/
+
+/**
+ at defgroup gutils Basic Graph Utilities
+ at ingroup utils
+\brief Simple basic graph utilities.
+
+This group contains some simple basic graph utilities.
+*/
+
+/**
+ at defgroup misc Miscellaneous Tools
+ at ingroup utils
+\brief Tools for development, debugging and testing.
+
+This group contains several useful tools for development,
+debugging and testing.
+*/
+
+/**
+ at defgroup timecount Time Measuring and Counting
+ at ingroup misc
+\brief Simple tools for measuring the performance of algorithms.
+
+This group contains simple tools for measuring the performance
+of algorithms.
+*/
+
+/**
+ at defgroup exceptions Exceptions
+ at ingroup utils
+\brief Exceptions defined in LEMON.
+
+This group contains the exceptions defined in LEMON.
+*/
+
+/**
+ at defgroup io_group Input-Output
+\brief Graph Input-Output methods
+
+This group contains the tools for importing and exporting graphs
+and graph related data. Now it supports the \ref lgf-format
+"LEMON Graph Format", the \c DIMACS format and the encapsulated
+postscript (EPS) format.
+*/
+
+/**
+ at defgroup lemon_io LEMON Graph Format
+ at ingroup io_group
+\brief Reading and writing LEMON Graph Format.
+
+This group contains methods for reading and writing
+\ref lgf-format "LEMON Graph Format".
+*/
+
+/**
+ at defgroup eps_io Postscript Exporting
+ at ingroup io_group
+\brief General \c EPS drawer and graph exporter
+
+This group contains general \c EPS drawing methods and special
+graph exporting tools.
+
+\image html graph_to_eps.png
+*/
+
+/**
+ at defgroup dimacs_group DIMACS Format
+ at ingroup io_group
+\brief Read and write files in DIMACS format
+
+Tools to read a digraph from or write it to a file in DIMACS format data.
+*/
+
+/**
+ at defgroup nauty_group NAUTY Format
+ at ingroup io_group
+\brief Read \e Nauty format
+
+Tool to read graphs from \e Nauty format data.
+*/
+
+/**
+ at defgroup concept Concepts
+\brief Skeleton classes and concept checking classes
+
+This group contains the data/algorithm skeletons and concept checking
+classes implemented in LEMON.
+
+The purpose of the classes in this group is fourfold.
+
+- These classes contain the documentations of the %concepts. In order
+  to avoid document multiplications, an implementation of a concept
+  simply refers to the corresponding concept class.
+
+- These classes declare every functions, <tt>typedef</tt>s etc. an
+  implementation of the %concepts should provide, however completely
+  without implementations and real data structures behind the
+  interface. On the other hand they should provide nothing else. All
+  the algorithms working on a data structure meeting a certain concept
+  should compile with these classes. (Though it will not run properly,
+  of course.) In this way it is easily to check if an algorithm
+  doesn't use any extra feature of a certain implementation.
+
+- The concept descriptor classes also provide a <em>checker class</em>
+  that makes it possible to check whether a certain implementation of a
+  concept indeed provides all the required features.
+
+- Finally, They can serve as a skeleton of a new implementation of a concept.
+*/
+
+/**
+ at defgroup graph_concepts Graph Structure Concepts
+ at ingroup concept
+\brief Skeleton and concept checking classes for graph structures
+
+This group contains the skeletons and concept checking classes of
+graph structures.
+*/
+
+/**
+ at defgroup map_concepts Map Concepts
+ at ingroup concept
+\brief Skeleton and concept checking classes for maps
+
+This group contains the skeletons and concept checking classes of maps.
+*/
+
+/**
+ at defgroup tools Standalone Utility Applications
+
+Some utility applications are listed here.
+
+The standard compilation procedure (<tt>./configure;make</tt>) will compile
+them, as well.
+*/
+
+/**
+\anchor demoprograms
+
+ at defgroup demos Demo Programs
+
+Some demo programs are listed here. Their full source codes can be found in
+the \c demo subdirectory of the source tree.
+
+In order to compile them, use the <tt>make demo</tt> or the
+<tt>make check</tt> commands.
+*/
+
+}
diff --git a/doc/images/adaptors1.eps b/doc/images/adaptors1.eps
new file mode 100644
index 0000000..f75ce19
--- /dev/null
+++ b/doc/images/adaptors1.eps
@@ -0,0 +1,303 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: adaptors1.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5
+%%CreationDate: Sun Feb 21 18:51:21 2010
+%%For: Peter at KOVACSPETER (Péter,U-KOVACSPETER\Peter,S-1-5-21-1774138250-1299389707-1938712334-1001)
+%%BoundingBox: 0 0 787 372
+%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 372 moveto 0 0 lineto 787 0 lineto 787 372 lineto closepath clip newpath
+-14.2 385.4 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+	/endangle exch def
+	/startangle exch def
+	/yrad exch def
+	/xrad exch def
+	/y exch def
+	/x exch def
+	/savematrix mtrx currentmatrix def
+	x y tr xrad yrad sc 0 0 1 startangle endangle arc
+	closepath
+	savematrix setmatrix
+	} def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% 
+% here starts figure with depth 60
+% Polyline
+0 slj
+0 slc
+15.000 slw
+gs  clippath
+6319 5229 m 6442 5564 l 6527 5533 l 6403 5198 l 6403 5198 l 6424 5383 l 6319 5229 l cp
+eoclip
+n 5850 3825 m
+ 6480 5535 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 6319 5229 m 6424 5383 l 6403 5198 l 6319 5229 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+5417 4044 m 5746 3905 l 5711 3822 l 5382 3961 l 5382 3961 l 5566 3933 l 5417 4044 l cp
+eoclip
+n 1575 5625 m
+ 5715 3870 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 5417 4044 m 5566 3933 l 5382 3961 l 5417 4044 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3897 3780 m 3540 3780 l 3540 3870 l 3897 3870 l 3897 3870 l 3717 3825 l 3897 3780 l cp
+eoclip
+n 5625 3825 m
+ 3555 3825 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3897 3780 m 3717 3825 l 3897 3870 l 3897 3780 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3075 4188 m 3327 3936 l 3263 3872 l 3011 4124 l 3011 4124 l 3171 4029 l 3075 4188 l cp
+eoclip
+n 1575 5625 m
+ 3285 3915 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3075 4188 m 3171 4029 l 3011 4124 l 3075 4188 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3528 2520 m 3885 2520 l 3885 2430 l 3528 2430 l 3528 2430 l 3708 2475 l 3528 2520 l cp
+eoclip
+n 1800 2475 m
+ 3870 2475 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3528 2520 m 3708 2475 l 3528 2430 l 3528 2520 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4304 2156 m 4052 2408 l 4116 2472 l 4368 2220 l 4368 2220 l 4209 2316 l 4304 2156 l cp
+eoclip
+n 5850 675 m
+ 4095 2430 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4304 2156 m 4209 2316 l 4368 2220 l 4304 2156 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+6319 2079 m 6442 2414 l 6527 2383 l 6403 2048 l 6403 2048 l 6424 2233 l 6319 2079 l cp
+eoclip
+n 5850 675 m
+ 6480 2385 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 6319 2079 m 6424 2233 l 6403 2048 l 6319 2079 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+5417 894 m 5746 755 l 5711 672 l 5382 811 l 5382 811 l 5566 783 l 5417 894 l cp
+eoclip
+n 1575 2475 m
+ 5715 720 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 5417 894 m 5566 783 l 5382 811 l 5417 894 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3528 5670 m 3885 5670 l 3885 5580 l 3528 5580 l 3528 5580 l 3708 5625 l 3528 5670 l cp
+eoclip
+n 1800 5625 m
+ 3870 5625 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3528 5670 m 3708 5625 l 3528 5580 l 3528 5670 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4572 5580 m 4215 5580 l 4215 5670 l 4572 5670 l 4572 5670 l 4392 5625 l 4572 5580 l cp
+eoclip
+n 6300 5625 m
+ 4230 5625 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4572 5580 m 4392 5625 l 4572 5670 l 4572 5580 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4304 5306 m 4052 5558 l 4116 5622 l 4368 5370 l 4368 5370 l 4209 5466 l 4304 5306 l cp
+eoclip
+n 5850 3825 m
+ 4095 5580 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4304 5306 m 4209 5466 l 4368 5370 l 4304 5306 l  cp gs 0.00 setgray ef gr  col0 s
+% here ends figure;
+% 
+% here starts figure with depth 50
+% Ellipse
+15.000 slw
+n 3375 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Polyline
+0 slj
+0 slc
+n 247 2947 m 2947 247 l 9697 247 l 6997 2947 l
+ 247 2947 l  cp gs col0 s gr 
+% Polyline
+n 247 6097 m 2947 3397 l 9697 3397 l 6997 6097 l
+ 247 6097 l  cp gs col0 s gr 
+% Ellipse
+n 1575 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 4050 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 675 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 1575 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 4050 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% here ends figure;
+% 
+% here starts figure with depth 40
+/Helvetica ff 480.00 scf sf
+8280 2610 m
+gs 1 -1 sc (SubDigraph adaptor) col0 sh gr
+% Polyline
+0 slj
+0 slc
+7.500 slw
+ [15 45] 45 sd
+n 4050 2610 m
+ 4050 5625 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 5850 810 m
+ 5850 3825 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 6525 2610 m
+ 6525 5625 l gs col0 s gr  [] 0 sd
+/Helvetica ff 480.00 scf sf
+8280 5760 m
+gs 1 -1 sc (Original digraph) col0 sh gr
+% Polyline
+ [15 45] 45 sd
+n 1575 2610 m
+ 1575 5625 l gs col0 s gr  [] 0 sd
+% here ends figure;
+$F2psEnd
+rs
+showpage
+%%Trailer
+%EOF
diff --git a/doc/images/adaptors2.eps b/doc/images/adaptors2.eps
new file mode 100644
index 0000000..d127ec5
--- /dev/null
+++ b/doc/images/adaptors2.eps
@@ -0,0 +1,349 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: adaptors2.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5
+%%CreationDate: Sun Feb 21 18:51:31 2010
+%%For: Peter at KOVACSPETER (Péter,U-KOVACSPETER\Peter,S-1-5-21-1774138250-1299389707-1938712334-1001)
+%%BoundingBox: 0 0 787 570
+%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 570 moveto 0 0 lineto 787 0 lineto 787 570 lineto closepath clip newpath
+-14.2 583.9 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+	/endangle exch def
+	/startangle exch def
+	/yrad exch def
+	/xrad exch def
+	/y exch def
+	/x exch def
+	/savematrix mtrx currentmatrix def
+	x y tr xrad yrad sc 0 0 1 startangle endangle arc
+	closepath
+	savematrix setmatrix
+	} def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% 
+% here starts figure with depth 60
+% Polyline
+0 slj
+0 slc
+15.000 slw
+gs  clippath
+5417 4044 m 5746 3905 l 5711 3822 l 5382 3961 l 5382 3961 l 5566 3933 l 5417 4044 l cp
+eoclip
+n 1575 5625 m
+ 5715 3870 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 5417 4044 m 5566 3933 l 5382 3961 l 5417 4044 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+5417 7194 m 5746 7055 l 5711 6972 l 5382 7111 l 5382 7111 l 5566 7083 l 5417 7194 l cp
+eoclip
+n 1575 8775 m
+ 5715 7020 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 5417 7194 m 5566 7083 l 5382 7111 l 5417 7194 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+6319 8379 m 6442 8714 l 6527 8683 l 6403 8348 l 6403 8348 l 6424 8533 l 6319 8379 l cp
+eoclip
+n 5850 6975 m
+ 6480 8685 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 6319 8379 m 6424 8533 l 6403 8348 l 6319 8379 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4304 8456 m 4052 8708 l 4116 8772 l 4368 8520 l 4368 8520 l 4209 8616 l 4304 8456 l cp
+eoclip
+n 5850 6975 m
+ 4095 8730 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4304 8456 m 4209 8616 l 4368 8520 l 4304 8456 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4572 8730 m 4215 8730 l 4215 8820 l 4572 8820 l 4572 8820 l 4392 8775 l 4572 8730 l cp
+eoclip
+n 6300 8775 m
+ 4230 8775 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4572 8730 m 4392 8775 l 4572 8820 l 4572 8730 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3528 8820 m 3885 8820 l 3885 8730 l 3528 8730 l 3528 8730 l 3708 8775 l 3528 8820 l cp
+eoclip
+n 1800 8775 m
+ 3870 8775 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3528 8820 m 3708 8775 l 3528 8730 l 3528 8820 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+n 1800 2475 m
+ 3870 2475 l gs col0 s gr 
+% Polyline
+n 1575 2475 m
+ 5715 720 l gs col0 s gr 
+% Polyline
+n 5850 675 m
+ 4095 2430 l gs col0 s gr 
+% Polyline
+n 5850 675 m
+ 6480 2385 l gs col0 s gr 
+% Polyline
+gs  clippath
+3075 7338 m 3327 7086 l 3263 7022 l 3011 7274 l 3011 7274 l 3171 7179 l 3075 7338 l cp
+eoclip
+n 1575 8775 m
+ 3285 7065 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3075 7338 m 3171 7179 l 3011 7274 l 3075 7338 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3528 5670 m 3885 5670 l 3885 5580 l 3528 5580 l 3528 5580 l 3708 5625 l 3528 5670 l cp
+eoclip
+n 1800 5625 m
+ 3870 5625 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3528 5670 m 3708 5625 l 3528 5580 l 3528 5670 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4304 5306 m 4052 5558 l 4116 5622 l 4368 5370 l 4368 5370 l 4209 5466 l 4304 5306 l cp
+eoclip
+n 5850 3825 m
+ 4095 5580 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4304 5306 m 4209 5466 l 4368 5370 l 4304 5306 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+6319 5229 m 6442 5564 l 6527 5533 l 6403 5198 l 6403 5198 l 6424 5383 l 6319 5229 l cp
+eoclip
+n 5850 3825 m
+ 6480 5535 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 6319 5229 m 6424 5383 l 6403 5198 l 6319 5229 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3897 6930 m 3540 6930 l 3540 7020 l 3897 7020 l 3897 7020 l 3717 6975 l 3897 6930 l cp
+eoclip
+n 5625 6975 m
+ 3555 6975 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3897 6930 m 3717 6975 l 3897 7020 l 3897 6930 l  cp gs 0.00 setgray ef gr  col0 s
+% here ends figure;
+% 
+% here starts figure with depth 50
+% Polyline
+0 slj
+0 slc
+15.000 slw
+n 247 6097 m 2947 3397 l 9697 3397 l 6997 6097 l
+ 247 6097 l  cp gs col0 s gr 
+% Polyline
+n 247 9247 m 2947 6547 l 9697 6547 l 6997 9247 l
+ 247 9247 l  cp gs col0 s gr 
+% Ellipse
+n 4050 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 1575 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 675 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 1575 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 4050 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 1575 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 4050 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 3375 6975 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 6975 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Polyline
+n 247 2947 m 2947 247 l 9697 247 l 6997 2947 l
+ 247 2947 l  cp gs col0 s gr 
+% here ends figure;
+% 
+% here starts figure with depth 40
+/Helvetica ff 480.00 scf sf
+8280 8910 m
+gs 1 -1 sc (Original digraph) col0 sh gr
+% Polyline
+0 slj
+0 slc
+7.500 slw
+ [15 45] 45 sd
+n 5850 810 m
+ 5850 3825 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 6525 2610 m
+ 6525 5625 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 4050 2610 m
+ 4050 5625 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 1575 2610 m
+ 1575 5625 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 5850 3960 m
+ 5850 6975 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 6525 5760 m
+ 6525 8775 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 4050 5760 m
+ 4050 8775 l gs col0 s gr  [] 0 sd
+/Helvetica ff 480.00 scf sf
+8280 2610 m
+gs 1 -1 sc (Undirector adaptor) col0 sh gr
+/Helvetica ff 480.00 scf sf
+8280 5760 m
+gs 1 -1 sc (SubDigraph adaptor) col0 sh gr
+% Polyline
+ [15 45] 45 sd
+n 1575 5760 m
+ 1575 8775 l gs col0 s gr  [] 0 sd
+% here ends figure;
+$F2psEnd
+rs
+showpage
+%%Trailer
+%EOF
diff --git a/doc/images/bipartite_matching.eps b/doc/images/bipartite_matching.eps
new file mode 100644
index 0000000..b5683cb
--- /dev/null
+++ b/doc/images/bipartite_matching.eps
@@ -0,0 +1,586 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 15 18 829 570
+%%HiResBoundingBox: 15.1913 18.4493 828.078 569.438
+%%Creator: Karbon14 EPS Exportfilter 0.5
+%%CreationDate: (04/15/06 15:20:26)
+%%For: (Balazs Dezso) ()
+%%Title: ()
+
+/N {newpath} def
+/C {closepath} def
+/m {moveto} def
+/c {curveto} def
+/l {lineto} def
+/s {stroke} def
+/f {fill} def
+/w {setlinewidth} def
+/d {setdash} def
+/r {setrgbcolor} def
+/S {gsave} def
+/R {grestore} def
+
+N
+251.402 32.047 m
+532.945 293.946 814.484 555.844 814.484 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+749.012 32.047 m
+742.465 293.946 735.918 555.844 735.918 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+539.492 32.047 m
+637.703 293.946 735.918 555.844 735.918 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+172.832 32.047 m
+454.375 293.946 735.918 555.844 735.918 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+107.355 32.047 m
+421.637 293.946 735.918 555.844 735.918 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+644.25 555.844 m
+696.633 293.946 749.012 32.047 749.012 32.047 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+474.016 555.844 m
+611.516 293.946 749.012 32.047 749.012 32.047 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+683.535 32.047 m
+663.894 293.946 644.25 555.844 644.25 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+120.453 555.844 m
+401.992 293.946 683.535 32.047 683.535 32.047 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+28.7853 555.844 m
+356.16 293.946 683.535 32.047 683.535 32.047 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+539.492 32.047 m
+546.039 293.946 552.586 555.844 552.586 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+316.875 32.047 m
+349.613 293.946 382.351 555.844 382.351 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+107.355 32.047 m
+244.855 293.946 382.351 555.844 382.351 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+290.687 555.844 m
+375.805 293.946 460.922 32.047 460.922 32.047 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+120.453 555.844 m
+290.687 293.946 460.922 32.047 460.922 32.047 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+172.832 32.047 m
+146.64 293.946 120.453 555.844 120.453 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+15.6913 555.844 m
+15.6913 555.844 l
+15.6913 548.614 21.5553 542.75 28.7853 542.75 c
+36.0163 542.75 41.8833 548.614 41.8833 555.844 c
+41.8833 563.075 36.0163 568.938 28.7853 568.938 c
+21.5553 568.938 15.6913 563.075 15.6913 555.844 c
+15.6913 555.844 l
+C
+S 0 0 0 r f R
+
+N
+16.8833 555.844 m
+16.8833 555.844 l
+16.8833 549.27 22.2113 543.942 28.7853 543.942 c
+35.3593 543.942 40.6913 549.27 40.6913 555.844 c
+40.6913 562.418 35.3593 567.747 28.7853 567.747 c
+22.2113 567.747 16.8833 562.418 16.8833 555.844 c
+16.8833 555.844 l
+C
+S 1 0.5 1 r f R
+
+N
+107.355 555.844 m
+107.355 555.844 l
+107.355 548.614 113.223 542.75 120.453 542.75 c
+127.683 542.75 133.547 548.614 133.547 555.844 c
+133.547 563.075 127.683 568.938 120.453 568.938 c
+113.223 568.938 107.355 563.075 107.355 555.844 c
+107.355 555.844 l
+C
+S 0 0 0 r f R
+
+N
+108.547 555.844 m
+108.547 555.844 l
+108.547 549.27 113.879 543.942 120.453 543.942 c
+127.027 543.942 132.355 549.27 132.355 555.844 c
+132.355 562.418 127.027 567.747 120.453 567.747 c
+113.879 567.747 108.547 562.418 108.547 555.844 c
+108.547 555.844 l
+C
+S 1 0 1 r f R
+
+N
+199.019 555.844 m
+199.019 555.844 l
+199.019 548.614 204.887 542.75 212.117 542.75 c
+219.348 542.75 225.211 548.614 225.211 555.844 c
+225.211 563.075 219.348 568.938 212.117 568.938 c
+204.887 568.938 199.019 563.075 199.019 555.844 c
+199.019 555.844 l
+C
+S 0 0 0 r f R
+
+N
+200.211 555.844 m
+200.211 555.844 l
+200.211 549.27 205.543 543.942 212.117 543.942 c
+218.691 543.942 224.019 549.27 224.019 555.844 c
+224.019 562.418 218.691 567.747 212.117 567.747 c
+205.543 567.747 200.211 562.418 200.211 555.844 c
+200.211 555.844 l
+C
+S 1 0.5 1 r f R
+
+N
+277.59 555.844 m
+277.59 555.844 l
+277.59 548.614 283.457 542.75 290.687 542.75 c
+297.918 542.75 303.781 548.614 303.781 555.844 c
+303.781 563.075 297.918 568.938 290.687 568.938 c
+283.457 568.938 277.59 563.075 277.59 555.844 c
+277.59 555.844 l
+C
+S 0 0 0 r f R
+
+N
+278.781 555.844 m
+278.781 555.844 l
+278.781 549.27 284.113 543.942 290.687 543.942 c
+297.262 543.942 302.59 549.27 302.59 555.844 c
+302.59 562.418 297.262 567.747 290.687 567.747 c
+284.113 567.747 278.781 562.418 278.781 555.844 c
+278.781 555.844 l
+C
+S 1 0 1 r f R
+
+N
+369.258 555.844 m
+369.258 555.844 l
+369.258 548.614 375.121 542.75 382.351 542.75 c
+389.582 542.75 395.445 548.614 395.445 555.844 c
+395.445 563.075 389.582 568.938 382.351 568.938 c
+375.121 568.938 369.258 563.075 369.258 555.844 c
+369.258 555.844 l
+C
+S 0 0 0 r f R
+
+N
+370.445 555.844 m
+370.445 555.844 l
+370.445 549.27 375.777 543.942 382.351 543.942 c
+388.926 543.942 394.258 549.27 394.258 555.844 c
+394.258 562.418 388.926 567.747 382.351 567.747 c
+375.777 567.747 370.445 562.418 370.445 555.844 c
+370.445 555.844 l
+C
+S 1 0 1 r f R
+
+N
+460.922 555.844 m
+460.922 555.844 l
+460.922 548.614 466.785 542.75 474.016 542.75 c
+481.246 542.75 487.109 548.614 487.109 555.844 c
+487.109 563.075 481.246 568.938 474.016 568.938 c
+466.785 568.938 460.922 563.075 460.922 555.844 c
+460.922 555.844 l
+C
+S 0 0 0 r f R
+
+N
+462.113 555.844 m
+462.113 555.844 l
+462.113 549.27 467.441 543.942 474.016 543.942 c
+480.59 543.942 485.922 549.27 485.922 555.844 c
+485.922 562.418 480.59 567.747 474.016 567.747 c
+467.441 567.747 462.113 562.418 462.113 555.844 c
+462.113 555.844 l
+C
+S 1 0.5 1 r f R
+
+N
+539.492 555.844 m
+539.492 555.844 l
+539.492 548.614 545.355 542.75 552.586 542.75 c
+559.816 542.75 565.68 548.614 565.68 555.844 c
+565.68 563.075 559.816 568.938 552.586 568.938 c
+545.355 568.938 539.492 563.075 539.492 555.844 c
+539.492 555.844 l
+C
+S 0 0 0 r f R
+
+N
+540.683 555.844 m
+540.683 555.844 l
+540.683 549.27 546.012 543.942 552.586 543.942 c
+559.16 543.942 564.492 549.27 564.492 555.844 c
+564.492 562.418 559.16 567.747 552.586 567.747 c
+546.012 567.747 540.683 562.418 540.683 555.844 c
+540.683 555.844 l
+C
+S 1 0 1 r f R
+
+N
+631.156 555.844 m
+631.156 555.844 l
+631.156 548.614 637.019 542.75 644.25 542.75 c
+651.48 542.75 657.348 548.614 657.348 555.844 c
+657.348 563.075 651.48 568.938 644.25 568.938 c
+637.019 568.938 631.156 563.075 631.156 555.844 c
+631.156 555.844 l
+C
+S 0 0 0 r f R
+
+N
+632.348 555.844 m
+632.348 555.844 l
+632.348 549.27 637.676 543.942 644.25 543.942 c
+650.824 543.942 656.156 549.27 656.156 555.844 c
+656.156 562.418 650.824 567.747 644.25 567.747 c
+637.676 567.747 632.348 562.418 632.348 555.844 c
+632.348 555.844 l
+C
+S 1 0.5 1 r f R
+
+N
+722.82 555.844 m
+722.82 555.844 l
+722.82 548.614 728.687 542.75 735.918 542.75 c
+743.149 542.75 749.012 548.614 749.012 555.844 c
+749.012 563.075 743.149 568.938 735.918 568.938 c
+728.687 568.938 722.82 563.075 722.82 555.844 c
+722.82 555.844 l
+C
+S 0 0 0 r f R
+
+N
+724.012 555.844 m
+724.012 555.844 l
+724.012 549.27 729.344 543.942 735.918 543.942 c
+742.492 543.942 747.82 549.27 747.82 555.844 c
+747.82 562.418 742.492 567.747 735.918 567.747 c
+729.344 567.747 724.012 562.418 724.012 555.844 c
+724.012 555.844 l
+C
+S 1 0 1 r f R
+
+N
+801.391 555.844 m
+801.391 555.844 l
+801.391 548.614 807.254 542.75 814.484 542.75 c
+821.715 542.75 827.578 548.614 827.578 555.844 c
+827.578 563.075 821.715 568.938 814.484 568.938 c
+807.254 568.938 801.391 563.075 801.391 555.844 c
+801.391 555.844 l
+C
+S 0 0 0 r f R
+
+N
+802.582 555.844 m
+802.582 555.844 l
+802.582 549.27 807.91 543.942 814.484 543.942 c
+821.059 543.942 826.387 549.27 826.387 555.844 c
+826.387 562.418 821.059 567.747 814.484 567.747 c
+807.91 567.747 802.582 562.418 802.582 555.844 c
+802.582 555.844 l
+C
+S 1 0 1 r f R
+
+N
+15.6913 32.047 m
+15.6913 32.047 l
+15.6913 24.8165 21.5553 18.9493 28.7853 18.9493 c
+36.0163 18.9493 41.8833 24.8165 41.8833 32.047 c
+41.8833 39.2775 36.0163 45.1407 28.7853 45.1407 c
+21.5553 45.1407 15.6913 39.2775 15.6913 32.047 c
+15.6913 32.047 l
+C
+S 0 0 0 r f R
+
+N
+16.8833 32.047 m
+16.8833 32.047 l
+16.8833 25.4728 22.2113 20.1407 28.7853 20.1407 c
+35.3593 20.1407 40.6913 25.4728 40.6913 32.047 c
+40.6913 38.6212 35.3593 43.9493 28.7853 43.9493 c
+22.2113 43.9493 16.8833 38.6212 16.8833 32.047 c
+16.8833 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+94.2623 32.047 m
+94.2623 32.047 l
+94.2623 24.8165 100.125 18.9493 107.355 18.9493 c
+114.586 18.9493 120.453 24.8165 120.453 32.047 c
+120.453 39.2775 114.586 45.1407 107.355 45.1407 c
+100.125 45.1407 94.2623 39.2775 94.2623 32.047 c
+94.2623 32.047 l
+C
+S 0 0 0 r f R
+
+N
+95.4533 32.047 m
+95.4533 32.047 l
+95.4533 25.4728 100.781 20.1407 107.355 20.1407 c
+113.93 20.1407 119.262 25.4728 119.262 32.047 c
+119.262 38.6212 113.93 43.9493 107.355 43.9493 c
+100.781 43.9493 95.4533 38.6212 95.4533 32.047 c
+95.4533 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+159.734 32.047 m
+159.734 32.047 l
+159.734 24.8165 165.601 18.9493 172.832 18.9493 c
+180.062 18.9493 185.926 24.8165 185.926 32.047 c
+185.926 39.2775 180.062 45.1407 172.832 45.1407 c
+165.601 45.1407 159.734 39.2775 159.734 32.047 c
+159.734 32.047 l
+C
+S 0 0 0 r f R
+
+N
+160.926 32.047 m
+160.926 32.047 l
+160.926 25.4728 166.258 20.1407 172.832 20.1407 c
+179.406 20.1407 184.734 25.4728 184.734 32.047 c
+184.734 38.6212 179.406 43.9493 172.832 43.9493 c
+166.258 43.9493 160.926 38.6212 160.926 32.047 c
+160.926 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+238.305 32.047 m
+238.305 32.047 l
+238.305 24.8165 244.172 18.9493 251.402 18.9493 c
+258.633 18.9493 264.496 24.8165 264.496 32.047 c
+264.496 39.2775 258.633 45.1407 251.402 45.1407 c
+244.172 45.1407 238.305 39.2775 238.305 32.047 c
+238.305 32.047 l
+C
+S 0 0 0 r f R
+
+N
+239.496 32.047 m
+239.496 32.047 l
+239.496 25.4728 244.828 20.1407 251.402 20.1407 c
+257.976 20.1407 263.305 25.4728 263.305 32.047 c
+263.305 38.6212 257.976 43.9493 251.402 43.9493 c
+244.828 43.9493 239.496 38.6212 239.496 32.047 c
+239.496 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+303.781 32.047 m
+303.781 32.047 l
+303.781 24.8165 309.644 18.9493 316.875 18.9493 c
+324.105 18.9493 329.973 24.8165 329.973 32.047 c
+329.973 39.2775 324.105 45.1407 316.875 45.1407 c
+309.644 45.1407 303.781 39.2775 303.781 32.047 c
+303.781 32.047 l
+C
+S 0 0 0 r f R
+
+N
+304.973 32.047 m
+304.973 32.047 l
+304.973 25.4728 310.301 20.1407 316.875 20.1407 c
+323.449 20.1407 328.781 25.4728 328.781 32.047 c
+328.781 38.6212 323.449 43.9493 316.875 43.9493 c
+310.301 43.9493 304.973 38.6212 304.973 32.047 c
+304.973 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+382.351 32.047 m
+382.351 32.047 l
+382.351 24.8165 388.215 18.9493 395.445 18.9493 c
+402.676 18.9493 408.543 24.8165 408.543 32.047 c
+408.543 39.2775 402.676 45.1407 395.445 45.1407 c
+388.215 45.1407 382.351 39.2775 382.351 32.047 c
+382.351 32.047 l
+C
+S 0 0 0 r f R
+
+N
+383.543 32.047 m
+383.543 32.047 l
+383.543 25.4728 388.871 20.1407 395.445 20.1407 c
+402.019 20.1407 407.351 25.4728 407.351 32.047 c
+407.351 38.6212 402.019 43.9493 395.445 43.9493 c
+388.871 43.9493 383.543 38.6212 383.543 32.047 c
+383.543 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+447.828 32.047 m
+447.828 32.047 l
+447.828 24.8165 453.691 18.9493 460.922 18.9493 c
+468.152 18.9493 474.016 24.8165 474.016 32.047 c
+474.016 39.2775 468.152 45.1407 460.922 45.1407 c
+453.691 45.1407 447.828 39.2775 447.828 32.047 c
+447.828 32.047 l
+C
+S 0 0 0 r f R
+
+N
+449.016 32.047 m
+449.016 32.047 l
+449.016 25.4728 454.348 20.1407 460.922 20.1407 c
+467.496 20.1407 472.824 25.4728 472.824 32.047 c
+472.824 38.6212 467.496 43.9493 460.922 43.9493 c
+454.348 43.9493 449.016 38.6212 449.016 32.047 c
+449.016 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+526.394 32.047 m
+526.394 32.047 l
+526.394 24.8165 532.262 18.9493 539.492 18.9493 c
+546.723 18.9493 552.586 24.8165 552.586 32.047 c
+552.586 39.2775 546.723 45.1407 539.492 45.1407 c
+532.262 45.1407 526.394 39.2775 526.394 32.047 c
+526.394 32.047 l
+C
+S 0 0 0 r f R
+
+N
+527.586 32.047 m
+527.586 32.047 l
+527.586 25.4728 532.918 20.1407 539.492 20.1407 c
+546.066 20.1407 551.394 25.4728 551.394 32.047 c
+551.394 38.6212 546.066 43.9493 539.492 43.9493 c
+532.918 43.9493 527.586 38.6212 527.586 32.047 c
+527.586 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+591.871 32.047 m
+591.871 32.047 l
+591.871 24.8165 597.734 18.9493 604.965 18.9493 c
+612.195 18.9493 618.062 24.8165 618.062 32.047 c
+618.062 39.2775 612.195 45.1407 604.965 45.1407 c
+597.734 45.1407 591.871 39.2775 591.871 32.047 c
+591.871 32.047 l
+C
+S 0 0 0 r f R
+
+N
+593.062 32.047 m
+593.062 32.047 l
+593.062 25.4728 598.39 20.1407 604.965 20.1407 c
+611.539 20.1407 616.871 25.4728 616.871 32.047 c
+616.871 38.6212 611.539 43.9493 604.965 43.9493 c
+598.39 43.9493 593.062 38.6212 593.062 32.047 c
+593.062 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+670.441 32.047 m
+670.441 32.047 l
+670.441 24.8165 676.305 18.9493 683.535 18.9493 c
+690.766 18.9493 696.633 24.8165 696.633 32.047 c
+696.633 39.2775 690.766 45.1407 683.535 45.1407 c
+676.305 45.1407 670.441 39.2775 670.441 32.047 c
+670.441 32.047 l
+C
+S 0 0 0 r f R
+
+N
+671.633 32.047 m
+671.633 32.047 l
+671.633 25.4728 676.961 20.1407 683.535 20.1407 c
+690.109 20.1407 695.441 25.4728 695.441 32.047 c
+695.441 38.6212 690.109 43.9493 683.535 43.9493 c
+676.961 43.9493 671.633 38.6212 671.633 32.047 c
+671.633 32.047 l
+C
+S 0 0 1 r f R
+
+N
+735.918 32.047 m
+735.918 32.047 l
+735.918 24.8165 741.781 18.9493 749.012 18.9493 c
+756.242 18.9493 762.106 24.8165 762.106 32.047 c
+762.106 39.2775 756.242 45.1407 749.012 45.1407 c
+741.781 45.1407 735.918 39.2775 735.918 32.047 c
+735.918 32.047 l
+C
+S 0 0 0 r f R
+
+N
+737.105 32.047 m
+737.105 32.047 l
+737.105 25.4728 742.437 20.1407 749.012 20.1407 c
+755.586 20.1407 760.914 25.4728 760.914 32.047 c
+760.914 38.6212 755.586 43.9493 749.012 43.9493 c
+742.437 43.9493 737.105 38.6212 737.105 32.047 c
+737.105 32.047 l
+C
+S 0 0 1 r f R
+
+N
+801.391 32.047 m
+801.391 32.047 l
+801.391 24.8165 807.254 18.9493 814.484 18.9493 c
+821.715 18.9493 827.578 24.8165 827.578 32.047 c
+827.578 39.2775 821.715 45.1407 814.484 45.1407 c
+807.254 45.1407 801.391 39.2775 801.391 32.047 c
+801.391 32.047 l
+C
+S 0 0 0 r f R
+
+N
+802.582 32.047 m
+802.582 32.047 l
+802.582 25.4728 807.91 20.1407 814.484 20.1407 c
+821.059 20.1407 826.387 25.4728 826.387 32.047 c
+826.387 38.6212 821.059 43.9493 814.484 43.9493 c
+807.91 43.9493 802.582 38.6212 802.582 32.047 c
+802.582 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+%%EOF
diff --git a/doc/images/bipartite_partitions.eps b/doc/images/bipartite_partitions.eps
new file mode 100644
index 0000000..242f269
--- /dev/null
+++ b/doc/images/bipartite_partitions.eps
@@ -0,0 +1,114 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Mar  8 00:18:43 2013
+%%BoundingBox: 0 0 842 596
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+90 rotate
+0 -842 translate
+71.6378 15 translate
+0.389093 dup scale
+90 rotate
+1197.47 -613.138 translate
+%Edges:
+gsave
+513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 7.00153 lb
+513.857 -446.322 575.52 -315.656 637.183 -184.989 0 0 0 7.00153 lb
+393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 7.00153 lb
+393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 7.00153 lb
+393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 7.00153 lb
+869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 7.00153 lb
+869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 7.00153 lb
+-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 7.00153 lb
+-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 7.00153 lb
+-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 7.00153 lb
+-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 7.00153 lb
+-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 7.00153 lb
+-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 7.00153 lb
+-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 7.00153 lb
+-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 7.00153 lb
+-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 7.00153 lb
+-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 7.00153 lb
+-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 7.00153 lb
+79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 7.00153 lb
+637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 7.00153 lb
+205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 7.00153 lb
+399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 7.00153 lb
+399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 7.00153 lb
+-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 7.00153 lb
+-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 7.00153 lb
+-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 7.00153 lb
+-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 7.00153 lb
+-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 7.00153 lb
+-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 7.00153 lb
+120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 7.00153 lb
+grestore
+%Nodes:
+gsave
+-274 -131 23.3384 1 0 0 nc
+-607.82 -246.651 23.3384 1 0 0 nc
+-484.494 328.869 23.3384 0 0 1 nc
+108.644 334.741 23.3384 0 0 1 nc
+120.389 -129.198 23.3384 0 0 1 nc
+-99.8351 99.8351 23.3384 1 0 0 nc
+-211.415 -452.194 23.3384 1 0 0 nc
+-860.344 -29.3633 23.3384 0 0 1 nc
+-842.726 243.715 23.3384 0 0 1 nc
+399.34 88.0898 23.3384 1 0 0 nc
+205.543 -322.996 23.3384 1 0 0 nc
+637.183 -184.989 23.3384 0 0 1 nc
+79.2808 -528.539 23.3384 0 0 1 nc
+-499.175 -499.175 23.3384 0 0 1 nc
+-880.898 -528.539 23.3384 0 0 1 nc
+-1177.47 -234.906 23.3384 1 0 0 nc
+-1077.63 161.498 23.3384 1 0 0 nc
+-663.61 546.157 23.3384 1 0 0 nc
+-82.2171 593.138 23.3384 0 0 1 nc
+596.074 302.442 23.3384 0 0 1 nc
+869.153 52.8539 23.3384 1 0 0 nc
+393.468 566.711 23.3384 1 0 0 nc
+513.857 -446.322 23.3384 1 0 0 nc
+grestore
+grestore
+showpage
diff --git a/doc/images/connected_components.eps b/doc/images/connected_components.eps
new file mode 100644
index 0000000..5e2802e
--- /dev/null
+++ b/doc/images/connected_components.eps
@@ -0,0 +1,159 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Mar  8 00:18:43 2013
+%%BoundingBox: 0 0 842 596
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+90 rotate
+0 -842 translate
+71.0944 15 translate
+0.434694 dup scale
+90 rotate
+860.856 -588.349 translate
+%Edges:
+gsave
+574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 6.25356 lb
+694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 6.25356 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 6.25356 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 6.25356 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 6.25356 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 6.25356 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 6.25356 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 6.25356 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 6.25356 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 6.25356 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 6.25356 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 6.25356 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 6.25356 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 6.25356 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 6.25356 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 6.25356 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 6.25356 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 6.25356 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 6.25356 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 6.25356 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 6.25356 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 6.25356 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 6.25356 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 6.25356 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 6.25356 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 6.25356 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 6.25356 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 6.25356 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 6.25356 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 6.25356 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 6.25356 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 6.25356 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 6.25356 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 6.25356 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 6.25356 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 6.25356 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 6.25356 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 6.25356 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 6.25356 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 6.25356 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 6.25356 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 6.25356 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 6.25356 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 6.25356 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 6.25356 lb
+-180.397 245.045 -113.509 338.465 -132.697 451.748 0 0 0 6.25356 lb
+-180.397 245.045 -199.585 358.328 -132.697 451.748 0 0 0 6.25356 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 6.25356 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 6.25356 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 6.25356 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 6.25356 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 6.25356 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 6.25356 lb
+-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 0 6.25356 lb
+-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 0 6.25356 lb
+grestore
+%Nodes:
+gsave
+-567.302 43.6423 20.8452 0 0 0 nc
+-689.204 -237.261 20.8452 0 0 0 nc
+924.667 409.347 20.8452 1 0 0 nc
+588.113 544.499 20.8452 1 0 0 nc
+670.264 274.195 20.8452 1 0 0 nc
+-371.2 568.349 20.8452 0 1 0 nc
+-132.697 451.748 20.8452 0 1 0 nc
+-416.25 345.746 20.8452 0 1 0 nc
+-180.397 245.045 20.8452 0 1 0 nc
+-13.4452 133.743 20.8452 0 1 0 nc
+-262.548 107.243 20.8452 0 1 0 nc
+201.208 38.3422 20.8452 0 1 0 nc
+116.407 -173.66 20.8452 0 1 0 nc
+-26.6953 -19.9585 20.8452 0 1 0 nc
+-539.894 -262.64 20.8452 0 0 1 nc
+-323.543 -433.964 20.8452 0 0 1 nc
+-309.657 -57.9033 20.8452 0 0 1 nc
+-67.9734 -347.42 20.8452 0 0 1 nc
+415.393 -289.516 20.8452 0 0 1 nc
+730.084 -307.139 20.8452 0 0 1 nc
+526.164 32.7279 20.8452 0 0 1 nc
+762.812 -17.6227 20.8452 0 0 1 nc
+-67.9734 319.727 20.8452 0 0 1 nc
+329.797 314.692 20.8452 0 0 1 nc
+-5.03507 561.41 20.8452 0 0 1 nc
+422.945 521.129 20.8452 0 0 1 nc
+-470.779 158.605 20.8452 0 0 1 nc
+986.873 -115.807 20.8452 0 0 1 nc
+906.312 201.403 20.8452 0 0 1 nc
+-767.847 113.289 20.8452 0 0 1 nc
+-579.033 445.603 20.8452 0 0 1 nc
+-840.856 -246.718 20.8452 0 0 1 nc
+206.221 -205.967 20.8452 1 1 0 nc
+277.311 -252.33 20.8452 1 1 0 nc
+271.13 -175.058 20.8452 1 1 0 nc
+366.947 -110.15 20.8452 1 1 0 nc
+397.855 -196.694 20.8452 1 1 0 nc
+438.037 -88.514 20.8452 1 1 0 nc
+286.584 -48.3327 20.8452 1 1 0 nc
+212.403 -23.6057 20.8452 1 1 0 nc
+280.402 10.3938 20.8452 1 1 0 nc
+694.579 115.483 20.8452 1 0 0 nc
+574.035 177.301 20.8452 1 0 0 nc
+grestore
+grestore
+showpage
diff --git a/doc/images/edge_biconnected_components.eps b/doc/images/edge_biconnected_components.eps
new file mode 100644
index 0000000..fda4879
--- /dev/null
+++ b/doc/images/edge_biconnected_components.eps
@@ -0,0 +1,159 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Mar  8 00:18:43 2013
+%%BoundingBox: 0 0 842 596
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+90 rotate
+0 -842 translate
+71.0944 15 translate
+0.434694 dup scale
+90 rotate
+860.856 -588.349 translate
+%Edges:
+gsave
+574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 6.25356 lb
+694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 6.25356 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 6.25356 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 6.25356 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 6.25356 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 6.25356 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 6.25356 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 6.25356 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 6.25356 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 6.25356 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 6.25356 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 6.25356 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 6.25356 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 6.25356 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 6.25356 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 6.25356 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 6.25356 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 6.25356 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 6.25356 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 6.25356 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 6.25356 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 6.25356 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 6.25356 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 6.25356 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 6.25356 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 6.25356 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 6.25356 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 6.25356 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 6.25356 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 6.25356 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 6.25356 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 6.25356 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 6.25356 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 6.25356 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 6.25356 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 6.25356 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 6.25356 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 6.25356 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 6.25356 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 6.25356 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 6.25356 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 6.25356 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 6.25356 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 6.25356 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 6.25356 lb
+-180.397 245.045 -113.509 338.465 -132.697 451.748 0 0 1 6.25356 lb
+-180.397 245.045 -199.585 358.328 -132.697 451.748 0 0 1 6.25356 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 6.25356 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 6.25356 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 6.25356 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 6.25356 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 6.25356 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 6.25356 lb
+-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 1 6.25356 lb
+-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 1 6.25356 lb
+grestore
+%Nodes:
+gsave
+-567.302 43.6423 20.8452 0 0 0 nc
+-689.204 -237.261 20.8452 0 0 0 nc
+924.667 409.347 20.8452 0 0 1 nc
+588.113 544.499 20.8452 0 0 1 nc
+670.264 274.195 20.8452 0 0 1 nc
+-371.2 568.349 20.8452 1 1 0 nc
+-132.697 451.748 20.8452 1 1 0 nc
+-416.25 345.746 20.8452 1 1 0 nc
+-180.397 245.045 20.8452 1 1 0 nc
+-13.4452 133.743 20.8452 1 1 0 nc
+-262.548 107.243 20.8452 1 1 0 nc
+201.208 38.3422 20.8452 1 1 0 nc
+116.407 -173.66 20.8452 1 1 0 nc
+-26.6953 -19.9585 20.8452 1 1 0 nc
+-539.894 -262.64 20.8452 0 0.5 0 nc
+-323.543 -433.964 20.8452 0 0.5 0 nc
+-309.657 -57.9033 20.8452 0 0.5 0 nc
+-67.9734 -347.42 20.8452 0 0.5 0 nc
+415.393 -289.516 20.8452 0.5 0 0 nc
+730.084 -307.139 20.8452 0.5 0 0 nc
+526.164 32.7279 20.8452 0.5 0 0 nc
+762.812 -17.6227 20.8452 0.5 0 0 nc
+-67.9734 319.727 20.8452 0.5 0 0 nc
+329.797 314.692 20.8452 0.5 0 0 nc
+-5.03507 561.41 20.8452 0.5 0 0 nc
+422.945 521.129 20.8452 0.5 0 0 nc
+-470.779 158.605 20.8452 0 1 1 nc
+986.873 -115.807 20.8452 0.5 0 0 nc
+906.312 201.403 20.8452 0.5 0 0 nc
+-767.847 113.289 20.8452 0 1 1 nc
+-579.033 445.603 20.8452 0 1 1 nc
+-840.856 -246.718 20.8452 1 0 1 nc
+206.221 -205.967 20.8452 0 0 0.5 nc
+277.311 -252.33 20.8452 0 0 0.5 nc
+271.13 -175.058 20.8452 0 0 0.5 nc
+366.947 -110.15 20.8452 0 0 0.5 nc
+397.855 -196.694 20.8452 0 0 0.5 nc
+438.037 -88.514 20.8452 0 0 0.5 nc
+286.584 -48.3327 20.8452 0 0 0.5 nc
+212.403 -23.6057 20.8452 0 0 0.5 nc
+280.402 10.3938 20.8452 0 0 0.5 nc
+694.579 115.483 20.8452 1 0 0 nc
+574.035 177.301 20.8452 0 1 0 nc
+grestore
+grestore
+showpage
diff --git a/doc/images/graph_to_eps.png b/doc/images/graph_to_eps.png
new file mode 100644
index 0000000..4d497f7
Binary files /dev/null and b/doc/images/graph_to_eps.png differ
diff --git a/doc/images/grid_graph.eps b/doc/images/grid_graph.eps
new file mode 100644
index 0000000..6dbf477
--- /dev/null
+++ b/doc/images/grid_graph.eps
@@ -0,0 +1,286 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: Grid undirected graph
+%%Copyright: (C) 2006 LEMON Project
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Sep 29 11:55:56 2006
+%%BoundingBox: 0 0 985 1144
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+2 2 scale
+50 40 translate
+5.5000 5.5000 scale
+% 1.14018 1.14018 translate
+%Edges:
+gsave
+70 80 70 90 0 0 0 0.5000 l
+70 70 70 80 0 0 0 0.5000 l
+70 60 70 70 0 0 0 0.5000 l
+70 50 70 60 0 0 0 0.5000 l
+70 40 70 50 0 0 0 0.5000 l
+70 30 70 40 0 0 0 0.5000 l
+70 20 70 30 0 0 0 0.5000 l
+70 10 70 20 0 0 0 0.5000 l
+70 0 70 10 0 0 0 0.5000 l
+60 80 60 90 0 0 0 0.5000 l
+60 70 60 80 0 0 0 0.5000 l
+60 60 60 70 0 0 0 0.5000 l
+60 50 60 60 0 0 0 0.5000 l
+60 40 60 50 0 0 0 0.5000 l
+60 30 60 40 0 0 0 0.5000 l
+60 20 60 30 0 0 0 0.5000 l
+60 10 60 20 0 0 0 0.5000 l
+60 0 60 10 0 0 0 0.5000 l
+50 80 50 90 0 0 0 0.5000 l
+50 70 50 80 0 0 0 0.5000 l
+50 60 50 70 0 0 0 0.5000 l
+50 50 50 60 0 0 0 0.5000 l
+50 40 50 50 0 0 0 0.5000 l
+50 30 50 40 0 0 0 0.5000 l
+50 20 50 30 0 0 0 0.5000 l
+50 10 50 20 0 0 0 0.5000 l
+50 0 50 10 0 0 0 0.5000 l
+40 80 40 90 0 0 0 0.5000 l
+40 70 40 80 0 0 0 0.5000 l
+40 60 40 70 0 0 0 0.5000 l
+40 50 40 60 0 0 0 0.5000 l
+40 40 40 50 0 0 0 0.5000 l
+40 30 40 40 0 0 0 0.5000 l
+40 20 40 30 0 0 0 0.5000 l
+40 10 40 20 0 0 0 0.5000 l
+40 0 40 10 0 0 0 0.5000 l
+30 80 30 90 0 0 0 0.5000 l
+30 70 30 80 0 0 0 0.5000 l
+30 60 30 70 0 0 0 0.5000 l
+30 50 30 60 0 0 0 0.5000 l
+30 40 30 50 0 0 0 0.5000 l
+30 30 30 40 0 0 0 0.5000 l
+30 20 30 30 0 0 0 0.5000 l
+30 10 30 20 0 0 0 0.5000 l
+30 0 30 10 0 0 0 0.5000 l
+20 80 20 90 0 0 0 0.5000 l
+20 70 20 80 0 0 0 0.5000 l
+20 60 20 70 0 0 0 0.5000 l
+20 50 20 60 0 0 0 0.5000 l
+20 40 20 50 0 0 0 0.5000 l
+20 30 20 40 0 0 0 0.5000 l
+20 20 20 30 0 0 0 0.5000 l
+20 10 20 20 0 0 0 0.5000 l
+20 0 20 10 0 0 0 0.5000 l
+10 80 10 90 0 0 0 0.5000 l
+10 70 10 80 0 0 0 0.5000 l
+10 60 10 70 0 0 0 0.5000 l
+10 50 10 60 0 0 0 0.5000 l
+10 40 10 50 0 0 0 0.5000 l
+10 30 10 40 0 0 0 0.5000 l
+10 20 10 30 0 0 0 0.5000 l
+10 10 10 20 0 0 0 0.5000 l
+10 0 10 10 0 0 0 0.5000 l
+0 80 0 90 0 0 0 0.5000 l
+0 70 0 80 0 0 0 0.5000 l
+0 60 0 70 0 0 0 0.5000 l
+0 50 0 60 0 0 0 0.5000 l
+0 40 0 50 0 0 0 0.5000 l
+0 30 0 40 0 0 0 0.5000 l
+0 20 0 30 0 0 0 0.5000 l
+0 10 0 20 0 0 0 0.5000 l
+0 0 0 10 0 0 0 0.5000 l
+60 90 70 90 0 0 0 0.5000 l
+60 80 70 80 0 0 0 0.5000 l
+60 70 70 70 0 0 0 0.5000 l
+60 60 70 60 0 0 0 0.5000 l
+60 50 70 50 0 0 0 0.5000 l
+60 40 70 40 0 0 0 0.5000 l
+60 30 70 30 0 0 0 0.5000 l
+60 20 70 20 0 0 0 0.5000 l
+60 10 70 10 0 0 0 0.5000 l
+60 0 70 0 0 0 0 0.5000 l
+50 90 60 90 0 0 0 0.5000 l
+50 80 60 80 0 0 0 0.5000 l
+50 70 60 70 0 0 0 0.5000 l
+50 60 60 60 0 0 0 0.5000 l
+50 50 60 50 0 0 0 0.5000 l
+50 40 60 40 0 0 0 0.5000 l
+50 30 60 30 0 0 0 0.5000 l
+50 20 60 20 0 0 0 0.5000 l
+50 10 60 10 0 0 0 0.5000 l
+50 0 60 0 0 0 0 0.5000 l
+40 90 50 90 0 0 0 0.5000 l
+40 80 50 80 0 0 0 0.5000 l
+40 70 50 70 0 0 0 0.5000 l
+40 60 50 60 0 0 0 0.5000 l
+40 50 50 50 0 0 0 0.5000 l
+40 40 50 40 0 0 0 0.5000 l
+40 30 50 30 0 0 0 0.5000 l
+40 20 50 20 0 0 0 0.5000 l
+40 10 50 10 0 0 0 0.5000 l
+40 0 50 0 0 0 0 0.5000 l
+30 90 40 90 0 0 0 0.5000 l
+30 80 40 80 0 0 0 0.5000 l
+30 70 40 70 0 0 0 0.5000 l
+30 60 40 60 0 0 0 0.5000 l
+30 50 40 50 0 0 0 0.5000 l
+30 40 40 40 0 0 0 0.5000 l
+30 30 40 30 0 0 0 0.5000 l
+30 20 40 20 0 0 0 0.5000 l
+30 10 40 10 0 0 0 0.5000 l
+30 0 40 0 0 0 0 0.5000 l
+20 90 30 90 0 0 0 0.5000 l
+20 80 30 80 0 0 0 0.5000 l
+20 70 30 70 0 0 0 0.5000 l
+20 60 30 60 0 0 0 0.5000 l
+20 50 30 50 0 0 0 0.5000 l
+20 40 30 40 0 0 0 0.5000 l
+20 30 30 30 0 0 0 0.5000 l
+20 20 30 20 0 0 0 0.5000 l
+20 10 30 10 0 0 0 0.5000 l
+20 0 30 0 0 0 0 0.5000 l
+10 90 20 90 0 0 0 0.5000 l
+10 80 20 80 0 0 0 0.5000 l
+10 70 20 70 0 0 0 0.5000 l
+10 60 20 60 0 0 0 0.5000 l
+10 50 20 50 0 0 0 0.5000 l
+10 40 20 40 0 0 0 0.5000 l
+10 30 20 30 0 0 0 0.5000 l
+10 20 20 20 0 0 0 0.5000 l
+10 10 20 10 0 0 0 0.5000 l
+10 0 20 0 0 0 0 0.5000 l
+0 90 10 90 0 0 0 0.5000 l
+0 80 10 80 0 0 0 0.5000 l
+0 70 10 70 0 0 0 0.5000 l
+0 60 10 60 0 0 0 0.5000 l
+0 50 10 50 0 0 0 0.5000 l
+0 40 10 40 0 0 0 0.5000 l
+0 30 10 30 0 0 0 0.5000 l
+0 20 10 20 0 0 0 0.5000 l
+0 10 10 10 0 0 0 0.5000 l
+0 0 10 0 0 0 0 0.5000 l
+grestore
+%Nodes:
+gsave
+70 90 1.4000 0 0 0 nc
+70 80 1.4000 1 1 1 nc
+70 70 1.4000 1 1 1 nc
+70 60 1.4000 1 1 1 nc
+70 50 1.4000 1 1 1 nc
+70 40 1.4000 1 1 1 nc
+70 30 1.4000 1 1 1 nc
+70 20 1.4000 1 1 1 nc
+70 10 1.4000 1 1 1 nc
+70 0 1.4000 0 0 0 nc
+60 90 1.4000 1 1 1 nc
+60 80 1.4000 1 1 1 nc
+60 70 1.4000 1 1 1 nc
+60 60 1.4000 1 1 1 nc
+60 50 1.4000 1 1 1 nc
+60 40 1.4000 1 1 1 nc
+60 30 1.4000 1 1 1 nc
+60 20 1.4000 1 1 1 nc
+60 10 1.4000 1 1 1 nc
+60 0 1.4000 1 1 1 nc
+50 90 1.4000 1 1 1 nc
+50 80 1.4000 1 1 1 nc
+50 70 1.4000 1 1 1 nc
+50 60 1.4000 1 1 1 nc
+50 50 1.4000 1 1 1 nc
+50 40 1.4000 1 1 1 nc
+50 30 1.4000 1 1 1 nc
+50 20 1.4000 1 1 1 nc
+50 10 1.4000 1 1 1 nc
+50 0 1.4000 1 1 1 nc
+40 90 1.4000 1 1 1 nc
+40 80 1.4000 1 1 1 nc
+40 70 1.4000 1 1 1 nc
+40 60 1.4000 1 1 1 nc
+40 50 1.4000 1 1 1 nc
+40 40 1.4000 1 1 1 nc
+40 30 1.4000 1 1 1 nc
+40 20 1.4000 1 1 1 nc
+40 10 1.4000 1 1 1 nc
+40 0 1.4000 1 1 1 nc
+30 90 1.4000 1 1 1 nc
+30 80 1.4000 1 1 1 nc
+30 70 1.4000 1 1 1 nc
+30 60 1.4000 1 1 1 nc
+30 50 1.4000 1 1 1 nc
+30 40 1.4000 1 1 1 nc
+30 30 1.4000 1 1 1 nc
+30 20 1.4000 1 1 1 nc
+30 10 1.4000 1 1 1 nc
+30 0 1.4000 1 1 1 nc
+20 90 1.4000 1 1 1 nc
+20 80 1.4000 1 1 1 nc
+20 70 1.4000 1 1 1 nc
+20 60 1.4000 1 1 1 nc
+20 50 1.4000 1 1 1 nc
+20 40 1.4000 1 1 1 nc
+20 30 1.4000 1 1 1 nc
+20 20 1.4000 1 1 1 nc
+20 10 1.4000 1 1 1 nc
+20 0 1.4000 1 1 1 nc
+10 90 1.4000 1 1 1 nc
+10 80 1.4000 1 1 1 nc
+10 70 1.4000 1 1 1 nc
+10 60 1.4000 1 1 1 nc
+10 50 1.4000 1 1 1 nc
+10 40 1.4000 1 1 1 nc
+10 30 1.4000 1 1 1 nc
+10 20 1.4000 1 1 1 nc
+10 10 1.4000 1 1 1 nc
+10 0 1.4000 1 1 1 nc
+0 90 1.4000 0 0 0 nc
+0 80 1.4000 1 1 1 nc
+0 70 1.4000 1 1 1 nc
+0 60 1.4000 1 1 1 nc
+0 50 1.4000 1 1 1 nc
+0 40 1.4000 1 1 1 nc
+0 30 1.4000 1 1 1 nc
+0 20 1.4000 1 1 1 nc
+0 10 1.4000 1 1 1 nc
+0 0 1.4000 0 0 0 nc
+grestore
+gsave
+/fosi 3.5 def
+(Helvetica) findfont fosi scalefont setfont
+0 0 0 setrgbcolor
+0 95 ((0,height-1)) cshow
+67 95 ((width-1,height-1)) cshow
+0 -5 ((0,0)) cshow
+70 -5 ((width-1,0)) cshow
+grestore
+grestore
+showpage
diff --git a/doc/images/matching.eps b/doc/images/matching.eps
new file mode 100644
index 0000000..2f418bd
--- /dev/null
+++ b/doc/images/matching.eps
@@ -0,0 +1,130 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Sun Mar 14 09:08:34 2010
+%%BoundingBox: -353 -264 559 292
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
+  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
+  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
+  5 index 5 index 5 index c fill
+  setrgbcolor 1.1 div c fill
+  } bind def
+/nmale {
+  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto
+  5 index 4 index 1 mul 1.5 mul add
+  5 index 5 index 3 sqrt 1.5 mul mul add
+  1 index 1 index lineto
+  1 index 1 index 7 index sub moveto
+  1 index 1 index lineto
+  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
+  stroke
+  5 index 5 index 5 index c fill
+  setrgbcolor 1.1 div c fill
+  } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+%Arcs:
+gsave
+140.321 266.249 -327.729 150.06 0 0 0 4.99223 l
+82.1207 -238.726 -245.288 -110.743 0 0 0 4.99223 l
+336.635 -229.036 533.603 13.109 0 0 0 4.99223 l
+53.8598 -45.8071 -245.288 -110.743 0 0 0 4.99223 l
+-75.5617 118.579 -327.729 150.06 0 0 0 4.99223 l
+-327.729 150.06 -245.288 -110.743 1 0 0 11.9813 l
+533.603 13.109 218.184 -84.2955 0 0 0 4.99223 l
+39.87 175.035 141.163 67.2575 0 0 0 4.99223 l
+53.8598 -45.8071 -75.5617 118.579 0 0 0 4.99223 l
+-102.406 -141.267 82.1207 -238.726 0 0 0 4.99223 l
+399.144 166.894 533.603 13.109 1 0 0 11.9813 l
+39.87 175.035 140.321 266.249 1 0 0 11.9813 l
+399.144 166.894 140.321 266.249 0 0 0 4.99223 l
+399.144 166.894 141.163 67.2575 0 0 0 4.99223 l
+53.8598 -45.8071 204.765 -173.77 0 0 0 4.99223 l
+82.1207 -238.726 204.765 -173.77 0 0 0 4.99223 l
+258.227 61.658 399.144 166.894 0 0 0 4.99223 l
+53.8598 -45.8071 -102.406 -141.267 1 0 0 11.9813 l
+175.073 -37.4477 141.163 67.2575 0 0 0 4.99223 l
+258.227 61.658 380 0 0 0 0 4.99223 l
+34.6739 40.8267 -75.5617 118.579 1 0 0 11.9813 l
+380 0 533.603 13.109 0 0 0 4.99223 l
+175.073 -37.4477 380 0 0 0 0 4.99223 l
+218.184 -84.2955 204.765 -173.77 0 0 0 4.99223 l
+53.8598 -45.8071 34.6739 40.8267 0 0 0 4.99223 l
+167.905 -213.988 82.1207 -238.726 1 0 0 11.9813 l
+336.635 -229.036 204.765 -173.77 1 0 0 11.9813 l
+336.635 -229.036 167.905 -213.988 0 0 0 4.99223 l
+329.08 -26.3098 218.184 -84.2955 0 0 0 4.99223 l
+39.87 175.035 -75.5617 118.579 0 0 0 4.99223 l
+53.8598 -45.8071 175.073 -37.4477 0 0 0 4.99223 l
+34.6739 40.8267 141.163 67.2575 0 0 0 4.99223 l
+258.227 61.658 141.163 67.2575 1 0 0 11.9813 l
+175.073 -37.4477 218.184 -84.2955 1 0 0 11.9813 l
+380 0 329.08 -26.3098 1 0 0 11.9813 l
+grestore
+%Nodes:
+gsave
+-245.288 -110.743 14.9767 1 1 1 nc
+204.765 -173.77 14.9767 1 1 1 nc
+-327.729 150.06 14.9767 1 1 1 nc
+-75.5617 118.579 14.9767 1 1 1 nc
+218.184 -84.2955 14.9767 1 1 1 nc
+140.321 266.249 14.9767 1 1 1 nc
+141.163 67.2575 14.9767 1 1 1 nc
+82.1207 -238.726 14.9767 1 1 1 nc
+329.08 -26.3098 14.9767 1 1 1 nc
+-102.406 -141.267 14.9767 1 1 1 nc
+533.603 13.109 14.9767 1 1 1 nc
+167.905 -213.988 14.9767 1 1 1 nc
+336.635 -229.036 14.9767 1 1 1 nc
+380 0 14.9767 1 1 1 nc
+399.144 166.894 14.9767 1 1 1 nc
+34.6739 40.8267 14.9767 1 1 1 nc
+39.87 175.035 14.9767 1 1 1 nc
+175.073 -37.4477 14.9767 1 1 1 nc
+53.8598 -45.8071 14.9767 1 1 1 nc
+258.227 61.658 14.9767 1 1 1 nc
+grestore
+grestore
+showpage
diff --git a/doc/images/node_biconnected_components.eps b/doc/images/node_biconnected_components.eps
new file mode 100644
index 0000000..55a9b21
--- /dev/null
+++ b/doc/images/node_biconnected_components.eps
@@ -0,0 +1,159 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Mar  8 00:18:43 2013
+%%BoundingBox: 0 0 842 596
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+90 rotate
+0 -842 translate
+71.0944 15 translate
+0.434694 dup scale
+90 rotate
+860.856 -588.349 translate
+%Edges:
+gsave
+574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 6.25356 lb
+694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 6.25356 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 6.25356 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 6.25356 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 6.25356 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 6.25356 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 6.25356 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 6.25356 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 6.25356 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 6.25356 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 6.25356 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 6.25356 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 6.25356 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 6.25356 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 6.25356 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 6.25356 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 6.25356 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 6.25356 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 6.25356 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 6.25356 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 6.25356 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 6.25356 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 6.25356 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 6.25356 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 6.25356 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 6.25356 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 6.25356 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 6.25356 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 6.25356 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 6.25356 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 6.25356 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 6.25356 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 6.25356 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 6.25356 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 6.25356 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 6.25356 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 6.25356 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 6.25356 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 6.25356 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 6.25356 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 6.25356 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 6.25356 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 6.25356 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 6.25356 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 6.25356 lb
+-180.397 245.045 -113.509 338.465 -132.697 451.748 0 1 1 6.25356 lb
+-180.397 245.045 -199.585 358.328 -132.697 451.748 0 1 1 6.25356 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 6.25356 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 6.25356 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 6.25356 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 6.25356 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 6.25356 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 6.25356 lb
+-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 0 6.25356 lb
+-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 0 6.25356 lb
+grestore
+%Nodes:
+gsave
+-567.302 43.6423 20.8452 0 0 1 nc
+-689.204 -237.261 20.8452 0 0 1 nc
+924.667 409.347 20.8452 0 0 1 nc
+588.113 544.499 20.8452 0 0 1 nc
+670.264 274.195 20.8452 1 0 0 nc
+-371.2 568.349 20.8452 0 0 1 nc
+-132.697 451.748 20.8452 1 0 0 nc
+-416.25 345.746 20.8452 0 0 1 nc
+-180.397 245.045 20.8452 1 0 0 nc
+-13.4452 133.743 20.8452 0 0 1 nc
+-262.548 107.243 20.8452 0 0 1 nc
+201.208 38.3422 20.8452 0 0 1 nc
+116.407 -173.66 20.8452 0 0 1 nc
+-26.6953 -19.9585 20.8452 1 0 0 nc
+-539.894 -262.64 20.8452 0 0 1 nc
+-323.543 -433.964 20.8452 0 0 1 nc
+-309.657 -57.9033 20.8452 1 0 0 nc
+-67.9734 -347.42 20.8452 1 0 0 nc
+415.393 -289.516 20.8452 1 0 0 nc
+730.084 -307.139 20.8452 0 0 1 nc
+526.164 32.7279 20.8452 1 0 0 nc
+762.812 -17.6227 20.8452 1 0 0 nc
+-67.9734 319.727 20.8452 0 0 1 nc
+329.797 314.692 20.8452 0 0 1 nc
+-5.03507 561.41 20.8452 0 0 1 nc
+422.945 521.129 20.8452 0 0 1 nc
+-470.779 158.605 20.8452 1 0 0 nc
+986.873 -115.807 20.8452 0 0 1 nc
+906.312 201.403 20.8452 0 0 1 nc
+-767.847 113.289 20.8452 1 0 0 nc
+-579.033 445.603 20.8452 0 0 1 nc
+-840.856 -246.718 20.8452 0 0 1 nc
+206.221 -205.967 20.8452 0 0 1 nc
+277.311 -252.33 20.8452 0 0 1 nc
+271.13 -175.058 20.8452 1 0 0 nc
+366.947 -110.15 20.8452 1 0 0 nc
+397.855 -196.694 20.8452 0 0 1 nc
+438.037 -88.514 20.8452 0 0 1 nc
+286.584 -48.3327 20.8452 1 0 0 nc
+212.403 -23.6057 20.8452 0 0 1 nc
+280.402 10.3938 20.8452 0 0 1 nc
+694.579 115.483 20.8452 0 0 1 nc
+574.035 177.301 20.8452 0 0 1 nc
+grestore
+grestore
+showpage
diff --git a/doc/images/nodeshape_0.eps b/doc/images/nodeshape_0.eps
new file mode 100644
index 0000000..5f2f4a8
--- /dev/null
+++ b/doc/images/nodeshape_0.eps
@@ -0,0 +1,57 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: LEMON GraphToEps figure
+%%Creator: LEMON GraphToEps function
+%%BoundingBox: 0 0 200 200
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+100 dup scale
+%Edges:
+gsave
+grestore
+%Nodes:
+gsave
+1 1 1 0.2 1 0.2 nc
+grestore
+grestore
+showpage
diff --git a/doc/images/nodeshape_1.eps b/doc/images/nodeshape_1.eps
new file mode 100644
index 0000000..e8b1104
--- /dev/null
+++ b/doc/images/nodeshape_1.eps
@@ -0,0 +1,57 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: LEMON GraphToEps figure
+%%Creator: LEMON GraphToEps function
+%%BoundingBox: 0 0 200 200
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+100 dup scale
+%Edges:
+gsave
+grestore
+%Nodes:
+gsave
+1 1 1 0.2 1 0.2 nsq
+grestore
+grestore
+showpage
diff --git a/doc/images/nodeshape_2.eps b/doc/images/nodeshape_2.eps
new file mode 100644
index 0000000..5dcc4aa
--- /dev/null
+++ b/doc/images/nodeshape_2.eps
@@ -0,0 +1,57 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: LEMON GraphToEps figure
+%%Creator: LEMON GraphToEps function
+%%BoundingBox: 0 0 200 200
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+100 dup scale
+%Edges:
+gsave
+grestore
+%Nodes:
+gsave
+1 1 1 0.2 1 0.2 ndi
+grestore
+grestore
+showpage
diff --git a/doc/images/nodeshape_3.eps b/doc/images/nodeshape_3.eps
new file mode 100644
index 0000000..bc736af
--- /dev/null
+++ b/doc/images/nodeshape_3.eps
@@ -0,0 +1,77 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: LEMON GraphToEps figure
+%%Creator: LEMON GraphToEps function
+%%BoundingBox: 0 0 256 372
+%%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
+100 dup scale
+%Edges:
+gsave
+grestore
+%Nodes:
+gsave
+1 1 1 0.2 1 0.2 nmale
+grestore
+grestore
+showpage
diff --git a/doc/images/nodeshape_4.eps b/doc/images/nodeshape_4.eps
new file mode 100644
index 0000000..e9fa575
--- /dev/null
+++ b/doc/images/nodeshape_4.eps
@@ -0,0 +1,77 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: LEMON GraphToEps figure
+%%Creator: LEMON GraphToEps function
+%%BoundingBox: 0 -199 200 200
+%%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
+100 dup scale
+%Edges:
+gsave
+grestore
+%Nodes:
+gsave
+1 1 1 0.2 1 0.2 nfemale
+grestore
+grestore
+showpage
diff --git a/doc/images/planar.eps b/doc/images/planar.eps
new file mode 100644
index 0000000..97d0aaf
--- /dev/null
+++ b/doc/images/planar.eps
@@ -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
diff --git a/doc/images/strongly_connected_components.eps b/doc/images/strongly_connected_components.eps
new file mode 100644
index 0000000..0997706
--- /dev/null
+++ b/doc/images/strongly_connected_components.eps
@@ -0,0 +1,180 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Mar  8 00:22:15 2013
+%%BoundingBox: 0 0 842 596
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 10 def
+/arrw 3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+90 rotate
+0 -842 translate
+77.1122 15 translate
+0.585745 dup scale
+90 rotate
+695.963 -397.916 translate
+%Edges:
+gsave
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+218.178 27.2723 moveto
+195.849 -31.0725 190.033 -46.2697 176.306 -82.1369 curveto stroke
+newpath 163.235 -116.291 moveto 165.206 -77.8889 lineto 187.405 -86.3849 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+44.8044 15.5841 moveto
+109.705 19.9594 126.016 21.0591 166.493 23.7879 curveto stroke
+newpath 202.98 26.2477 moveto 167.292 11.9299 lineto 165.694 35.6458 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
+218.178 27.2723 moveto
+281.264 -80.3935 289.87 -95.0808 338.092 -177.379 curveto stroke
+newpath 356.579 -208.932 moveto 327.837 -183.388 lineto 348.346 -171.371 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+157.79 -130.517 moveto
+114.446 -74.4692 104.358 -61.4239 76.4943 -25.394 curveto stroke
+newpath 54.1228 3.53455 moveto 85.8959 -18.1234 lineto 67.0928 -32.6646 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
+-105.193 -261.035 moveto
+-39.4801 -139.85 -31.344 -124.846 20.1113 -29.9539 curveto stroke
+newpath 37.5434 2.19358 moveto 30.559 -35.6192 lineto 9.66361 -24.2886 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-465.576 -42.8564 moveto
+-550.335 -27.1603 -566.8 -24.1113 -625.027 -13.3286 curveto stroke
+newpath -660.985 -6.66971 moveto -622.863 -1.64245 lineto -627.191 -25.0148 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-574.666 -153.893 moveto
+-535.911 -114.447 -524.692 -103.027 -501.88 -79.8085 curveto stroke
+newpath -476.251 -53.7222 moveto -493.402 -88.1377 lineto -510.358 -71.4793 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
+-490.901 120.777 moveto
+-481.623 60.8277 -479.143 44.8049 -473.499 8.33636 curveto stroke
+newpath -467.906 -27.8032 moveto -485.244 6.51862 lineto -461.754 10.1541 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-675.963 -3.89604 moveto
+-637.405 -60.9909 -628.201 -74.6206 -603.658 -110.963 curveto stroke
+newpath -583.191 -141.27 moveto -613.507 -117.615 lineto -593.808 -104.312 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-490.901 120.777 moveto
+-439.75 208.465 -431.238 223.057 -394.278 286.417 curveto stroke
+newpath -375.851 318.006 moveto -384.012 280.429 lineto -404.543 292.406 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-266.879 114.933 moveto
+-358.311 117.318 -375.109 117.756 -439.117 119.426 curveto stroke
+newpath -475.674 120.38 moveto -438.807 131.307 lineto -439.426 107.545 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-368.176 331.163 moveto
+-326.156 241.466 -318.997 226.186 -288.855 161.843 curveto stroke
+newpath -273.341 128.727 moveto -299.617 156.801 lineto -278.092 166.885 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
+-266.879 114.933 moveto
+-226.764 227.755 -221.069 243.774 -190.728 329.107 curveto stroke
+newpath -178.477 363.564 moveto -179.53 325.126 lineto -201.926 333.089 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-251.294 -335.059 moveto
+-198.044 -308.079 -183.61 -300.766 -151.402 -284.448 curveto stroke
+newpath -118.781 -267.92 moveto -146.031 -295.049 lineto -156.774 -273.846 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-389.604 -136.361 moveto
+-332.039 -219.059 -322.392 -232.919 -280.889 -292.543 curveto stroke
+newpath -259.996 -322.557 moveto -290.643 -299.333 lineto -271.134 -285.753 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
+5.84406 175.322 moveto
+-70.5724 261.706 -81.8227 274.423 -139.051 339.116 curveto stroke
+newpath -163.281 366.507 moveto -130.149 346.991 lineto -147.953 331.242 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+169.478 311.683 moveto
+103.641 256.819 90.7821 246.103 45.6398 208.485 curveto stroke
+newpath 17.546 185.074 moveto 38.0313 217.615 lineto 53.2483 199.355 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+342.851 111.037 moveto
+269.224 196.246 258.132 209.083 203.347 272.486 curveto stroke
+newpath 179.437 300.157 moveto 212.34 280.257 lineto 194.354 264.716 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+5.84406 175.322 moveto
+155.419 146.79 172.221 143.585 291.966 120.743 curveto stroke
+newpath 327.888 113.891 moveto 289.739 109.069 lineto 294.193 132.418 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+342.851 111.037 moveto
+490.978 6.99574 505.015 -2.86383 627.727 -89.0547 curveto stroke
+newpath 657.653 -110.074 moveto 620.896 -98.7802 lineto 634.558 -79.3291 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+364.28 -222.074 moveto
+354.807 -74.8128 353.709 -57.7536 346.177 59.3416 curveto stroke
+newpath 343.829 95.836 moveto 358.037 60.1045 lineto 334.316 58.5786 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+670.118 -118.829 moveto
+535.595 -164.241 519.412 -169.704 413.361 -205.505 curveto stroke
+newpath 378.712 -217.202 moveto 409.559 -194.245 lineto 417.162 -216.766 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
+-105.193 -261.035 moveto
+110.939 -243.099 128.069 -241.677 312.655 -226.358 curveto stroke
+newpath 349.1 -223.334 moveto 313.638 -238.202 lineto 311.672 -214.514 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-105.193 -261.035 moveto
+-156.746 -168.566 -164.987 -153.784 -202.693 -86.1539 curveto stroke
+newpath -220.5 -54.2129 moveto -192.312 -80.3665 lineto -213.073 -91.9413 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
+-227.918 -40.9084 moveto
+-290.327 -77.7521 -304.558 -86.1532 -344.995 -110.026 curveto stroke
+newpath -376.487 -128.617 moveto -351.037 -99.7914 lineto -338.953 -120.26 lineto closepath fill
+grestore
+%Nodes:
+gsave
+-389.604 -136.361 15.2324 0 1 0 nc
+-227.918 -40.9084 15.2324 0 1 0 nc
+-105.193 -261.035 15.2324 0 1 0 nc
+364.28 -222.074 15.2324 1 1 0 nc
+670.118 -118.829 15.2324 1 1 0 nc
+342.851 111.037 15.2324 1 1 0 nc
+5.84406 175.322 15.2324 1 1 0 nc
+169.478 311.683 15.2324 1 1 0 nc
+-173.374 377.916 15.2324 1 0 1 nc
+-251.294 -335.059 15.2324 0 1 0 nc
+-266.879 114.933 15.2324 0 0 0 nc
+-368.176 331.163 15.2324 0 0 0 nc
+-490.901 120.777 15.2324 0 0 0 nc
+-574.666 -153.893 15.2324 1 0 0 nc
+-675.963 -3.89604 15.2324 1 0 0 nc
+-465.576 -42.8564 15.2324 1 0 0 nc
+44.8044 15.5841 15.2324 0 0 1 nc
+157.79 -130.517 15.2324 0 0 1 nc
+218.178 27.2723 15.2324 0 0 1 nc
+grestore
+grestore
+showpage
diff --git a/doc/images/tsp.eps b/doc/images/tsp.eps
new file mode 100644
index 0000000..20bda96
--- /dev/null
+++ b/doc/images/tsp.eps
@@ -0,0 +1,229 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Tue Jun 15 00:58:57 2010
+%%BoundingBox: 31 41 649 709
+%%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
+10 dup scale
+%Arcs:
+gsave
+27 68 37 69 0 0 1 0.513798 l
+37 69 27 68 0 0 1 0.513798 l
+8 52 5 64 0 0 1 0.513798 l
+5 64 8 52 0 0 1 0.513798 l
+16 57 25 55 0 0 1 0.513798 l
+25 55 16 57 0 0 1 0.513798 l
+43 67 37 69 0 0 1 0.513798 l
+37 69 43 67 0 0 1 0.513798 l
+42 57 43 67 0 0 1 0.513798 l
+43 67 42 57 0 0 1 0.513798 l
+62 42 61 33 0 0 1 0.513798 l
+61 33 62 42 0 0 1 0.513798 l
+62 42 58 48 0 0 1 0.513798 l
+58 48 62 42 0 0 1 0.513798 l
+58 27 61 33 0 0 1 0.513798 l
+61 33 58 27 0 0 1 0.513798 l
+57 58 62 63 0 0 1 0.513798 l
+62 63 57 58 0 0 1 0.513798 l
+13 13 21 10 0 0 1 0.513798 l
+21 10 13 13 0 0 1 0.513798 l
+13 13 5 6 0 0 1 0.513798 l
+5 6 13 13 0 0 1 0.513798 l
+17 33 7 38 0 0 1 0.513798 l
+7 38 17 33 0 0 1 0.513798 l
+46 10 59 15 0 0 1 0.513798 l
+59 15 46 10 0 0 1 0.513798 l
+46 10 39 10 0 0 1 0.513798 l
+39 10 46 10 0 0 1 0.513798 l
+27 23 21 10 0 0 1 0.513798 l
+21 10 27 23 0 0 1 0.513798 l
+52 41 56 37 0 0 1 0.513798 l
+56 37 52 41 0 0 1 0.513798 l
+62 63 63 69 0 0 1 0.513798 l
+63 69 62 63 0 0 1 0.513798 l
+36 16 39 10 0 0 1 0.513798 l
+39 10 36 16 0 0 1 0.513798 l
+36 16 30 15 0 0 1 0.513798 l
+30 15 36 16 0 0 1 0.513798 l
+12 42 7 38 0 0 1 0.513798 l
+7 38 12 42 0 0 1 0.513798 l
+12 42 8 52 0 0 1 0.513798 l
+8 52 12 42 0 0 1 0.513798 l
+32 22 30 15 0 0 1 0.513798 l
+30 15 32 22 0 0 1 0.513798 l
+5 25 10 17 0 0 1 0.513798 l
+10 17 5 25 0 0 1 0.513798 l
+5 25 17 33 0 0 1 0.513798 l
+17 33 5 25 0 0 1 0.513798 l
+45 35 48 28 0 0 1 0.513798 l
+48 28 45 35 0 0 1 0.513798 l
+31 32 25 32 0 0 1 0.513798 l
+25 32 31 32 0 0 1 0.513798 l
+31 32 32 39 0 0 1 0.513798 l
+32 39 31 32 0 0 1 0.513798 l
+42 41 38 46 0 0 1 0.513798 l
+38 46 42 41 0 0 1 0.513798 l
+42 41 52 41 0 0 1 0.513798 l
+52 41 42 41 0 0 1 0.513798 l
+5 6 10 17 0 0 1 0.513798 l
+10 17 5 6 0 0 1 0.513798 l
+51 21 59 15 0 0 1 0.513798 l
+59 15 51 21 0 0 1 0.513798 l
+51 21 58 27 0 0 1 0.513798 l
+58 27 51 21 0 0 1 0.513798 l
+52 33 56 37 0 0 1 0.513798 l
+56 37 52 33 0 0 1 0.513798 l
+52 33 48 28 0 0 1 0.513798 l
+48 28 52 33 0 0 1 0.513798 l
+31 62 25 55 0 0 1 0.513798 l
+25 55 31 62 0 0 1 0.513798 l
+31 62 27 68 0 0 1 0.513798 l
+27 68 31 62 0 0 1 0.513798 l
+17 63 5 64 0 0 1 0.513798 l
+5 64 17 63 0 0 1 0.513798 l
+17 63 16 57 0 0 1 0.513798 l
+16 57 17 63 0 0 1 0.513798 l
+21 47 30 40 0 0 1 0.513798 l
+30 40 21 47 0 0 1 0.513798 l
+21 47 30 48 0 0 1 0.513798 l
+30 48 21 47 0 0 1 0.513798 l
+40 30 45 35 0 0 1 0.513798 l
+45 35 40 30 0 0 1 0.513798 l
+40 30 32 22 0 0 1 0.513798 l
+32 22 40 30 0 0 1 0.513798 l
+32 39 30 40 0 0 1 0.513798 l
+30 40 32 39 0 0 1 0.513798 l
+20 26 25 32 0 0 1 0.513798 l
+25 32 20 26 0 0 1 0.513798 l
+20 26 27 23 0 0 1 0.513798 l
+27 23 20 26 0 0 1 0.513798 l
+52 64 63 69 0 0 1 0.513798 l
+63 69 52 64 0 0 1 0.513798 l
+52 64 42 57 0 0 1 0.513798 l
+42 57 52 64 0 0 1 0.513798 l
+49 49 58 48 0 0 1 0.513798 l
+58 48 49 49 0 0 1 0.513798 l
+49 49 57 58 0 0 1 0.513798 l
+57 58 49 49 0 0 1 0.513798 l
+37 52 38 46 0 0 1 0.513798 l
+38 46 37 52 0 0 1 0.513798 l
+37 52 30 48 0 0 1 0.513798 l
+30 48 37 52 0 0 1 0.513798 l
+grestore
+%Nodes:
+gsave
+30 40 0.856329 1 1 1 nc
+56 37 0.856329 1 1 1 nc
+48 28 0.856329 1 1 1 nc
+25 55 0.856329 1 1 1 nc
+25 32 0.856329 1 1 1 nc
+32 39 0.856329 1 1 1 nc
+39 10 0.856329 1 1 1 nc
+30 15 0.856329 1 1 1 nc
+5 64 0.856329 1 1 1 nc
+21 10 0.856329 1 1 1 nc
+10 17 0.856329 1 1 1 nc
+5 6 0.856329 1 1 1 nc
+59 15 0.856329 1 1 1 nc
+45 35 0.856329 1 1 1 nc
+32 22 0.856329 1 1 1 nc
+63 69 0.856329 1 1 1 nc
+62 63 0.856329 1 1 1 nc
+61 33 0.856329 1 1 1 nc
+46 10 0.856329 1 1 1 nc
+38 46 0.856329 1 1 1 nc
+37 69 0.856329 1 1 1 nc
+58 27 0.856329 1 1 1 nc
+58 48 0.856329 1 1 1 nc
+43 67 0.856329 1 1 1 nc
+30 48 0.856329 1 1 1 nc
+27 68 0.856329 1 1 1 nc
+7 38 0.856329 1 1 1 nc
+8 52 0.856329 1 1 1 nc
+16 57 0.856329 1 1 1 nc
+42 57 0.856329 1 1 1 nc
+62 42 0.856329 1 1 1 nc
+57 58 0.856329 1 1 1 nc
+13 13 0.856329 1 1 1 nc
+17 33 0.856329 1 1 1 nc
+27 23 0.856329 1 1 1 nc
+52 41 0.856329 1 1 1 nc
+36 16 0.856329 1 1 1 nc
+12 42 0.856329 1 1 1 nc
+5 25 0.856329 1 1 1 nc
+31 32 0.856329 1 1 1 nc
+42 41 0.856329 1 1 1 nc
+51 21 0.856329 1 1 1 nc
+52 33 0.856329 1 1 1 nc
+31 62 0.856329 1 1 1 nc
+17 63 0.856329 1 1 1 nc
+21 47 0.856329 1 1 1 nc
+40 30 0.856329 1 1 1 nc
+20 26 0.856329 1 1 1 nc
+52 64 0.856329 1 1 1 nc
+49 49 0.856329 1 1 1 nc
+37 52 0.856329 1 1 1 nc
+grestore
+grestore
+showpage
diff --git a/doc/lgf.dox b/doc/lgf.dox
new file mode 100644
index 0000000..a04fccb
--- /dev/null
+++ b/doc/lgf.dox
@@ -0,0 +1,135 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+namespace lemon {
+/*!
+
+
+
+\page lgf-format LEMON Graph Format (LGF)
+
+The \e LGF is a <em>column oriented</em>
+file format for storing graphs and associated data like
+node and edge maps.
+
+Each line with \c '#' first non-whitespace
+character is considered as a comment line.
+
+Otherwise the file consists of sections starting with
+a header line. The header lines starts with an \c '@' character followed by the
+type of section. The standard section types are \c \@nodes, \c
+\@arcs and \c \@edges
+and \@attributes. Each header line may also have an optional
+\e name, which can be use to distinguish the sections of the same
+type.
+
+The standard sections are column oriented, each line consists of
+<em>token</em>s separated by whitespaces. A token can be \e plain or
+\e quoted. A plain token is just a sequence of non-whitespace characters,
+while a quoted token is a
+character sequence surrounded by double quotes, and it can also
+contain whitespaces and escape sequences.
+
+The \c \@nodes section describes a set of nodes and associated
+maps. The first is a header line, its columns are the names of the
+maps appearing in the following lines.
+One of the maps must be called \c
+"label", which plays special role in the file.
+The following
+non-empty lines until the next section describes nodes of the
+graph. Each line contains the values of the node maps
+associated to the current node.
+
+\code
+ @nodes
+ label  coordinates  size    title
+ 1      (10,20)      10      "First node"
+ 2      (80,80)      8       "Second node"
+ 3      (40,10)      10      "Third node"
+\endcode
+
+The \e LGF files can also contain bipartite graphs, in this case a
+\c \@red_nodes and a \c \@blue_nodes sections describe the node set of the
+graph. If a map is in both of these sections, then it can be used as a
+regular node map.
+
+\code
+ @red_nodes
+ label  only_red_map   name
+ 1      "cherry"       "John"
+ 2      "Santa Claus"  "Jack"
+ 3      "blood"        "Jason"
+ @blue_nodes
+ label  name
+ 4      "Elisabeth"
+ 5      "Eve"
+\endcode
+
+The \c \@arcs section is very similar to the \c \@nodes section,
+it again starts with a header line describing the names of the maps,
+but the \c "label" map is not obligatory here. The following lines
+describe the arcs. The first two tokens of each line are
+the source and the target node of the arc, respectively, then come the map
+values. The source and target tokens must be node labels.
+
+\code
+ @arcs
+         capacity
+ 1   2   16
+ 1   3   12
+ 2   3   18
+\endcode
+
+If there is no map in the \c \@arcs section at all, then it must be
+indicated by a sole '-' sign in the first line.
+
+\code
+ @arcs
+         -
+ 1   2
+ 1   3
+ 2   3
+\endcode
+
+The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can
+also store the edge set of an undirected graph. In such case there is
+a conventional method for store arc maps in the file, if two columns
+have the same caption with \c '+' and \c '-' prefix, then these columns
+can be regarded as the values of an arc map.
+
+The \c \@attributes section contains key-value pairs, each line
+consists of two tokens, an attribute name, and then an attribute
+value. The value of the attribute could be also a label value of a
+node or an edge, or even an edge label prefixed with \c '+' or \c '-',
+which regards to the forward or backward directed arc of the
+corresponding edge.
+
+\code
+ @attributes
+ source 1
+ target 3
+ caption "LEMON test digraph"
+\endcode
+
+The \e LGF can contain extra sections, but there is no restriction on
+the format of such sections.
+
+*/
+}
+
+//  LocalWords:  whitespace whitespaces
diff --git a/doc/license.dox b/doc/license.dox
new file mode 100644
index 0000000..a40939b
--- /dev/null
+++ b/doc/license.dox
@@ -0,0 +1,25 @@
+/* -*- 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.
+ *
+ */
+
+/**
+
+\page license License Terms
+
+\verbinclude LICENSE
+
+*/
diff --git a/doc/mainpage.dox.in b/doc/mainpage.dox.in
new file mode 100644
index 0000000..b384df5
--- /dev/null
+++ b/doc/mainpage.dox.in
@@ -0,0 +1,61 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+/**
+\mainpage @PACKAGE_NAME@ @PACKAGE_VERSION@ Documentation
+
+\section intro Introduction
+
+<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
+and <b>O</b>ptimization in <b>N</b>etworks</i>.
+It is a C++ template library providing efficient implementations of common
+data structures and algorithms with focus on combinatorial optimization
+tasks connected mainly with graphs and networks \cite DezsoJuttnerKovacs11Lemon.
+
+<b>
+LEMON is an <a class="el" href="http://opensource.org/">open source</a>
+project.
+You are free to use it in your commercial or
+non-commercial applications under very permissive
+\ref license "license terms".
+</b>
+
+The project is maintained by the
+<a href="http://www.cs.elte.hu/egres/">Egerváry Research Group on
+Combinatorial Optimization</a> \cite egres
+at the Operations Research Department of the
+<a href="http://www.elte.hu/en/">Eötvös Loránd University</a>,
+Budapest, Hungary.
+LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
+initiative \cite coinor.
+
+\section howtoread How to Read the Documentation
+
+If you would like to get to know the library, see
+<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
+
+If you are interested in starting to use the library, see the <a class="el"
+href="http://lemon.cs.elte.hu/trac/lemon/wiki/InstallGuide/">Installation
+Guide</a>.
+
+If you know what you are looking for, then try to find it under the
+<a class="el" href="modules.html">Modules</a> section.
+
+If you are a user of the old (0.x) series of LEMON, please check out the
+\ref migration "Migration Guide" for the backward incompatibilities.
+*/
diff --git a/doc/migration.dox b/doc/migration.dox
new file mode 100644
index 0000000..3117aa3
--- /dev/null
+++ b/doc/migration.dox
@@ -0,0 +1,145 @@
+/* -*- 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.
+ *
+ */
+
+namespace lemon {
+/*!
+
+\page migration Migration from the 0.x Series
+
+This guide gives an in depth description on what has changed compared
+to the 0.x release series.
+
+Many of these changes adjusted automatically by the
+<tt>lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
+update are typeset <b>boldface</b>.
+
+\section migration-graph Graph Related Name Changes
+
+- \ref concepts::Digraph "Directed graphs" are called \c Digraph and
+  they have <tt>Arc</tt>s (instead of <tt>Edge</tt>s), while
+  \ref concepts::Graph "undirected graphs" are called \c Graph
+  (instead of \c UGraph) and they have <tt>Edge</tt>s (instead of
+  <tt>UEdge</tt>s). These changes reflected thoroughly everywhere in
+  the library. Namely,
+  - \c Graph -> \c Digraph
+    - \c %ListGraph -> \c ListDigraph, \c %SmartGraph -> \c SmartDigraph etc.
+  - \c UGraph -> \c Graph
+    - \c ListUGraph -> \c ListGraph, \c SmartUGraph -> \c SmartGraph etc.
+  - \c Edge -> \c Arc, \c UEdge -> \c Edge
+  - \c EdgeMap -> \c ArcMap, \c UEdgeMap -> \c EdgeMap
+  - \c EdgeIt -> \c ArcIt, \c UEdgeIt -> \c EdgeIt
+  - Class names and function names containing the words \c graph,
+    \c ugraph, \e edge or \e arc should also be updated.
+- <b>The two endpoints of an (\e undirected) \c Edge can be obtained by the
+  <tt>u()</tt> and <tt>v()</tt> member function of the graph
+  (instead of <tt>source()</tt> and <tt>target()</tt>). This change
+  must be done by hand.</b>
+  \n Of course, you can still use <tt>source()</tt> and <tt>target()</tt>
+  for <tt>Arc</tt>s (directed edges).
+
+\warning
+<b>The <tt>lemon-0.x-to-1.x.sh</tt> script replaces the words \c graph,
+\c ugraph, \c edge and \c uedge in your own identifiers and in
+strings, comments etc. as well as in all LEMON specific identifiers.
+So use the script carefully and make a backup copy of your source files
+before applying the script to them.</b>
+
+\section migration-lgf LGF tools
+ - The \ref lgf-format "LGF file format" has changed,
+   <tt>\@nodeset</tt> has changed to <tt>\@nodes</tt>,
+   <tt>\@edgeset</tt> and <tt>\@uedgeset</tt> to <tt>\@arcs</tt> or
+   <tt>\@edges</tt>, which become completely equivalents. The
+   <tt>\@nodes</tt>, <tt>\@edges</tt> and <tt>\@uedges</tt> sections are
+   removed from the format, the content of them should be
+   the part of <tt>\@attributes</tt> section. The data fields in
+   the sections must follow a strict format, they must be either character
+   sequences without whitespaces or quoted strings.
+ - The <tt>LemonReader</tt> and <tt>LemonWriter</tt> core interfaces
+   are no longer available.
+ - The implementation of the general section readers and writers has changed
+   they are simple functors now. Beside the old
+   stream based section handling, currently line oriented section
+   reading and writing are also supported. In the
+   section readers the lines must be counted manually. The sections
+   should be read and written with the SectionWriter and SectionReader
+   classes.
+ - Instead of the item readers and writers, item converters should be
+   used. The converters are functors, which map the type to
+   std::string or std::string to the type. The converters for standard
+   containers hasn't yet been implemented in the new LEMON. The converters
+   can return strings in any format, because if it is necessary, the LGF
+   writer and reader will quote and unquote the given value.
+ - The DigraphReader and DigraphWriter can used similarly to the
+   0.x series, however the <tt>read</tt> or <tt>write</tt> prefix of
+   the member functions are removed.
+ - The new LEMON supports the function like interface, the \c
+   digraphReader and \c digraphWriter functions are more convenient than
+   using the classes directly.
+
+\section migration-search BFS, DFS and Dijkstra
+- <b>Using the function interface of BFS, DFS and %Dijkstra both source and
+  target nodes can be given as parameters of the <tt>run()</tt> function
+  (instead of \c bfs(), \c dfs() or \c dijkstra() itself).</b>
+- \ref named-templ-param "Named class template parameters" of \c Bfs,
+  \c Dfs, \c Dijkstra, \c BfsVisit, \c DfsVisit are renamed to start
+  with "Set" instead of "Def". Namely,
+  - \c DefPredMap -> \c SetPredMap
+  - \c DefDistMap -> \c SetDistMap
+  - \c DefReachedMap -> \c SetReachedMap
+  - \c DefProcessedMap -> \c SetProcessedMap
+  - \c DefHeap -> \c SetHeap
+  - \c DefStandardHeap -> \c SetStandardHeap
+  - \c DefOperationTraits -> \c SetOperationTraits
+  - \c DefProcessedMapToBeDefaultMap -> \c SetStandardProcessedMap
+
+\section migration-error Exceptions and Debug tools
+
+<b>The class hierarchy of exceptions has largely been simplified. Now,
+only the i/o related tools may throw exceptions. All other exceptions
+have been replaced with either the \c LEMON_ASSERT or the \c LEMON_DEBUG
+macros.</b>
+
+<b>On the other hand, the parameter order of constructors of the
+exceptions has been changed. See \ref IoError and \ref FormatError for
+more details.</b>
+
+\section migration-other Others
+- <b>The contents of <tt>graph_utils.h</tt> are moved to <tt>core.h</tt>
+  and <tt>maps.h</tt>. <tt>core.h</tt> is included by all graph types,
+  therefore it usually do not have to be included directly.</b>
+- <b><tt>path_utils.h</tt> is merged to \c path.h.</b>
+- <b>The semantic of the assignment operations and copy constructors of maps
+  are still under discussion. So, you must copy them by hand (i.e. copy
+  each entry one-by-one)</b>
+- <b>The parameters of the graph copying tools (i.e. \c GraphCopy,
+  \c DigraphCopy) have to be given in the from-to order.</b>
+- \c copyDigraph() and \c copyGraph() are renamed to \c digraphCopy()
+  and \c graphCopy(), respectively.
+- <b>The interface of \ref DynArcLookUp has changed. It is now the same as
+  of \ref ArcLookUp and \ref AllArcLookUp</b>
+- Some map types should also been renamed. Namely,
+  - \c IntegerMap -> \c RangeMap
+  - \c StdMap -> \c SparseMap
+  - \c FunctorMap -> \c FunctorToMap
+  - \c MapFunctor -> \c MapToFunctor
+  - \c ForkWriteMap -> \c ForkMap
+  - \c StoreBoolMap -> \c LoggerBoolMap
+- \c dim2::BoundingBox -> \c dim2::Box
+
+*/
+}
diff --git a/doc/min_cost_flow.dox b/doc/min_cost_flow.dox
new file mode 100644
index 0000000..09b449d
--- /dev/null
+++ b/doc/min_cost_flow.dox
@@ -0,0 +1,153 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+namespace lemon {
+
+/**
+\page min_cost_flow Minimum Cost Flow Problem
+
+\section mcf_def Definition (GEQ form)
+
+The \e minimum \e cost \e flow \e problem is to find a feasible flow of
+minimum total cost from a set of supply nodes to a set of demand nodes
+in a network with capacity constraints (lower and upper bounds)
+and arc costs \cite amo93networkflows.
+
+Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
+\f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
+upper bounds for the flow values on the arcs, for which
+\f$lower(uv) \leq upper(uv)\f$ must hold for all \f$uv\in A\f$,
+\f$cost: A\rightarrow\mathbf{R}\f$ denotes the cost per unit flow
+on the arcs and \f$sup: V\rightarrow\mathbf{R}\f$ denotes the
+signed supply values of the nodes.
+If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
+supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
+\f$-sup(u)\f$ demand.
+A minimum cost flow is an \f$f: A\rightarrow\mathbf{R}\f$ solution
+of the following optimization problem.
+
+\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
+\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
+    sup(u) \quad \forall u\in V \f]
+\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
+
+The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
+zero or negative in order to have a feasible solution (since the sum
+of the expressions on the left-hand side of the inequalities is zero).
+It means that the total demand must be greater or equal to the total
+supply and all the supplies have to be carried out from the supply nodes,
+but there could be demands that are not satisfied.
+If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
+constraints have to be satisfied with equality, i.e. all demands
+have to be satisfied and all supplies have to be used.
+
+
+\section mcf_algs Algorithms
+
+LEMON contains several algorithms for solving this problem, for more
+information see \ref min_cost_flow_algs "Minimum Cost Flow Algorithms".
+
+A feasible solution for this problem can be found using \ref Circulation.
+
+
+\section mcf_dual Dual Solution
+
+The dual solution of the minimum cost flow problem is represented by
+node potentials \f$\pi: V\rightarrow\mathbf{R}\f$.
+An \f$f: A\rightarrow\mathbf{R}\f$ primal feasible solution is optimal
+if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ node potentials
+the following \e complementary \e slackness optimality conditions hold.
+
+ - For all \f$uv\in A\f$ arcs:
+   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
+   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
+   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
+ - For all \f$u\in V\f$ nodes:
+   - \f$\pi(u)\leq 0\f$;
+   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
+     then \f$\pi(u)=0\f$.
+
+Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
+\f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
+\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
+
+All algorithms provide dual solution (node potentials), as well,
+if an optimal flow is found.
+
+
+\section mcf_eq Equality Form
+
+The above \ref mcf_def "definition" is actually more general than the
+usual formulation of the minimum cost flow problem, in which strict
+equalities are required in the supply/demand contraints.
+
+\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
+\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) =
+    sup(u) \quad \forall u\in V \f]
+\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
+
+However, if the sum of the supply values is zero, then these two problems
+are equivalent.
+The \ref min_cost_flow_algs "algorithms" in LEMON support the general
+form, so if you need the equality form, you have to ensure this additional
+contraint manually.
+
+
+\section mcf_leq Opposite Inequalites (LEQ Form)
+
+Another possible definition of the minimum cost flow problem is
+when there are <em>"less or equal"</em> (LEQ) supply/demand constraints,
+instead of the <em>"greater or equal"</em> (GEQ) constraints.
+
+\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
+\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq
+    sup(u) \quad \forall u\in V \f]
+\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
+
+It means that the total demand must be less or equal to the
+total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
+positive) and all the demands have to be satisfied, but there
+could be supplies that are not carried out from the supply
+nodes.
+The equality form is also a special case of this form, of course.
+
+You could easily transform this case to the \ref mcf_def "GEQ form"
+of the problem by reversing the direction of the arcs and taking the
+negative of the supply values (e.g. using \ref ReverseDigraph and
+\ref NegMap adaptors).
+However \ref NetworkSimplex algorithm also supports this form directly
+for the sake of convenience.
+
+Note that the optimality conditions for this supply constraint type are
+slightly differ from the conditions that are discussed for the GEQ form,
+namely the potentials have to be non-negative instead of non-positive.
+An \f$f: A\rightarrow\mathbf{R}\f$ feasible solution of this problem
+is optimal if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$
+node potentials the following conditions hold.
+
+ - For all \f$uv\in A\f$ arcs:
+   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
+   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
+   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
+ - For all \f$u\in V\f$ nodes:
+   - \f$\pi(u)\geq 0\f$;
+   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
+     then \f$\pi(u)=0\f$.
+
+*/
+}
diff --git a/doc/named-param.dox b/doc/named-param.dox
new file mode 100644
index 0000000..2a981f7
--- /dev/null
+++ b/doc/named-param.dox
@@ -0,0 +1,119 @@
+/* -*- 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.
+ *
+ */
+
+/*!
+
+\page named-param Named Parameters
+
+\section named-func-param Named Function Parameters
+
+Several modern languages provide a convenient way to refer the
+function parameters by name also when you call the function. It is
+especially comfortable in case of a function having tons of parameters
+with natural default values. Sadly, C++ lack this amenity.
+
+However, with a crafty trick and with some little
+inconvenience, it is possible to emulate is.
+The example below shows how to do it.
+
+\code
+class namedFn
+{
+  int _id;
+  double _val;
+  int _dim;
+
+  public:
+  namedFn() : _id(0), _val(1), _dim(2) {}
+  namedFn& id(int p)     { _id  = p ; return *this; }
+  namedFn& val(double p) { _val = p ; return *this; }
+  namedFn& dim(int p)    { _dim = p ; return *this; }
+
+  run() {
+    std::cout << "Here comes the function itself\n" <<
+              << "With parameters "
+              << _id << ", " << _val << ", " << _dim << std::endl;
+  }
+};
+\endcode
+
+Then you can use it like this.
+
+\code
+namedFn().id(3).val(2).run();
+\endcode
+
+The trick is obvious, each "named parameter" changes one component of
+the underlying class, then gives back a reference to it. Finally,
+<tt>run()</tt> executes the algorithm itself.
+
+\note Although it is a class, namedFn is used pretty much like as it were
+a function. That it why we called it namedFn instead of \c NamedFn.
+
+\note In fact, the final <tt>.run()</tt> could be made unnecessary,
+because the algorithm could also be implemented in the destructor of
+\c namedFn instead. This however would make it impossible to implement
+functions with return values, and would also cause serious problems when
+implementing \ref named-templ-func-param "named template parameters".
+<b>Therefore, by convention, <tt>.run()</tt> must be used
+explicitly to execute a function having named parameters
+everywhere in LEMON.</b>
+
+\section named-templ-func-param Named Function Template Parameters
+
+A named parameter can also be a template function. The usage is
+exactly the same, but the implementation behind is a kind of black
+magic and they are the dirtiest part of the LEMON code.
+
+You will probably never need to know how it works, but if you really
+committed, have a look at \ref lemon/graph_to_eps.h for an example.
+
+\section traits-classes Traits Classes
+
+A similar game can also be played when defining classes. In this case
+the type of the class attributes can be changed. Initially we have to
+define a special class called <em>Traits Class</em> defining the
+default type of the attributes. Then the types of these attributes can
+be changed in the same way as described in the next section.
+
+See \ref lemon::DijkstraDefaultTraits for an
+example how a traits class implementation looks like.
+
+\section named-templ-param Named Class Template Parameters
+
+If we would like to change the type of an attribute in a class that
+was instantiated by using a traits class as a template parameter, and
+the class contains named parameters, we do not have to instantiate again
+the class with new traits class, but instead adaptor classes can
+be used as shown in the following example.
+
+\code
+Dijkstra<>::SetPredMap<NullMap<Node,Arc> >::Create
+\endcode
+
+It can also be used in conjunction with other named template
+parameters in arbitrary order.
+
+\code
+Dijkstra<>::SetDistMap<MyMap>::SetPredMap<NullMap<Node,Arc> >::Create
+\endcode
+
+The result will be an instantiated Dijkstra class, in which the
+DistMap and the PredMap is modified.
+
+*/
diff --git a/doc/namespaces.dox b/doc/namespaces.dox
new file mode 100644
index 0000000..248ca20
--- /dev/null
+++ b/doc/namespaces.dox
@@ -0,0 +1,30 @@
+/* -*- 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.
+ *
+ */
+
+/// The namespace of LEMON
+
+/// The namespace of LEMON
+///
+namespace lemon {
+
+  /// The namespace of LEMON concepts and concept checking classes
+
+  /// The namespace of LEMON concepts and concept checking classes
+  ///
+  namespace concepts {}
+}
diff --git a/doc/references.bib b/doc/references.bib
new file mode 100644
index 0000000..7952d3e
--- /dev/null
+++ b/doc/references.bib
@@ -0,0 +1,356 @@
+%%%%% Defining LEMON %%%%%
+
+ at 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/}}
+}
+
+ at 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/}
+}
+
+ at misc{coinor,
+  key =          {COIN-OR},
+  title =        {{COIN-OR} -- {C}omputational {I}nfrastructure for
+                  {O}perations {R}esearch},
+  url =          {http://www.coin-or.org/}
+}
+
+
+%%%%% Papers related to LEMON %%%%%
+
+ at article{DezsoJuttnerKovacs11Lemon,
+  author =       {B. Dezs{\H o} and A. J\"uttner and P. Kov\'acs},
+  title =        {{LEMON} -- an open source {C++} graph template library},
+  journal =      {Electronic Notes in Theoretical Computer Science},
+  volume =       {264},
+  pages =        {23--45},
+  year =         {2011},
+  note =         {Proc. 2nd Workshop on Generative Technologies}
+}
+
+ at article{KiralyKovacs12MCF,
+  author =       {Z. Kir\'aly and P. Kov\'acs},
+  title =        {Efficient implementations of minimum-cost flow algorithms},
+  journal =      {Acta Universitatis Sapientiae, Informatica},
+  year =         {2012},
+  volume =       {4},
+  pages =        {67--118}
+}
+
+
+%%%%% Other libraries %%%%%%
+
+ at misc{boost,
+  key =          {Boost},
+  title =        {{B}oost {C++} {L}ibraries},
+  url =          {http://www.boost.org/}
+}
+
+ at 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
+}
+
+ at misc{leda,
+  key =          {LEDA},
+  title =        {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
+                  {A}lgorithms},
+  url =          {http://www.algorithmic-solutions.com/}
+}
+
+ at 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 %%%%%
+
+ at misc{cmake,
+  key =          {CMake},
+  title =        {{CMake} -- {C}ross {P}latform {M}ake},
+  url =          {http://www.cmake.org/}
+}
+
+ at misc{doxygen,
+  key =          {Doxygen},
+  title =        {{Doxygen} -- {S}ource code documentation generator
+                  tool},
+  url =          {http://www.doxygen.org/}
+}
+
+
+%%%%% LP/MIP libraries %%%%%
+
+ at misc{glpk,
+  key =          {GLPK},
+  title =        {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
+  url =          {http://www.gnu.org/software/glpk/}
+}
+
+ at misc{clp,
+  key =          {Clp},
+  title =        {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
+  url =          {http://projects.coin-or.org/Clp/}
+}
+
+ at misc{cbc,
+  key =          {Cbc},
+  title =        {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
+  url =          {http://projects.coin-or.org/Cbc/}
+}
+
+ at misc{cplex,
+  key =          {CPLEX},
+  title =        {{ILOG} {CPLEX}},
+  url =          {http://www.ilog.com/}
+}
+
+ at misc{soplex,
+  key =          {SoPlex},
+  title =        {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
+                  {S}implex},
+  url =          {http://soplex.zib.de/}
+}
+
+
+%%%%% General books %%%%%
+
+ at 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}
+}
+
+ at book{schrijver03combinatorial,
+  author =       {Alexander Schrijver},
+  title =        {Combinatorial Optimization: Polyhedra and Efficiency},
+  publisher =    {Springer-Verlag},
+  year =         2003,
+  isbn =         {978-3540443896}
+}
+
+ at 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}
+}
+
+ at 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 %%%%%
+
+ at 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}
+}
+
+ at 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}
+}
+
+ at 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}
+}
+
+ at 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}
+}
+
+ at 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 %%%%%
+
+ at 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}
+}
+
+ at article{hartmann93finding,
+  author =       {Mark Hartmann and James B. Orlin},
+  title =        {Finding minimum cost to time ratio cycles with small
+                  integral transit times},
+  journal =      {Networks},
+  year =         1993,
+  volume =       23,
+  pages =        {567-574}
+}
+
+ at 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}
+}
+
+ at article{dasdan04experimental,
+  author =       {Ali Dasdan},
+  title =        {Experimental analysis of the fastest optimum cycle
+                  ratio and mean algorithms},
+  journal =      {ACM Trans. Des. Autom. Electron. Syst.},
+  year =         2004,
+  volume =       9,
+  issue =        4,
+  pages =        {385-418}
+} 
+
+
+%%%%% Minimum cost flow algorithms %%%%%
+
+ at 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}
+}
+
+ at 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}
+}
+
+ at 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}
+}
+
+ at 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}
+}
+
+ at 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}
+}
+
+ at book{dantzig63linearprog,
+  author =       {George B. Dantzig},
+  title =        {Linear Programming and Extensions},
+  publisher =    {Princeton University Press},
+  year =         1963
+}
+
+ at 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
+}
+
+%%%%% Other algorithms %%%%%
+
+ at article{grosso08maxclique,
+  author =       {Andrea Grosso and Marco Locatelli and Wayne Pullan},
+  title =        {Simple ingredients leading to very efficient
+                  heuristics for the maximum clique problem},
+  journal =      {Journal of Heuristics},
+  year =         2008,
+  volume =       14,
+  number =       6,
+  pages =        {587--612}
+}
diff --git a/doc/template.h b/doc/template.h
new file mode 100644
index 0000000..7f361ab
--- /dev/null
+++ b/doc/template.h
@@ -0,0 +1,22 @@
+/* -*- 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_TEMPLATE_H
+#define LEMON_TEMPLATE_H
+
+#endif // LEMON_TEMPLATE_H
diff --git a/lemon/CMakeLists.txt b/lemon/CMakeLists.txt
new file mode 100644
index 0000000..4e6567e
--- /dev/null
+++ b/lemon/CMakeLists.txt
@@ -0,0 +1,91 @@
+INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}
+  ${PROJECT_BINARY_DIR}
+)
+
+CONFIGURE_FILE(
+  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
+  ${CMAKE_CURRENT_BINARY_DIR}/config.h
+)
+
+CONFIGURE_FILE(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc
+  @ONLY
+)
+
+SET(LEMON_SOURCES
+  arg_parser.cc
+  base.cc
+  color.cc
+  lp_base.cc
+  lp_skeleton.cc
+  random.cc
+  bits/windows.cc
+)
+
+IF(LEMON_HAVE_GLPK)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
+  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
+  IF(WIN32)
+    INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
+    INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
+    INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
+  ENDIF()
+ENDIF()
+
+IF(LEMON_HAVE_CPLEX)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
+  INCLUDE_DIRECTORIES(${ILOG_INCLUDE_DIRS})
+ENDIF()
+
+IF(LEMON_HAVE_CLP)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
+  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
+ENDIF()
+
+IF(LEMON_HAVE_CBC)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
+  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
+ENDIF()
+
+IF(LEMON_HAVE_SOPLEX)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} soplex.cc)
+  INCLUDE_DIRECTORIES(${SOPLEX_INCLUDE_DIRS})
+ENDIF()
+
+ADD_LIBRARY(lemon ${LEMON_SOURCES})
+
+TARGET_LINK_LIBRARIES(lemon
+  ${GLPK_LIBRARIES} ${COIN_LIBRARIES} ${ILOG_LIBRARIES} ${SOPLEX_LIBRARIES}
+  )
+
+IF(UNIX)
+  SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon VERSION ${LEMON_VERSION} SOVERSION ${LEMON_VERSION})
+ENDIF()
+
+INSTALL(
+  TARGETS lemon
+  ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
+  COMPONENT library
+)
+
+INSTALL(
+  DIRECTORY . bits concepts
+  DESTINATION include/lemon
+  COMPONENT headers
+  FILES_MATCHING PATTERN "*.h"
+)
+
+INSTALL(
+  FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
+  DESTINATION include/lemon
+  COMPONENT headers
+)
+
+INSTALL(
+  FILES ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc
+  DESTINATION lib/pkgconfig
+)
+
diff --git a/lemon/adaptors.h b/lemon/adaptors.h
new file mode 100644
index 0000000..1a40f8e
--- /dev/null
+++ b/lemon/adaptors.h
@@ -0,0 +1,3638 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_ADAPTORS_H
+#define LEMON_ADAPTORS_H
+
+/// \ingroup graph_adaptors
+/// \file
+/// \brief Adaptor classes for digraphs and graphs
+///
+/// This file contains several useful adaptors for digraphs and graphs.
+
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/bits/variant.h>
+
+#include <lemon/bits/graph_adaptor_extender.h>
+#include <lemon/bits/map_extender.h>
+#include <lemon/tolerance.h>
+
+#include <algorithm>
+
+namespace lemon {
+
+#ifdef _MSC_VER
+#define LEMON_SCOPE_FIX(OUTER, NESTED) OUTER::NESTED
+#else
+#define LEMON_SCOPE_FIX(OUTER, NESTED) typename OUTER::template NESTED
+#endif
+
+  template<typename DGR>
+  class DigraphAdaptorBase {
+  public:
+    typedef DGR Digraph;
+    typedef DigraphAdaptorBase Adaptor;
+
+  protected:
+    DGR* _digraph;
+    DigraphAdaptorBase() : _digraph(0) { }
+    void initialize(DGR& digraph) { _digraph = &digraph; }
+
+  public:
+    DigraphAdaptorBase(DGR& digraph) : _digraph(&digraph) { }
+
+    typedef typename DGR::Node Node;
+    typedef typename DGR::Arc Arc;
+
+    void first(Node& i) const { _digraph->first(i); }
+    void first(Arc& i) const { _digraph->first(i); }
+    void firstIn(Arc& i, const Node& n) const { _digraph->firstIn(i, n); }
+    void firstOut(Arc& i, const Node& n ) const { _digraph->firstOut(i, n); }
+
+    void next(Node& i) const { _digraph->next(i); }
+    void next(Arc& i) const { _digraph->next(i); }
+    void nextIn(Arc& i) const { _digraph->nextIn(i); }
+    void nextOut(Arc& i) const { _digraph->nextOut(i); }
+
+    Node source(const Arc& a) const { return _digraph->source(a); }
+    Node target(const Arc& a) const { return _digraph->target(a); }
+
+    typedef NodeNumTagIndicator<DGR> NodeNumTag;
+    int nodeNum() const { return _digraph->nodeNum(); }
+
+    typedef ArcNumTagIndicator<DGR> ArcNumTag;
+    int arcNum() const { return _digraph->arcNum(); }
+
+    typedef FindArcTagIndicator<DGR> FindArcTag;
+    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const {
+      return _digraph->findArc(u, v, prev);
+    }
+
+    Node addNode() { return _digraph->addNode(); }
+    Arc addArc(const Node& u, const Node& v) { return _digraph->addArc(u, v); }
+
+    void erase(const Node& n) { _digraph->erase(n); }
+    void erase(const Arc& a) { _digraph->erase(a); }
+
+    void clear() { _digraph->clear(); }
+
+    int id(const Node& n) const { return _digraph->id(n); }
+    int id(const Arc& a) const { return _digraph->id(a); }
+
+    Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
+    Arc arcFromId(int ix) const { return _digraph->arcFromId(ix); }
+
+    int maxNodeId() const { return _digraph->maxNodeId(); }
+    int maxArcId() const { return _digraph->maxArcId(); }
+
+    typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
+    NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
+
+    typedef typename ItemSetTraits<DGR, Arc>::ItemNotifier ArcNotifier;
+    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Arc()); }
+
+    template <typename V>
+    class NodeMap : public DGR::template NodeMap<V> {
+      typedef typename DGR::template NodeMap<V> Parent;
+
+    public:
+      explicit NodeMap(const Adaptor& adaptor)
+        : Parent(*adaptor._digraph) {}
+      NodeMap(const Adaptor& adaptor, const V& value)
+        : Parent(*adaptor._digraph, value) { }
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename V>
+    class ArcMap : public DGR::template ArcMap<V> {
+      typedef typename DGR::template ArcMap<V> Parent;
+
+    public:
+      explicit ArcMap(const DigraphAdaptorBase<DGR>& adaptor)
+        : Parent(*adaptor._digraph) {}
+      ArcMap(const DigraphAdaptorBase<DGR>& adaptor, const V& value)
+        : Parent(*adaptor._digraph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+  };
+
+  template<typename GR>
+  class GraphAdaptorBase {
+  public:
+    typedef GR Graph;
+
+  protected:
+    GR* _graph;
+
+    GraphAdaptorBase() : _graph(0) {}
+
+    void initialize(GR& graph) { _graph = &graph; }
+
+  public:
+    GraphAdaptorBase(GR& graph) : _graph(&graph) {}
+
+    typedef typename GR::Node Node;
+    typedef typename GR::Arc Arc;
+    typedef typename GR::Edge Edge;
+
+    void first(Node& i) const { _graph->first(i); }
+    void first(Arc& i) const { _graph->first(i); }
+    void first(Edge& i) const { _graph->first(i); }
+    void firstIn(Arc& i, const Node& n) const { _graph->firstIn(i, n); }
+    void firstOut(Arc& i, const Node& n ) const { _graph->firstOut(i, n); }
+    void firstInc(Edge &i, bool &d, const Node &n) const {
+      _graph->firstInc(i, d, n);
+    }
+
+    void next(Node& i) const { _graph->next(i); }
+    void next(Arc& i) const { _graph->next(i); }
+    void next(Edge& i) const { _graph->next(i); }
+    void nextIn(Arc& i) const { _graph->nextIn(i); }
+    void nextOut(Arc& i) const { _graph->nextOut(i); }
+    void nextInc(Edge &i, bool &d) const { _graph->nextInc(i, d); }
+
+    Node u(const Edge& e) const { return _graph->u(e); }
+    Node v(const Edge& e) const { return _graph->v(e); }
+
+    Node source(const Arc& a) const { return _graph->source(a); }
+    Node target(const Arc& a) const { return _graph->target(a); }
+
+    typedef NodeNumTagIndicator<Graph> NodeNumTag;
+    int nodeNum() const { return _graph->nodeNum(); }
+
+    typedef ArcNumTagIndicator<Graph> ArcNumTag;
+    int arcNum() const { return _graph->arcNum(); }
+
+    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
+    int edgeNum() const { return _graph->edgeNum(); }
+
+    typedef FindArcTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      return _graph->findArc(u, v, prev);
+    }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
+      return _graph->findEdge(u, v, prev);
+    }
+
+    Node addNode() { return _graph->addNode(); }
+    Edge addEdge(const Node& u, const Node& v) { return _graph->addEdge(u, v); }
+
+    void erase(const Node& i) { _graph->erase(i); }
+    void erase(const Edge& i) { _graph->erase(i); }
+
+    void clear() { _graph->clear(); }
+
+    bool direction(const Arc& a) const { return _graph->direction(a); }
+    Arc direct(const Edge& e, bool d) const { return _graph->direct(e, d); }
+
+    int id(const Node& v) const { return _graph->id(v); }
+    int id(const Arc& a) const { return _graph->id(a); }
+    int id(const Edge& e) const { return _graph->id(e); }
+
+    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
+    Arc arcFromId(int ix) const { return _graph->arcFromId(ix); }
+    Edge edgeFromId(int ix) const { return _graph->edgeFromId(ix); }
+
+    int maxNodeId() const { return _graph->maxNodeId(); }
+    int maxArcId() const { return _graph->maxArcId(); }
+    int maxEdgeId() const { return _graph->maxEdgeId(); }
+
+    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
+    NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
+
+    typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
+    ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
+
+    typedef typename ItemSetTraits<GR, Edge>::ItemNotifier EdgeNotifier;
+    EdgeNotifier& notifier(Edge) const { return _graph->notifier(Edge()); }
+
+    template <typename V>
+    class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
+    public:
+      explicit NodeMap(const GraphAdaptorBase<GR>& adapter)
+        : Parent(*adapter._graph) {}
+      NodeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
+        : Parent(*adapter._graph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename V>
+    class ArcMap : public GR::template ArcMap<V> {
+      typedef typename GR::template ArcMap<V> Parent;
+
+    public:
+      explicit ArcMap(const GraphAdaptorBase<GR>& adapter)
+        : Parent(*adapter._graph) {}
+      ArcMap(const GraphAdaptorBase<GR>& adapter, const V& value)
+        : Parent(*adapter._graph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class EdgeMap : public GR::template EdgeMap<V> {
+      typedef typename GR::template EdgeMap<V> Parent;
+
+    public:
+      explicit EdgeMap(const GraphAdaptorBase<GR>& adapter)
+        : Parent(*adapter._graph) {}
+      EdgeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
+        : Parent(*adapter._graph, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  template <typename DGR>
+  class ReverseDigraphBase : public DigraphAdaptorBase<DGR> {
+    typedef DigraphAdaptorBase<DGR> Parent;
+  public:
+    typedef DGR Digraph;
+  protected:
+    ReverseDigraphBase() : Parent() { }
+  public:
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    void firstIn(Arc& a, const Node& n) const { Parent::firstOut(a, n); }
+    void firstOut(Arc& a, const Node& n ) const { Parent::firstIn(a, n); }
+
+    void nextIn(Arc& a) const { Parent::nextOut(a); }
+    void nextOut(Arc& a) const { Parent::nextIn(a); }
+
+    Node source(const Arc& a) const { return Parent::target(a); }
+    Node target(const Arc& a) const { return Parent::source(a); }
+
+    Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); }
+
+    typedef FindArcTagIndicator<DGR> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      return Parent::findArc(v, u, prev);
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for reversing the orientation of the arcs in
+  /// a digraph.
+  ///
+  /// ReverseDigraph can be used for reversing the arcs in a digraph.
+  /// It conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// 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.
+  /// It can also be specified to be \c const.
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
+  template<typename DGR>
+#ifdef DOXYGEN
+  class ReverseDigraph {
+#else
+  class ReverseDigraph :
+    public DigraphAdaptorExtender<ReverseDigraphBase<DGR> > {
+#endif
+    typedef DigraphAdaptorExtender<ReverseDigraphBase<DGR> > Parent;
+  public:
+    /// The type of the adapted digraph.
+    typedef DGR Digraph;
+  protected:
+    ReverseDigraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a reverse digraph adaptor for the given digraph.
+    explicit ReverseDigraph(DGR& digraph) {
+      Parent::initialize(digraph);
+    }
+  };
+
+  /// \brief Returns a read-only ReverseDigraph adaptor
+  ///
+  /// This function just returns a read-only \ref ReverseDigraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates ReverseDigraph
+  template<typename DGR>
+  ReverseDigraph<const DGR> reverseDigraph(const DGR& digraph) {
+    return ReverseDigraph<const DGR>(digraph);
+  }
+
+
+  template <typename DGR, typename NF, typename AF, bool ch = true>
+  class SubDigraphBase : public DigraphAdaptorBase<DGR> {
+    typedef DigraphAdaptorBase<DGR> Parent;
+  public:
+    typedef DGR Digraph;
+    typedef NF NodeFilterMap;
+    typedef AF ArcFilterMap;
+
+    typedef SubDigraphBase Adaptor;
+  protected:
+    NF* _node_filter;
+    AF* _arc_filter;
+    SubDigraphBase()
+      : Parent(), _node_filter(0), _arc_filter(0) { }
+
+    void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
+      Parent::initialize(digraph);
+      _node_filter = &node_filter;
+      _arc_filter = &arc_filter;
+    }
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    void first(Node& i) const {
+      Parent::first(i);
+      while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void first(Arc& i) const {
+      Parent::first(i);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::source(i)]
+                              || !(*_node_filter)[Parent::target(i)]))
+        Parent::next(i);
+    }
+
+    void firstIn(Arc& i, const Node& n) const {
+      Parent::firstIn(i, n);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::source(i)]))
+        Parent::nextIn(i);
+    }
+
+    void firstOut(Arc& i, const Node& n) const {
+      Parent::firstOut(i, n);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::target(i)]))
+        Parent::nextOut(i);
+    }
+
+    void next(Node& i) const {
+      Parent::next(i);
+      while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void next(Arc& i) const {
+      Parent::next(i);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::source(i)]
+                              || !(*_node_filter)[Parent::target(i)]))
+        Parent::next(i);
+    }
+
+    void nextIn(Arc& i) const {
+      Parent::nextIn(i);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::source(i)]))
+        Parent::nextIn(i);
+    }
+
+    void nextOut(Arc& i) const {
+      Parent::nextOut(i);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::target(i)]))
+        Parent::nextOut(i);
+    }
+
+    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
+    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
+
+    bool status(const Node& n) const { return (*_node_filter)[n]; }
+    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
+
+    typedef False NodeNumTag;
+    typedef False ArcNumTag;
+
+    typedef FindArcTagIndicator<DGR> FindArcTag;
+    Arc findArc(const Node& source, const Node& target,
+                const Arc& prev = INVALID) const {
+      if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
+        return INVALID;
+      }
+      Arc arc = Parent::findArc(source, target, prev);
+      while (arc != INVALID && !(*_arc_filter)[arc]) {
+        arc = Parent::findArc(source, target, arc);
+      }
+      return arc;
+    }
+
+  public:
+
+    template <typename V>
+    class NodeMap
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+              LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
+        : Parent(adaptor) {}
+      NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class ArcMap
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+              LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
+        : Parent(adaptor) {}
+      ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  template <typename DGR, typename NF, typename AF>
+  class SubDigraphBase<DGR, NF, AF, false>
+    : public DigraphAdaptorBase<DGR> {
+    typedef DigraphAdaptorBase<DGR> Parent;
+  public:
+    typedef DGR Digraph;
+    typedef NF NodeFilterMap;
+    typedef AF ArcFilterMap;
+
+    typedef SubDigraphBase Adaptor;
+  protected:
+    NF* _node_filter;
+    AF* _arc_filter;
+    SubDigraphBase()
+      : Parent(), _node_filter(0), _arc_filter(0) { }
+
+    void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
+      Parent::initialize(digraph);
+      _node_filter = &node_filter;
+      _arc_filter = &arc_filter;
+    }
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    void first(Node& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void first(Arc& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
+    }
+
+    void firstIn(Arc& i, const Node& n) const {
+      Parent::firstIn(i, n);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
+    }
+
+    void firstOut(Arc& i, const Node& n) const {
+      Parent::firstOut(i, n);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
+    }
+
+    void next(Node& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+    void next(Arc& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
+    }
+    void nextIn(Arc& i) const {
+      Parent::nextIn(i);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
+    }
+
+    void nextOut(Arc& i) const {
+      Parent::nextOut(i);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
+    }
+
+    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
+    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
+
+    bool status(const Node& n) const { return (*_node_filter)[n]; }
+    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
+
+    typedef False NodeNumTag;
+    typedef False ArcNumTag;
+
+    typedef FindArcTagIndicator<DGR> FindArcTag;
+    Arc findArc(const Node& source, const Node& target,
+                const Arc& prev = INVALID) const {
+      if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
+        return INVALID;
+      }
+      Arc arc = Parent::findArc(source, target, prev);
+      while (arc != INVALID && !(*_arc_filter)[arc]) {
+        arc = Parent::findArc(source, target, arc);
+      }
+      return arc;
+    }
+
+    template <typename V>
+    class NodeMap
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
+        : Parent(adaptor) {}
+      NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class ArcMap
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
+        : Parent(adaptor) {}
+      ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for hiding nodes and arcs in a digraph
+  ///
+  /// SubDigraph can be used for hiding nodes and arcs in a digraph.
+  /// A \c bool node map and a \c bool arc map must be specified, which
+  /// define the filters for nodes and arcs.
+  /// Only the nodes and arcs with \c true filter value are
+  /// shown in the subdigraph. The arcs that are incident to hidden
+  /// nodes are also filtered out.
+  /// This adaptor conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// 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.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::NodeMap "DGR::NodeMap<bool>".
+  /// \tparam AF The type of the arc filter map.
+  /// It must be \c bool (or convertible) arc map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
+  ///
+  /// \see FilterNodes
+  /// \see FilterArcs
+#ifdef DOXYGEN
+  template<typename DGR, typename NF, typename AF>
+  class SubDigraph {
+#else
+  template<typename DGR,
+           typename NF = typename DGR::template NodeMap<bool>,
+           typename AF = typename DGR::template ArcMap<bool> >
+  class SubDigraph :
+    public DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef DGR Digraph;
+    /// The type of the node filter map.
+    typedef NF NodeFilterMap;
+    /// The type of the arc filter map.
+    typedef AF ArcFilterMap;
+
+    typedef DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> >
+      Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+  protected:
+    SubDigraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subdigraph for the given digraph with the
+    /// given node and arc filter maps.
+    SubDigraph(DGR& digraph, NF& node_filter, AF& arc_filter) {
+      Parent::initialize(digraph, node_filter, arc_filter);
+    }
+
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Sets the status of the given arc
+    ///
+    /// This function sets the status of the given arc.
+    /// It is done by simply setting the assigned value of \c a
+    /// to \c v in the arc filter map.
+    void status(const Arc& a, bool v) const { Parent::status(a, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Returns the status of the given arc
+    ///
+    /// This function returns the status of the given arc.
+    /// It is \c true if the given arc is enabled (i.e. not hidden).
+    bool status(const Arc& a) const { return Parent::status(a); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Disables the given arc
+    ///
+    /// This function disables the given arc in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(a, false)".
+    void disable(const Arc& a) const { Parent::status(a, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node in the subdigraph.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+    /// \brief Enables the given arc
+    ///
+    /// This function enables the given arc in the subdigraph.
+    /// It is the same as \ref status() "status(a, true)".
+    void enable(const Arc& a) const { Parent::status(a, true); }
+
+  };
+
+  /// \brief Returns a read-only SubDigraph adaptor
+  ///
+  /// This function just returns a read-only \ref SubDigraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SubDigraph
+  template<typename DGR, typename NF, typename AF>
+  SubDigraph<const DGR, NF, AF>
+  subDigraph(const DGR& digraph,
+             NF& node_filter, AF& arc_filter) {
+    return SubDigraph<const DGR, NF, AF>
+      (digraph, node_filter, arc_filter);
+  }
+
+  template<typename DGR, typename NF, typename AF>
+  SubDigraph<const DGR, const NF, AF>
+  subDigraph(const DGR& digraph,
+             const NF& node_filter, AF& arc_filter) {
+    return SubDigraph<const DGR, const NF, AF>
+      (digraph, node_filter, arc_filter);
+  }
+
+  template<typename DGR, typename NF, typename AF>
+  SubDigraph<const DGR, NF, const AF>
+  subDigraph(const DGR& digraph,
+             NF& node_filter, const AF& arc_filter) {
+    return SubDigraph<const DGR, NF, const AF>
+      (digraph, node_filter, arc_filter);
+  }
+
+  template<typename DGR, typename NF, typename AF>
+  SubDigraph<const DGR, const NF, const AF>
+  subDigraph(const DGR& digraph,
+             const NF& node_filter, const AF& arc_filter) {
+    return SubDigraph<const DGR, const NF, const AF>
+      (digraph, node_filter, arc_filter);
+  }
+
+
+  template <typename GR, typename NF, typename EF, bool ch = true>
+  class SubGraphBase : public GraphAdaptorBase<GR> {
+    typedef GraphAdaptorBase<GR> Parent;
+  public:
+    typedef GR Graph;
+    typedef NF NodeFilterMap;
+    typedef EF EdgeFilterMap;
+
+    typedef SubGraphBase Adaptor;
+  protected:
+
+    NF* _node_filter;
+    EF* _edge_filter;
+
+    SubGraphBase()
+      : Parent(), _node_filter(0), _edge_filter(0) { }
+
+    void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
+      Parent::initialize(graph);
+      _node_filter = &node_filter;
+      _edge_filter = &edge_filter;
+    }
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    void first(Node& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void first(Arc& i) const {
+      Parent::first(i);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::source(i)]
+                            || !(*_node_filter)[Parent::target(i)]))
+        Parent::next(i);
+    }
+
+    void first(Edge& i) const {
+      Parent::first(i);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::u(i)]
+                            || !(*_node_filter)[Parent::v(i)]))
+        Parent::next(i);
+    }
+
+    void firstIn(Arc& i, const Node& n) const {
+      Parent::firstIn(i, n);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::source(i)]))
+        Parent::nextIn(i);
+    }
+
+    void firstOut(Arc& i, const Node& n) const {
+      Parent::firstOut(i, n);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::target(i)]))
+        Parent::nextOut(i);
+    }
+
+    void firstInc(Edge& i, bool& d, const Node& n) const {
+      Parent::firstInc(i, d, n);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::u(i)]
+                            || !(*_node_filter)[Parent::v(i)]))
+        Parent::nextInc(i, d);
+    }
+
+    void next(Node& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void next(Arc& i) const {
+      Parent::next(i);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::source(i)]
+                            || !(*_node_filter)[Parent::target(i)]))
+        Parent::next(i);
+    }
+
+    void next(Edge& i) const {
+      Parent::next(i);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::u(i)]
+                            || !(*_node_filter)[Parent::v(i)]))
+        Parent::next(i);
+    }
+
+    void nextIn(Arc& i) const {
+      Parent::nextIn(i);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::source(i)]))
+        Parent::nextIn(i);
+    }
+
+    void nextOut(Arc& i) const {
+      Parent::nextOut(i);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::target(i)]))
+        Parent::nextOut(i);
+    }
+
+    void nextInc(Edge& i, bool& d) const {
+      Parent::nextInc(i, d);
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::u(i)]
+                            || !(*_node_filter)[Parent::v(i)]))
+        Parent::nextInc(i, d);
+    }
+
+    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
+    void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
+
+    bool status(const Node& n) const { return (*_node_filter)[n]; }
+    bool status(const Edge& e) const { return (*_edge_filter)[e]; }
+
+    typedef False NodeNumTag;
+    typedef False ArcNumTag;
+    typedef False EdgeNumTag;
+
+    typedef FindArcTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
+        return INVALID;
+      }
+      Arc arc = Parent::findArc(u, v, prev);
+      while (arc != INVALID && !(*_edge_filter)[arc]) {
+        arc = Parent::findArc(u, v, arc);
+      }
+      return arc;
+    }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
+      if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
+        return INVALID;
+      }
+      Edge edge = Parent::findEdge(u, v, prev);
+      while (edge != INVALID && !(*_edge_filter)[edge]) {
+        edge = Parent::findEdge(u, v, edge);
+      }
+      return edge;
+    }
+
+    template <typename V>
+    class NodeMap
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
+        : Parent(adaptor) {}
+      NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class ArcMap
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
+        : Parent(adaptor) {}
+      ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class EdgeMap
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
+        : Parent(adaptor) {}
+
+      EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  template <typename GR, typename NF, typename EF>
+  class SubGraphBase<GR, NF, EF, false>
+    : public GraphAdaptorBase<GR> {
+    typedef GraphAdaptorBase<GR> Parent;
+  public:
+    typedef GR Graph;
+    typedef NF NodeFilterMap;
+    typedef EF EdgeFilterMap;
+
+    typedef SubGraphBase Adaptor;
+  protected:
+    NF* _node_filter;
+    EF* _edge_filter;
+    SubGraphBase()
+          : Parent(), _node_filter(0), _edge_filter(0) { }
+
+    void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
+      Parent::initialize(graph);
+      _node_filter = &node_filter;
+      _edge_filter = &edge_filter;
+    }
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    void first(Node& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void first(Arc& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
+    }
+
+    void first(Edge& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
+    }
+
+    void firstIn(Arc& i, const Node& n) const {
+      Parent::firstIn(i, n);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
+    }
+
+    void firstOut(Arc& i, const Node& n) const {
+      Parent::firstOut(i, n);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
+    }
+
+    void firstInc(Edge& i, bool& d, const Node& n) const {
+      Parent::firstInc(i, d, n);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
+    }
+
+    void next(Node& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+    void next(Arc& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
+    }
+    void next(Edge& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
+    }
+    void nextIn(Arc& i) const {
+      Parent::nextIn(i);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
+    }
+
+    void nextOut(Arc& i) const {
+      Parent::nextOut(i);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
+    }
+    void nextInc(Edge& i, bool& d) const {
+      Parent::nextInc(i, d);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
+    }
+
+    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
+    void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
+
+    bool status(const Node& n) const { return (*_node_filter)[n]; }
+    bool status(const Edge& e) const { return (*_edge_filter)[e]; }
+
+    typedef False NodeNumTag;
+    typedef False ArcNumTag;
+    typedef False EdgeNumTag;
+
+    typedef FindArcTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      Arc arc = Parent::findArc(u, v, prev);
+      while (arc != INVALID && !(*_edge_filter)[arc]) {
+        arc = Parent::findArc(u, v, arc);
+      }
+      return arc;
+    }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
+      Edge edge = Parent::findEdge(u, v, prev);
+      while (edge != INVALID && !(*_edge_filter)[edge]) {
+        edge = Parent::findEdge(u, v, edge);
+      }
+      return edge;
+    }
+
+    template <typename V>
+    class NodeMap
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
+        : Parent(adaptor) {}
+      NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class ArcMap
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
+        : Parent(adaptor) {}
+      ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class EdgeMap
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
+
+    public:
+      typedef V Value;
+
+      EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
+        : Parent(adaptor) {}
+
+      EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for hiding nodes and edges in an undirected
+  /// graph.
+  ///
+  /// SubGraph can be used for hiding nodes and edges in a graph.
+  /// A \c bool node map and a \c bool edge map must be specified, which
+  /// define the filters for nodes and edges.
+  /// Only the nodes and edges with \c true filter value are
+  /// shown in the subgraph. The edges that are incident to hidden
+  /// nodes are also filtered out.
+  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// 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.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
+  /// \tparam EF The type of the edge filter map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
+  /// adapted graph are convertible to each other.
+  ///
+  /// \see FilterNodes
+  /// \see FilterEdges
+#ifdef DOXYGEN
+  template<typename GR, typename NF, typename EF>
+  class SubGraph {
+#else
+  template<typename GR,
+           typename NF = typename GR::template NodeMap<bool>,
+           typename EF = typename GR::template EdgeMap<bool> >
+  class SubGraph :
+    public GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> > {
+#endif
+  public:
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the node filter map.
+    typedef NF NodeFilterMap;
+    /// The type of the edge filter map.
+    typedef EF EdgeFilterMap;
+
+    typedef GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> >
+      Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Edge Edge;
+
+  protected:
+    SubGraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subgraph for the given graph with the given node
+    /// and edge filter maps.
+    SubGraph(GR& graph, NF& node_filter, EF& edge_filter) {
+      this->initialize(graph, node_filter, edge_filter);
+    }
+
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Sets the status of the given edge
+    ///
+    /// This function sets the status of the given edge.
+    /// It is done by simply setting the assigned value of \c e
+    /// to \c v in the edge filter map.
+    void status(const Edge& e, bool v) const { Parent::status(e, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Returns the status of the given edge
+    ///
+    /// This function returns the status of the given edge.
+    /// It is \c true if the given edge is enabled (i.e. not hidden).
+    bool status(const Edge& e) const { return Parent::status(e); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Disables the given edge
+    ///
+    /// This function disables the given edge in the subgraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(e, false)".
+    void disable(const Edge& e) const { Parent::status(e, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node in the subdigraph.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+    /// \brief Enables the given edge
+    ///
+    /// This function enables the given edge in the subgraph.
+    /// It is the same as \ref status() "status(e, true)".
+    void enable(const Edge& e) const { Parent::status(e, true); }
+
+  };
+
+  /// \brief Returns a read-only SubGraph adaptor
+  ///
+  /// This function just returns a read-only \ref SubGraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SubGraph
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, NF, EF>
+  subGraph(const GR& graph, NF& node_filter, EF& edge_filter) {
+    return SubGraph<const GR, NF, EF>
+      (graph, node_filter, edge_filter);
+  }
+
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, const NF, EF>
+  subGraph(const GR& graph, const NF& node_filter, EF& edge_filter) {
+    return SubGraph<const GR, const NF, EF>
+      (graph, node_filter, edge_filter);
+  }
+
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, NF, const EF>
+  subGraph(const GR& graph, NF& node_filter, const EF& edge_filter) {
+    return SubGraph<const GR, NF, const EF>
+      (graph, node_filter, edge_filter);
+  }
+
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, const NF, const EF>
+  subGraph(const GR& graph, const NF& node_filter, const EF& edge_filter) {
+    return SubGraph<const GR, const NF, const EF>
+      (graph, node_filter, edge_filter);
+  }
+
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for hiding nodes in a digraph or a graph.
+  ///
+  /// FilterNodes adaptor can be used for hiding nodes in a digraph or a
+  /// graph. A \c bool node map must be specified, which defines the filter
+  /// for the nodes. Only the nodes with \c true filter value and the
+  /// arcs/edges incident to nodes both with \c true filter value are shown
+  /// in the subgraph. This adaptor conforms to the \ref concepts::Digraph
+  /// "Digraph" concept or the \ref concepts::Graph "Graph" concept
+  /// depending on the \c GR template parameter.
+  ///
+  /// The adapted (di)graph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs/edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// This class provides only linear time item counting.
+  ///
+  /// \tparam GR The type of the adapted digraph or graph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept
+  /// or the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted (di)graph. The default type is
+  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
+  ///
+  /// \note The \c Node and <tt>Arc/Edge</tt> types of this adaptor and the
+  /// adapted (di)graph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename GR, typename NF>
+  class FilterNodes {
+#else
+  template<typename GR,
+           typename NF = typename GR::template NodeMap<bool>,
+           typename Enable = void>
+  class FilterNodes :
+    public DigraphAdaptorExtender<
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
+                     true> > {
+#endif
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
+                     true> > Parent;
+
+  public:
+
+    typedef GR Digraph;
+    typedef NF NodeFilterMap;
+
+    typedef typename Parent::Node Node;
+
+  protected:
+    ConstMap<typename Digraph::Arc, Const<bool, true> > const_true_map;
+
+    FilterNodes() : const_true_map() {}
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subgraph for the given digraph or graph with the
+    /// given node filter map.
+    FilterNodes(GR& graph, NF& node_filter)
+      : Parent(), const_true_map()
+    {
+      Parent::initialize(graph, node_filter, const_true_map);
+    }
+
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node, so the iteration
+    /// jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+  };
+
+  template<typename GR, typename NF>
+  class FilterNodes<GR, NF,
+                    typename enable_if<UndirectedTagIndicator<GR> >::type> :
+    public GraphAdaptorExtender<
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
+                   true> > {
+
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
+                   true> > Parent;
+
+  public:
+
+    typedef GR Graph;
+    typedef NF NodeFilterMap;
+
+    typedef typename Parent::Node Node;
+
+  protected:
+    ConstMap<typename GR::Edge, Const<bool, true> > const_true_map;
+
+    FilterNodes() : const_true_map() {}
+
+  public:
+
+    FilterNodes(GR& graph, NodeFilterMap& node_filter) :
+      Parent(), const_true_map() {
+      Parent::initialize(graph, node_filter, const_true_map);
+    }
+
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+    bool status(const Node& n) const { return Parent::status(n); }
+    void disable(const Node& n) const { Parent::status(n, false); }
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+  };
+
+
+  /// \brief Returns a read-only FilterNodes adaptor
+  ///
+  /// This function just returns a read-only \ref FilterNodes adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterNodes
+  template<typename GR, typename NF>
+  FilterNodes<const GR, NF>
+  filterNodes(const GR& graph, NF& node_filter) {
+    return FilterNodes<const GR, NF>(graph, node_filter);
+  }
+
+  template<typename GR, typename NF>
+  FilterNodes<const GR, const NF>
+  filterNodes(const GR& graph, const NF& node_filter) {
+    return FilterNodes<const GR, const NF>(graph, node_filter);
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for hiding arcs in a digraph.
+  ///
+  /// FilterArcs adaptor can be used for hiding arcs in a digraph.
+  /// A \c bool arc map must be specified, which defines the filter for
+  /// the arcs. Only the arcs with \c true filter value are shown in the
+  /// subdigraph. This adaptor conforms to the \ref concepts::Digraph
+  /// "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// 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.
+  /// It can also be specified to be \c const.
+  /// \tparam AF The type of the arc filter map.
+  /// It must be a \c bool (or convertible) arc map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename DGR,
+           typename AF>
+  class FilterArcs {
+#else
+  template<typename DGR,
+           typename AF = typename DGR::template ArcMap<bool> >
+  class FilterArcs :
+    public DigraphAdaptorExtender<
+      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
+                     AF, false> > {
+#endif
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
+                     AF, false> > Parent;
+
+  public:
+
+    /// The type of the adapted digraph.
+    typedef DGR Digraph;
+    /// The type of the arc filter map.
+    typedef AF ArcFilterMap;
+
+    typedef typename Parent::Arc Arc;
+
+  protected:
+    ConstMap<typename DGR::Node, Const<bool, true> > const_true_map;
+
+    FilterArcs() : const_true_map() {}
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subdigraph for the given digraph with the given arc
+    /// filter map.
+    FilterArcs(DGR& digraph, ArcFilterMap& arc_filter)
+      : Parent(), const_true_map() {
+      Parent::initialize(digraph, const_true_map, arc_filter);
+    }
+
+    /// \brief Sets the status of the given arc
+    ///
+    /// This function sets the status of the given arc.
+    /// It is done by simply setting the assigned value of \c a
+    /// to \c v in the arc filter map.
+    void status(const Arc& a, bool v) const { Parent::status(a, v); }
+
+    /// \brief Returns the status of the given arc
+    ///
+    /// This function returns the status of the given arc.
+    /// It is \c true if the given arc is enabled (i.e. not hidden).
+    bool status(const Arc& a) const { return Parent::status(a); }
+
+    /// \brief Disables the given arc
+    ///
+    /// This function disables the given arc in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(a, false)".
+    void disable(const Arc& a) const { Parent::status(a, false); }
+
+    /// \brief Enables the given arc
+    ///
+    /// This function enables the given arc in the subdigraph.
+    /// It is the same as \ref status() "status(a, true)".
+    void enable(const Arc& a) const { Parent::status(a, true); }
+
+  };
+
+  /// \brief Returns a read-only FilterArcs adaptor
+  ///
+  /// This function just returns a read-only \ref FilterArcs adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterArcs
+  template<typename DGR, typename AF>
+  FilterArcs<const DGR, AF>
+  filterArcs(const DGR& digraph, AF& arc_filter) {
+    return FilterArcs<const DGR, AF>(digraph, arc_filter);
+  }
+
+  template<typename DGR, typename AF>
+  FilterArcs<const DGR, const AF>
+  filterArcs(const DGR& digraph, const AF& arc_filter) {
+    return FilterArcs<const DGR, const AF>(digraph, arc_filter);
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for hiding edges in a graph.
+  ///
+  /// FilterEdges adaptor can be used for hiding edges in a graph.
+  /// A \c bool edge map must be specified, which defines the filter for
+  /// the edges. Only the edges with \c true filter value are shown in the
+  /// subgraph. This adaptor conforms to the \ref concepts::Graph
+  /// "Graph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// 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.
+  /// It can also be specified to be \c const.
+  /// \tparam EF The type of the edge filter map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
+  /// adapted graph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename EF>
+  class FilterEdges {
+#else
+  template<typename GR,
+           typename EF = typename GR::template EdgeMap<bool> >
+  class FilterEdges :
+    public GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >,
+                   EF, false> > {
+#endif
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >,
+                   EF, false> > Parent;
+
+  public:
+
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the edge filter map.
+    typedef EF EdgeFilterMap;
+
+    typedef typename Parent::Edge Edge;
+
+  protected:
+    ConstMap<typename GR::Node, Const<bool, true> > const_true_map;
+
+    FilterEdges() : const_true_map(true) {
+      Parent::setNodeFilterMap(const_true_map);
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subgraph for the given graph with the given edge
+    /// filter map.
+    FilterEdges(GR& graph, EF& edge_filter)
+      : Parent(), const_true_map() {
+      Parent::initialize(graph, const_true_map, edge_filter);
+    }
+
+    /// \brief Sets the status of the given edge
+    ///
+    /// This function sets the status of the given edge.
+    /// It is done by simply setting the assigned value of \c e
+    /// to \c v in the edge filter map.
+    void status(const Edge& e, bool v) const { Parent::status(e, v); }
+
+    /// \brief Returns the status of the given edge
+    ///
+    /// This function returns the status of the given edge.
+    /// It is \c true if the given edge is enabled (i.e. not hidden).
+    bool status(const Edge& e) const { return Parent::status(e); }
+
+    /// \brief Disables the given edge
+    ///
+    /// This function disables the given edge in the subgraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(e, false)".
+    void disable(const Edge& e) const { Parent::status(e, false); }
+
+    /// \brief Enables the given edge
+    ///
+    /// This function enables the given edge in the subgraph.
+    /// It is the same as \ref status() "status(e, true)".
+    void enable(const Edge& e) const { Parent::status(e, true); }
+
+  };
+
+  /// \brief Returns a read-only FilterEdges adaptor
+  ///
+  /// This function just returns a read-only \ref FilterEdges adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterEdges
+  template<typename GR, typename EF>
+  FilterEdges<const GR, EF>
+  filterEdges(const GR& graph, EF& edge_filter) {
+    return FilterEdges<const GR, EF>(graph, edge_filter);
+  }
+
+  template<typename GR, typename EF>
+  FilterEdges<const GR, const EF>
+  filterEdges(const GR& graph, const EF& edge_filter) {
+    return FilterEdges<const GR, const EF>(graph, edge_filter);
+  }
+
+
+  template <typename DGR>
+  class UndirectorBase {
+  public:
+    typedef DGR Digraph;
+    typedef UndirectorBase Adaptor;
+
+    typedef True UndirectedTag;
+
+    typedef typename Digraph::Arc Edge;
+    typedef typename Digraph::Node Node;
+
+    class Arc {
+      friend class UndirectorBase;
+    protected:
+      Edge _edge;
+      bool _forward;
+
+      Arc(const Edge& edge, bool forward)
+        : _edge(edge), _forward(forward) {}
+
+    public:
+      Arc() {}
+
+      Arc(Invalid) : _edge(INVALID), _forward(true) {}
+
+      operator const Edge&() const { return _edge; }
+
+      bool operator==(const Arc &other) const {
+        return _forward == other._forward && _edge == other._edge;
+      }
+      bool operator!=(const Arc &other) const {
+        return _forward != other._forward || _edge != other._edge;
+      }
+      bool operator<(const Arc &other) const {
+        return _forward < other._forward ||
+          (_forward == other._forward && _edge < other._edge);
+      }
+    };
+
+    void first(Node& n) const {
+      _digraph->first(n);
+    }
+
+    void next(Node& n) const {
+      _digraph->next(n);
+    }
+
+    void first(Arc& a) const {
+      _digraph->first(a._edge);
+      a._forward = true;
+    }
+
+    void next(Arc& a) const {
+      if (a._forward) {
+        a._forward = false;
+      } else {
+        _digraph->next(a._edge);
+        a._forward = true;
+      }
+    }
+
+    void first(Edge& e) const {
+      _digraph->first(e);
+    }
+
+    void next(Edge& e) const {
+      _digraph->next(e);
+    }
+
+    void firstOut(Arc& a, const Node& n) const {
+      _digraph->firstIn(a._edge, n);
+      if (a._edge != INVALID ) {
+        a._forward = false;
+      } else {
+        _digraph->firstOut(a._edge, n);
+        a._forward = true;
+      }
+    }
+    void nextOut(Arc &a) const {
+      if (!a._forward) {
+        Node n = _digraph->target(a._edge);
+        _digraph->nextIn(a._edge);
+        if (a._edge == INVALID) {
+          _digraph->firstOut(a._edge, n);
+          a._forward = true;
+        }
+      }
+      else {
+        _digraph->nextOut(a._edge);
+      }
+    }
+
+    void firstIn(Arc &a, const Node &n) const {
+      _digraph->firstOut(a._edge, n);
+      if (a._edge != INVALID ) {
+        a._forward = false;
+      } else {
+        _digraph->firstIn(a._edge, n);
+        a._forward = true;
+      }
+    }
+    void nextIn(Arc &a) const {
+      if (!a._forward) {
+        Node n = _digraph->source(a._edge);
+        _digraph->nextOut(a._edge);
+        if (a._edge == INVALID ) {
+          _digraph->firstIn(a._edge, n);
+          a._forward = true;
+        }
+      }
+      else {
+        _digraph->nextIn(a._edge);
+      }
+    }
+
+    void firstInc(Edge &e, bool &d, const Node &n) const {
+      d = true;
+      _digraph->firstOut(e, n);
+      if (e != INVALID) return;
+      d = false;
+      _digraph->firstIn(e, n);
+    }
+
+    void nextInc(Edge &e, bool &d) const {
+      if (d) {
+        Node s = _digraph->source(e);
+        _digraph->nextOut(e);
+        if (e != INVALID) return;
+        d = false;
+        _digraph->firstIn(e, s);
+      } else {
+        _digraph->nextIn(e);
+      }
+    }
+
+    Node u(const Edge& e) const {
+      return _digraph->source(e);
+    }
+
+    Node v(const Edge& e) const {
+      return _digraph->target(e);
+    }
+
+    Node source(const Arc &a) const {
+      return a._forward ? _digraph->source(a._edge) : _digraph->target(a._edge);
+    }
+
+    Node target(const Arc &a) const {
+      return a._forward ? _digraph->target(a._edge) : _digraph->source(a._edge);
+    }
+
+    static Arc direct(const Edge &e, bool d) {
+      return Arc(e, d);
+    }
+
+    static bool direction(const Arc &a) { return a._forward; }
+
+    Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
+    Arc arcFromId(int ix) const {
+      return direct(_digraph->arcFromId(ix >> 1), bool(ix & 1));
+    }
+    Edge edgeFromId(int ix) const { return _digraph->arcFromId(ix); }
+
+    int id(const Node &n) const { return _digraph->id(n); }
+    int id(const Arc &a) const {
+      return  (_digraph->id(a) << 1) | (a._forward ? 1 : 0);
+    }
+    int id(const Edge &e) const { return _digraph->id(e); }
+
+    int maxNodeId() const { return _digraph->maxNodeId(); }
+    int maxArcId() const { return (_digraph->maxArcId() << 1) | 1; }
+    int maxEdgeId() const { return _digraph->maxArcId(); }
+
+    Node addNode() { return _digraph->addNode(); }
+    Edge addEdge(const Node& u, const Node& v) {
+      return _digraph->addArc(u, v);
+    }
+
+    void erase(const Node& i) { _digraph->erase(i); }
+    void erase(const Edge& i) { _digraph->erase(i); }
+
+    void clear() { _digraph->clear(); }
+
+    typedef NodeNumTagIndicator<Digraph> NodeNumTag;
+    int nodeNum() const { return _digraph->nodeNum(); }
+
+    typedef ArcNumTagIndicator<Digraph> ArcNumTag;
+    int arcNum() const { return 2 * _digraph->arcNum(); }
+
+    typedef ArcNumTag EdgeNumTag;
+    int edgeNum() const { return _digraph->arcNum(); }
+
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
+    Arc findArc(Node s, Node t, Arc p = INVALID) const {
+      if (p == INVALID) {
+        Edge arc = _digraph->findArc(s, t);
+        if (arc != INVALID) return direct(arc, true);
+        arc = _digraph->findArc(t, s);
+        if (arc != INVALID) return direct(arc, false);
+      } else if (direction(p)) {
+        Edge arc = _digraph->findArc(s, t, p);
+        if (arc != INVALID) return direct(arc, true);
+        arc = _digraph->findArc(t, s);
+        if (arc != INVALID) return direct(arc, false);
+      } else {
+        Edge arc = _digraph->findArc(t, s, p);
+        if (arc != INVALID) return direct(arc, false);
+      }
+      return INVALID;
+    }
+
+    typedef FindArcTag FindEdgeTag;
+    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
+      if (s != t) {
+        if (p == INVALID) {
+          Edge arc = _digraph->findArc(s, t);
+          if (arc != INVALID) return arc;
+          arc = _digraph->findArc(t, s);
+          if (arc != INVALID) return arc;
+        } else if (_digraph->source(p) == s) {
+          Edge arc = _digraph->findArc(s, t, p);
+          if (arc != INVALID) return arc;
+          arc = _digraph->findArc(t, s);
+          if (arc != INVALID) return arc;
+        } else {
+          Edge arc = _digraph->findArc(t, s, p);
+          if (arc != INVALID) return arc;
+        }
+      } else {
+        return _digraph->findArc(s, t, p);
+      }
+      return INVALID;
+    }
+
+  private:
+
+    template <typename V>
+    class ArcMapBase {
+    private:
+
+      typedef typename DGR::template ArcMap<V> MapImpl;
+
+    public:
+
+      typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
+
+      typedef V Value;
+      typedef Arc Key;
+      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<MapImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReference;
+      typedef typename MapTraits<MapImpl>::ReturnValue Reference;
+
+      ArcMapBase(const UndirectorBase<DGR>& adaptor) :
+        _forward(*adaptor._digraph), _backward(*adaptor._digraph) {}
+
+      ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
+        : _forward(*adaptor._digraph, value),
+          _backward(*adaptor._digraph, value) {}
+
+      void set(const Arc& a, const V& value) {
+        if (direction(a)) {
+          _forward.set(a, value);
+        } else {
+          _backward.set(a, value);
+        }
+      }
+
+      ConstReturnValue operator[](const Arc& a) const {
+        if (direction(a)) {
+          return _forward[a];
+        } else {
+          return _backward[a];
+        }
+      }
+
+      ReturnValue operator[](const Arc& a) {
+        if (direction(a)) {
+          return _forward[a];
+        } else {
+          return _backward[a];
+        }
+      }
+
+    protected:
+
+      MapImpl _forward, _backward;
+
+    };
+
+  public:
+
+    template <typename V>
+    class NodeMap : public DGR::template NodeMap<V> {
+      typedef typename DGR::template NodeMap<V> Parent;
+
+    public:
+      typedef V Value;
+
+      explicit NodeMap(const UndirectorBase<DGR>& adaptor)
+        : Parent(*adaptor._digraph) {}
+
+      NodeMap(const UndirectorBase<DGR>& adaptor, const V& value)
+        : Parent(*adaptor._digraph, value) { }
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename V>
+    class ArcMap
+      : public SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > {
+      typedef SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > Parent;
+
+    public:
+      typedef V Value;
+
+      explicit ArcMap(const UndirectorBase<DGR>& adaptor)
+        : Parent(adaptor) {}
+
+      ArcMap(const UndirectorBase<DGR>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class EdgeMap : public Digraph::template ArcMap<V> {
+      typedef typename Digraph::template ArcMap<V> Parent;
+
+    public:
+      typedef V Value;
+
+      explicit EdgeMap(const UndirectorBase<DGR>& adaptor)
+        : Parent(*adaptor._digraph) {}
+
+      EdgeMap(const UndirectorBase<DGR>& adaptor, const V& value)
+        : Parent(*adaptor._digraph, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
+    NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
+
+    typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
+    EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
+
+    typedef EdgeNotifier ArcNotifier;
+    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
+
+  protected:
+
+    UndirectorBase() : _digraph(0) {}
+
+    DGR* _digraph;
+
+    void initialize(DGR& digraph) {
+      _digraph = &digraph;
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for viewing a digraph as an undirected graph.
+  ///
+  /// Undirector adaptor can be used for viewing a digraph as an undirected
+  /// graph. All arcs of the underlying digraph are showed in the
+  /// adaptor as an edge (and also as a pair of arcs, of course).
+  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// 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.
+  /// It can also be specified to be \c const.
+  ///
+  /// \note The \c Node type of this adaptor and the adapted digraph are
+  /// convertible to each other, moreover the \c Edge type of the adaptor
+  /// and the \c Arc type of the adapted digraph are also convertible to
+  /// each other.
+  /// (Thus the \c Arc type of the adaptor is convertible to the \c Arc type
+  /// of the adapted digraph.)
+  template<typename DGR>
+#ifdef DOXYGEN
+  class Undirector {
+#else
+  class Undirector :
+    public GraphAdaptorExtender<UndirectorBase<DGR> > {
+#endif
+    typedef GraphAdaptorExtender<UndirectorBase<DGR> > Parent;
+  public:
+    /// The type of the adapted digraph.
+    typedef DGR Digraph;
+  protected:
+    Undirector() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates an undirected graph from the given digraph.
+    Undirector(DGR& digraph) {
+      this->initialize(digraph);
+    }
+
+    /// \brief Arc map combined from two original arc maps
+    ///
+    /// This map adaptor class adapts two arc maps of the underlying
+    /// digraph to get an arc map of the undirected graph.
+    /// Its value type is inherited from the first arc map type (\c FW).
+    /// \tparam FW The type of the "foward" arc map.
+    /// \tparam BK The type of the "backward" arc map.
+    template <typename FW, typename BK>
+    class CombinedArcMap {
+    public:
+
+      /// The key type of the map
+      typedef typename Parent::Arc Key;
+      /// The value type of the map
+      typedef typename FW::Value Value;
+
+      typedef typename MapTraits<FW>::ReferenceMapTag ReferenceMapTag;
+
+      typedef typename MapTraits<FW>::ReturnValue ReturnValue;
+      typedef typename MapTraits<FW>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<FW>::ReturnValue Reference;
+      typedef typename MapTraits<FW>::ConstReturnValue ConstReference;
+
+      /// Constructor
+      CombinedArcMap(FW& forward, BK& backward)
+        : _forward(&forward), _backward(&backward) {}
+
+      /// Sets the value associated with the given key.
+      void set(const Key& e, const Value& a) {
+        if (Parent::direction(e)) {
+          _forward->set(e, a);
+        } else {
+          _backward->set(e, a);
+        }
+      }
+
+      /// Returns the value associated with the given key.
+      ConstReturnValue operator[](const Key& e) const {
+        if (Parent::direction(e)) {
+          return (*_forward)[e];
+        } else {
+          return (*_backward)[e];
+        }
+      }
+
+      /// Returns a reference to the value associated with the given key.
+      ReturnValue operator[](const Key& e) {
+        if (Parent::direction(e)) {
+          return (*_forward)[e];
+        } else {
+          return (*_backward)[e];
+        }
+      }
+
+    protected:
+
+      FW* _forward;
+      BK* _backward;
+
+    };
+
+    /// \brief Returns a combined arc map
+    ///
+    /// This function just returns a combined arc map.
+    template <typename FW, typename BK>
+    static CombinedArcMap<FW, BK>
+    combinedArcMap(FW& forward, BK& backward) {
+      return CombinedArcMap<FW, BK>(forward, backward);
+    }
+
+    template <typename FW, typename BK>
+    static CombinedArcMap<const FW, BK>
+    combinedArcMap(const FW& forward, BK& backward) {
+      return CombinedArcMap<const FW, BK>(forward, backward);
+    }
+
+    template <typename FW, typename BK>
+    static CombinedArcMap<FW, const BK>
+    combinedArcMap(FW& forward, const BK& backward) {
+      return CombinedArcMap<FW, const BK>(forward, backward);
+    }
+
+    template <typename FW, typename BK>
+    static CombinedArcMap<const FW, const BK>
+    combinedArcMap(const FW& forward, const BK& backward) {
+      return CombinedArcMap<const FW, const BK>(forward, backward);
+    }
+
+  };
+
+  /// \brief Returns a read-only Undirector adaptor
+  ///
+  /// This function just returns a read-only \ref Undirector adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates Undirector
+  template<typename DGR>
+  Undirector<const DGR> undirector(const DGR& digraph) {
+    return Undirector<const DGR>(digraph);
+  }
+
+
+  template <typename GR, typename DM>
+  class OrienterBase {
+  public:
+
+    typedef GR Graph;
+    typedef DM DirectionMap;
+
+    typedef typename GR::Node Node;
+    typedef typename GR::Edge Arc;
+
+    void reverseArc(const Arc& arc) {
+      _direction->set(arc, !(*_direction)[arc]);
+    }
+
+    void first(Node& i) const { _graph->first(i); }
+    void first(Arc& i) const { _graph->first(i); }
+    void firstIn(Arc& i, const Node& n) const {
+      bool d = true;
+      _graph->firstInc(i, d, n);
+      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
+    }
+    void firstOut(Arc& i, const Node& n ) const {
+      bool d = true;
+      _graph->firstInc(i, d, n);
+      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
+    }
+
+    void next(Node& i) const { _graph->next(i); }
+    void next(Arc& i) const { _graph->next(i); }
+    void nextIn(Arc& i) const {
+      bool d = !(*_direction)[i];
+      _graph->nextInc(i, d);
+      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
+    }
+    void nextOut(Arc& i) const {
+      bool d = (*_direction)[i];
+      _graph->nextInc(i, d);
+      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
+    }
+
+    Node source(const Arc& e) const {
+      return (*_direction)[e] ? _graph->u(e) : _graph->v(e);
+    }
+    Node target(const Arc& e) const {
+      return (*_direction)[e] ? _graph->v(e) : _graph->u(e);
+    }
+
+    typedef NodeNumTagIndicator<Graph> NodeNumTag;
+    int nodeNum() const { return _graph->nodeNum(); }
+
+    typedef EdgeNumTagIndicator<Graph> ArcNumTag;
+    int arcNum() const { return _graph->edgeNum(); }
+
+    typedef FindEdgeTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      Arc arc = _graph->findEdge(u, v, prev);
+      while (arc != INVALID && source(arc) != u) {
+        arc = _graph->findEdge(u, v, arc);
+      }
+      return arc;
+    }
+
+    Node addNode() {
+      return Node(_graph->addNode());
+    }
+
+    Arc addArc(const Node& u, const Node& v) {
+      Arc arc = _graph->addEdge(u, v);
+      _direction->set(arc, _graph->u(arc) == u);
+      return arc;
+    }
+
+    void erase(const Node& i) { _graph->erase(i); }
+    void erase(const Arc& i) { _graph->erase(i); }
+
+    void clear() { _graph->clear(); }
+
+    int id(const Node& v) const { return _graph->id(v); }
+    int id(const Arc& e) const { return _graph->id(e); }
+
+    Node nodeFromId(int idx) const { return _graph->nodeFromId(idx); }
+    Arc arcFromId(int idx) const { return _graph->edgeFromId(idx); }
+
+    int maxNodeId() const { return _graph->maxNodeId(); }
+    int maxArcId() const { return _graph->maxEdgeId(); }
+
+    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
+    NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
+
+    typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
+    ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
+
+    template <typename V>
+    class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
+    public:
+
+      explicit NodeMap(const OrienterBase<GR, DM>& adapter)
+        : Parent(*adapter._graph) {}
+
+      NodeMap(const OrienterBase<GR, DM>& adapter, const V& value)
+        : Parent(*adapter._graph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename V>
+    class ArcMap : public GR::template EdgeMap<V> {
+      typedef typename Graph::template EdgeMap<V> Parent;
+
+    public:
+
+      explicit ArcMap(const OrienterBase<GR, DM>& adapter)
+        : Parent(*adapter._graph) { }
+
+      ArcMap(const OrienterBase<GR, DM>& adapter, const V& value)
+        : Parent(*adapter._graph, value) { }
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+
+
+  protected:
+    Graph* _graph;
+    DM* _direction;
+
+    void initialize(GR& graph, DM& direction) {
+      _graph = &graph;
+      _direction = &direction;
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for orienting the edges of a graph to get a digraph
+  ///
+  /// Orienter adaptor can be used for orienting the edges of a graph to
+  /// get a digraph. A \c bool edge map of the underlying graph must be
+  /// specified, which define the direction of the arcs in the adaptor.
+  /// The arcs can be easily reversed by the \c reverseArc() member function
+  /// of the adaptor.
+  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// This class provides item counting in the same time as the adapted
+  /// graph structure.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam DM The type of the direction map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node type of this adaptor and the adapted graph are
+  /// convertible to each other, moreover the \c Arc type of the adaptor
+  /// and the \c Edge type of the adapted graph are also convertible to
+  /// each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename DM>
+  class Orienter {
+#else
+  template<typename GR,
+           typename DM = typename GR::template EdgeMap<bool> >
+  class Orienter :
+    public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
+#endif
+    typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
+  public:
+
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the direction edge map.
+    typedef DM DirectionMap;
+
+    typedef typename Parent::Arc Arc;
+
+  protected:
+    Orienter() { }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor of the adaptor.
+    Orienter(GR& graph, DM& direction) {
+      Parent::initialize(graph, direction);
+    }
+
+    /// \brief Reverses the given arc
+    ///
+    /// This function reverses the given arc.
+    /// It is done by simply negate the assigned value of \c a
+    /// in the direction map.
+    void reverseArc(const Arc& a) {
+      Parent::reverseArc(a);
+    }
+  };
+
+  /// \brief Returns a read-only Orienter adaptor
+  ///
+  /// This function just returns a read-only \ref Orienter adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates Orienter
+  template<typename GR, typename DM>
+  Orienter<const GR, DM>
+  orienter(const GR& graph, DM& direction) {
+    return Orienter<const GR, DM>(graph, direction);
+  }
+
+  template<typename GR, typename DM>
+  Orienter<const GR, const DM>
+  orienter(const GR& graph, const DM& direction) {
+    return Orienter<const GR, const DM>(graph, direction);
+  }
+
+  namespace _adaptor_bits {
+
+    template <typename DGR, typename CM, typename FM, typename TL>
+    class ResForwardFilter {
+    public:
+
+      typedef typename DGR::Arc Key;
+      typedef bool Value;
+
+    private:
+
+      const CM* _capacity;
+      const FM* _flow;
+      TL _tolerance;
+
+    public:
+
+      ResForwardFilter(const CM& capacity, const FM& flow,
+                       const TL& tolerance = TL())
+        : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
+
+      bool operator[](const typename DGR::Arc& a) const {
+        return _tolerance.positive((*_capacity)[a] - (*_flow)[a]);
+      }
+    };
+
+    template<typename DGR,typename CM, typename FM, typename TL>
+    class ResBackwardFilter {
+    public:
+
+      typedef typename DGR::Arc Key;
+      typedef bool Value;
+
+    private:
+
+      const CM* _capacity;
+      const FM* _flow;
+      TL _tolerance;
+
+    public:
+
+      ResBackwardFilter(const CM& capacity, const FM& flow,
+                        const TL& tolerance = TL())
+        : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
+
+      bool operator[](const typename DGR::Arc& a) const {
+        return _tolerance.positive((*_flow)[a]);
+      }
+    };
+
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for composing the residual digraph for directed
+  /// flow and circulation problems.
+  ///
+  /// ResidualDigraph can be used for composing the \e residual digraph
+  /// for directed flow and circulation problems. Let \f$ G=(V, A) \f$
+  /// be a directed graph and let \f$ F \f$ be a number type.
+  /// Let \f$ flow, cap: A\to F \f$ be functions on the arcs.
+  /// This adaptor implements a digraph structure with node set \f$ V \f$
+  /// and arc set \f$ A_{forward}\cup A_{backward} \f$,
+  /// where \f$ A_{forward}=\{uv : uv\in A, flow(uv)<cap(uv)\} \f$ and
+  /// \f$ A_{backward}=\{vu : uv\in A, flow(uv)>0\} \f$, i.e. the so
+  /// called residual digraph.
+  /// When the union \f$ A_{forward}\cup A_{backward} \f$ is taken,
+  /// multiplicities are counted, i.e. the adaptor has exactly
+  /// \f$ |A_{forward}| + |A_{backward}|\f$ arcs (it may have parallel
+  /// arcs).
+  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// 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.
+  /// It is implicitly \c const.
+  /// \tparam CM The type of the capacity map.
+  /// It must be an arc map of some numerical type, which defines
+  /// the capacities in the flow problem. It is implicitly \c const.
+  /// The default type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam FM The type of the flow map.
+  /// It must be an arc map of some numerical type, which defines
+  /// the flow values in the flow problem. The default type is \c CM.
+  /// \tparam TL The tolerance type for handling inexact computation.
+  /// The default tolerance type depends on the value type of the
+  /// capacity map.
+  ///
+  /// \note This adaptor is implemented using Undirector and FilterArcs
+  /// adaptors.
+  ///
+  /// \note The \c Node type of this adaptor and the adapted digraph are
+  /// convertible to each other, moreover the \c Arc type of the adaptor
+  /// is convertible to the \c Arc type of the adapted digraph.
+#ifdef DOXYGEN
+  template<typename DGR, typename CM, typename FM, typename TL>
+  class ResidualDigraph
+#else
+  template<typename DGR,
+           typename CM = typename DGR::template ArcMap<int>,
+           typename FM = CM,
+           typename TL = Tolerance<typename CM::Value> >
+  class ResidualDigraph
+    : public SubDigraph<
+        Undirector<const DGR>,
+        ConstMap<typename DGR::Node, Const<bool, true> >,
+        typename Undirector<const DGR>::template CombinedArcMap<
+          _adaptor_bits::ResForwardFilter<const DGR, CM, FM, TL>,
+          _adaptor_bits::ResBackwardFilter<const DGR, CM, FM, TL> > >
+#endif
+  {
+  public:
+
+    /// The type of the underlying digraph.
+    typedef DGR Digraph;
+    /// The type of the capacity map.
+    typedef CM CapacityMap;
+    /// The type of the flow map.
+    typedef FM FlowMap;
+    /// The tolerance type.
+    typedef TL Tolerance;
+
+    typedef typename CapacityMap::Value Value;
+    typedef ResidualDigraph Adaptor;
+
+  protected:
+
+    typedef Undirector<const Digraph> Undirected;
+
+    typedef ConstMap<typename DGR::Node, Const<bool, true> > NodeFilter;
+
+    typedef _adaptor_bits::ResForwardFilter<const DGR, CM,
+                                            FM, TL> ForwardFilter;
+
+    typedef _adaptor_bits::ResBackwardFilter<const DGR, CM,
+                                             FM, TL> BackwardFilter;
+
+    typedef typename Undirected::
+      template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
+
+    typedef SubDigraph<Undirected, NodeFilter, ArcFilter> Parent;
+
+    const CapacityMap* _capacity;
+    FlowMap* _flow;
+
+    Undirected _graph;
+    NodeFilter _node_filter;
+    ForwardFilter _forward_filter;
+    BackwardFilter _backward_filter;
+    ArcFilter _arc_filter;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor of the residual digraph adaptor. The parameters are the
+    /// digraph, the capacity map, the flow map, and a tolerance object.
+    ResidualDigraph(const DGR& digraph, const CM& capacity,
+                    FM& flow, const TL& tolerance = Tolerance())
+      : Parent(), _capacity(&capacity), _flow(&flow),
+        _graph(digraph), _node_filter(),
+        _forward_filter(capacity, flow, tolerance),
+        _backward_filter(capacity, flow, tolerance),
+        _arc_filter(_forward_filter, _backward_filter)
+    {
+      Parent::initialize(_graph, _node_filter, _arc_filter);
+    }
+
+    typedef typename Parent::Arc Arc;
+
+    /// \brief Returns the residual capacity of the given arc.
+    ///
+    /// Returns the residual capacity of the given arc.
+    Value residualCapacity(const Arc& a) const {
+      if (Undirected::direction(a)) {
+        return (*_capacity)[a] - (*_flow)[a];
+      } else {
+        return (*_flow)[a];
+      }
+    }
+
+    /// \brief Augments on the given arc in the residual digraph.
+    ///
+    /// Augments on the given arc in the residual digraph. It increases
+    /// or decreases the flow value on the original arc according to the
+    /// direction of the residual arc.
+    void augment(const Arc& a, const Value& v) const {
+      if (Undirected::direction(a)) {
+        _flow->set(a, (*_flow)[a] + v);
+      } else {
+        _flow->set(a, (*_flow)[a] - v);
+      }
+    }
+
+    /// \brief Returns \c true if the given residual arc is a forward arc.
+    ///
+    /// Returns \c true if the given residual arc has the same orientation
+    /// as the original arc, i.e. it is a so called forward arc.
+    static bool forward(const Arc& a) {
+      return Undirected::direction(a);
+    }
+
+    /// \brief Returns \c true if the given residual arc is a backward arc.
+    ///
+    /// Returns \c true if the given residual arc has the opposite orientation
+    /// than the original arc, i.e. it is a so called backward arc.
+    static bool backward(const Arc& a) {
+      return !Undirected::direction(a);
+    }
+
+    /// \brief Returns the forward oriented residual arc.
+    ///
+    /// Returns the forward oriented residual arc related to the given
+    /// arc of the underlying digraph.
+    static Arc forward(const typename Digraph::Arc& a) {
+      return Undirected::direct(a, true);
+    }
+
+    /// \brief Returns the backward oriented residual arc.
+    ///
+    /// Returns the backward oriented residual arc related to the given
+    /// arc of the underlying digraph.
+    static Arc backward(const typename Digraph::Arc& a) {
+      return Undirected::direct(a, false);
+    }
+
+    /// \brief Residual capacity map.
+    ///
+    /// This map adaptor class can be used for obtaining the residual
+    /// capacities as an arc map of the residual digraph.
+    /// Its value type is inherited from the capacity map.
+    class ResidualCapacity {
+    protected:
+      const Adaptor* _adaptor;
+    public:
+      /// The key type of the map
+      typedef Arc Key;
+      /// The value type of the map
+      typedef typename CapacityMap::Value Value;
+
+      /// Constructor
+      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor)
+        : _adaptor(&adaptor) {}
+
+      /// Returns the value associated with the given residual arc
+      Value operator[](const Arc& a) const {
+        return _adaptor->residualCapacity(a);
+      }
+
+    };
+
+    /// \brief Returns a residual capacity map
+    ///
+    /// This function just returns a residual capacity map.
+    ResidualCapacity residualCapacity() const {
+      return ResidualCapacity(*this);
+    }
+
+  };
+
+  /// \brief Returns a (read-only) Residual adaptor
+  ///
+  /// This function just returns a (read-only) \ref ResidualDigraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates ResidualDigraph
+    template<typename DGR, typename CM, typename FM>
+  ResidualDigraph<DGR, CM, FM>
+  residualDigraph(const DGR& digraph, const CM& capacity_map, FM& flow_map) {
+    return ResidualDigraph<DGR, CM, FM> (digraph, capacity_map, flow_map);
+  }
+
+
+  template <typename DGR>
+  class SplitNodesBase {
+    typedef DigraphAdaptorBase<const DGR> Parent;
+
+  public:
+
+    typedef DGR Digraph;
+    typedef SplitNodesBase Adaptor;
+
+    typedef typename DGR::Node DigraphNode;
+    typedef typename DGR::Arc DigraphArc;
+
+    class Node;
+    class Arc;
+
+  private:
+
+    template <typename T> class NodeMapBase;
+    template <typename T> class ArcMapBase;
+
+  public:
+
+    class Node : public DigraphNode {
+      friend class SplitNodesBase;
+      template <typename T> friend class NodeMapBase;
+    private:
+
+      bool _in;
+      Node(DigraphNode node, bool in)
+        : DigraphNode(node), _in(in) {}
+
+    public:
+
+      Node() {}
+      Node(Invalid) : DigraphNode(INVALID), _in(true) {}
+
+      bool operator==(const Node& node) const {
+        return DigraphNode::operator==(node) && _in == node._in;
+      }
+
+      bool operator!=(const Node& node) const {
+        return !(*this == node);
+      }
+
+      bool operator<(const Node& node) const {
+        return DigraphNode::operator<(node) ||
+          (DigraphNode::operator==(node) && _in < node._in);
+      }
+    };
+
+    class Arc {
+      friend class SplitNodesBase;
+      template <typename T> friend class ArcMapBase;
+    private:
+      typedef BiVariant<DigraphArc, DigraphNode> ArcImpl;
+
+      explicit Arc(const DigraphArc& arc) : _item(arc) {}
+      explicit Arc(const DigraphNode& node) : _item(node) {}
+
+      ArcImpl _item;
+
+    public:
+      Arc() {}
+      Arc(Invalid) : _item(DigraphArc(INVALID)) {}
+
+      bool operator==(const Arc& arc) const {
+        if (_item.firstState()) {
+          if (arc._item.firstState()) {
+            return _item.first() == arc._item.first();
+          }
+        } else {
+          if (arc._item.secondState()) {
+            return _item.second() == arc._item.second();
+          }
+        }
+        return false;
+      }
+
+      bool operator!=(const Arc& arc) const {
+        return !(*this == arc);
+      }
+
+      bool operator<(const Arc& arc) const {
+        if (_item.firstState()) {
+          if (arc._item.firstState()) {
+            return _item.first() < arc._item.first();
+          }
+          return false;
+        } else {
+          if (arc._item.secondState()) {
+            return _item.second() < arc._item.second();
+          }
+          return true;
+        }
+      }
+
+      operator DigraphArc() const { return _item.first(); }
+      operator DigraphNode() const { return _item.second(); }
+
+    };
+
+    void first(Node& n) const {
+      _digraph->first(n);
+      n._in = true;
+    }
+
+    void next(Node& n) const {
+      if (n._in) {
+        n._in = false;
+      } else {
+        n._in = true;
+        _digraph->next(n);
+      }
+    }
+
+    void first(Arc& e) const {
+      e._item.setSecond();
+      _digraph->first(e._item.second());
+      if (e._item.second() == INVALID) {
+        e._item.setFirst();
+        _digraph->first(e._item.first());
+      }
+    }
+
+    void next(Arc& e) const {
+      if (e._item.secondState()) {
+        _digraph->next(e._item.second());
+        if (e._item.second() == INVALID) {
+          e._item.setFirst();
+          _digraph->first(e._item.first());
+        }
+      } else {
+        _digraph->next(e._item.first());
+      }
+    }
+
+    void firstOut(Arc& e, const Node& n) const {
+      if (n._in) {
+        e._item.setSecond(n);
+      } else {
+        e._item.setFirst();
+        _digraph->firstOut(e._item.first(), n);
+      }
+    }
+
+    void nextOut(Arc& e) const {
+      if (!e._item.firstState()) {
+        e._item.setFirst(INVALID);
+      } else {
+        _digraph->nextOut(e._item.first());
+      }
+    }
+
+    void firstIn(Arc& e, const Node& n) const {
+      if (!n._in) {
+        e._item.setSecond(n);
+      } else {
+        e._item.setFirst();
+        _digraph->firstIn(e._item.first(), n);
+      }
+    }
+
+    void nextIn(Arc& e) const {
+      if (!e._item.firstState()) {
+        e._item.setFirst(INVALID);
+      } else {
+        _digraph->nextIn(e._item.first());
+      }
+    }
+
+    Node source(const Arc& e) const {
+      if (e._item.firstState()) {
+        return Node(_digraph->source(e._item.first()), false);
+      } else {
+        return Node(e._item.second(), true);
+      }
+    }
+
+    Node target(const Arc& e) const {
+      if (e._item.firstState()) {
+        return Node(_digraph->target(e._item.first()), true);
+      } else {
+        return Node(e._item.second(), false);
+      }
+    }
+
+    int id(const Node& n) const {
+      return (_digraph->id(n) << 1) | (n._in ? 0 : 1);
+    }
+    Node nodeFromId(int ix) const {
+      return Node(_digraph->nodeFromId(ix >> 1), (ix & 1) == 0);
+    }
+    int maxNodeId() const {
+      return 2 * _digraph->maxNodeId() + 1;
+    }
+
+    int id(const Arc& e) const {
+      if (e._item.firstState()) {
+        return _digraph->id(e._item.first()) << 1;
+      } else {
+        return (_digraph->id(e._item.second()) << 1) | 1;
+      }
+    }
+    Arc arcFromId(int ix) const {
+      if ((ix & 1) == 0) {
+        return Arc(_digraph->arcFromId(ix >> 1));
+      } else {
+        return Arc(_digraph->nodeFromId(ix >> 1));
+      }
+    }
+    int maxArcId() const {
+      return std::max(_digraph->maxNodeId() << 1,
+                      (_digraph->maxArcId() << 1) | 1);
+    }
+
+    static bool inNode(const Node& n) {
+      return n._in;
+    }
+
+    static bool outNode(const Node& n) {
+      return !n._in;
+    }
+
+    static bool origArc(const Arc& e) {
+      return e._item.firstState();
+    }
+
+    static bool bindArc(const Arc& e) {
+      return e._item.secondState();
+    }
+
+    static Node inNode(const DigraphNode& n) {
+      return Node(n, true);
+    }
+
+    static Node outNode(const DigraphNode& n) {
+      return Node(n, false);
+    }
+
+    static Arc arc(const DigraphNode& n) {
+      return Arc(n);
+    }
+
+    static Arc arc(const DigraphArc& e) {
+      return Arc(e);
+    }
+
+    typedef True NodeNumTag;
+    int nodeNum() const {
+      return  2 * countNodes(*_digraph);
+    }
+
+    typedef True ArcNumTag;
+    int arcNum() const {
+      return countArcs(*_digraph) + countNodes(*_digraph);
+    }
+
+    typedef True FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      if (inNode(u) && outNode(v)) {
+        if (static_cast<const DigraphNode&>(u) ==
+            static_cast<const DigraphNode&>(v) && prev == INVALID) {
+          return Arc(u);
+        }
+      }
+      else if (outNode(u) && inNode(v)) {
+        return Arc(::lemon::findArc(*_digraph, u, v, prev));
+      }
+      return INVALID;
+    }
+
+  private:
+
+    template <typename V>
+    class NodeMapBase
+      : public MapTraits<typename Parent::template NodeMap<V> > {
+      typedef typename Parent::template NodeMap<V> NodeImpl;
+    public:
+      typedef Node Key;
+      typedef V Value;
+      typedef typename MapTraits<NodeImpl>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<NodeImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<NodeImpl>::ReturnValue Reference;
+      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReference;
+
+      NodeMapBase(const SplitNodesBase<DGR>& adaptor)
+        : _in_map(*adaptor._digraph), _out_map(*adaptor._digraph) {}
+      NodeMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
+        : _in_map(*adaptor._digraph, value),
+          _out_map(*adaptor._digraph, value) {}
+
+      void set(const Node& key, const V& val) {
+        if (SplitNodesBase<DGR>::inNode(key)) { _in_map.set(key, val); }
+        else {_out_map.set(key, val); }
+      }
+
+      ReturnValue operator[](const Node& key) {
+        if (SplitNodesBase<DGR>::inNode(key)) { return _in_map[key]; }
+        else { return _out_map[key]; }
+      }
+
+      ConstReturnValue operator[](const Node& key) const {
+        if (Adaptor::inNode(key)) { return _in_map[key]; }
+        else { return _out_map[key]; }
+      }
+
+    private:
+      NodeImpl _in_map, _out_map;
+    };
+
+    template <typename V>
+    class ArcMapBase
+      : public MapTraits<typename Parent::template ArcMap<V> > {
+      typedef typename Parent::template ArcMap<V> ArcImpl;
+      typedef typename Parent::template NodeMap<V> NodeImpl;
+    public:
+      typedef Arc Key;
+      typedef V Value;
+      typedef typename MapTraits<ArcImpl>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<ArcImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ArcImpl>::ReturnValue Reference;
+      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReference;
+
+      ArcMapBase(const SplitNodesBase<DGR>& adaptor)
+        : _arc_map(*adaptor._digraph), _node_map(*adaptor._digraph) {}
+      ArcMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
+        : _arc_map(*adaptor._digraph, value),
+          _node_map(*adaptor._digraph, value) {}
+
+      void set(const Arc& key, const V& val) {
+        if (SplitNodesBase<DGR>::origArc(key)) {
+          _arc_map.set(static_cast<const DigraphArc&>(key), val);
+        } else {
+          _node_map.set(static_cast<const DigraphNode&>(key), val);
+        }
+      }
+
+      ReturnValue operator[](const Arc& key) {
+        if (SplitNodesBase<DGR>::origArc(key)) {
+          return _arc_map[static_cast<const DigraphArc&>(key)];
+        } else {
+          return _node_map[static_cast<const DigraphNode&>(key)];
+        }
+      }
+
+      ConstReturnValue operator[](const Arc& key) const {
+        if (SplitNodesBase<DGR>::origArc(key)) {
+          return _arc_map[static_cast<const DigraphArc&>(key)];
+        } else {
+          return _node_map[static_cast<const DigraphNode&>(key)];
+        }
+      }
+
+    private:
+      ArcImpl _arc_map;
+      NodeImpl _node_map;
+    };
+
+  public:
+
+    template <typename V>
+    class NodeMap
+      : public SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > {
+      typedef SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > Parent;
+
+    public:
+      typedef V Value;
+
+      NodeMap(const SplitNodesBase<DGR>& adaptor)
+        : Parent(adaptor) {}
+
+      NodeMap(const SplitNodesBase<DGR>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename V>
+    class ArcMap
+      : public SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > {
+      typedef SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > Parent;
+
+    public:
+      typedef V Value;
+
+      ArcMap(const SplitNodesBase<DGR>& adaptor)
+        : Parent(adaptor) {}
+
+      ArcMap(const SplitNodesBase<DGR>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  protected:
+
+    SplitNodesBase() : _digraph(0) {}
+
+    DGR* _digraph;
+
+    void initialize(Digraph& digraph) {
+      _digraph = &digraph;
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for splitting the nodes of a digraph.
+  ///
+  /// SplitNodes adaptor can be used for splitting each node into an
+  /// \e in-node and an \e out-node in a digraph. Formaly, the adaptor
+  /// replaces each node \f$ u \f$ in the digraph with two nodes,
+  /// namely node \f$ u_{in} \f$ and node \f$ u_{out} \f$.
+  /// If there is a \f$ (v, u) \f$ arc in the original digraph, then the
+  /// new target of the arc will be \f$ u_{in} \f$ and similarly the
+  /// source of each original \f$ (u, v) \f$ arc will be \f$ u_{out} \f$.
+  /// The adaptor adds an additional \e bind \e arc from \f$ u_{in} \f$
+  /// to \f$ u_{out} \f$ for each node \f$ u \f$ of the original digraph.
+  ///
+  /// The aim of this class is running an algorithm with respect to node
+  /// costs or capacities if the algorithm considers only arc costs or
+  /// capacities directly.
+  /// In this case you can use \c SplitNodes adaptor, and set the node
+  /// costs/capacities of the original digraph to the \e bind \e arcs
+  /// in the adaptor.
+  ///
+  /// 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.
+  /// It is implicitly \c const.
+  ///
+  /// \note The \c Node type of this adaptor is converible to the \c Node
+  /// type of the adapted digraph.
+  template <typename DGR>
+#ifdef DOXYGEN
+  class SplitNodes {
+#else
+  class SplitNodes
+    : public DigraphAdaptorExtender<SplitNodesBase<const DGR> > {
+#endif
+    typedef DigraphAdaptorExtender<SplitNodesBase<const DGR> > Parent;
+
+  public:
+    typedef DGR Digraph;
+
+    typedef typename DGR::Node DigraphNode;
+    typedef typename DGR::Arc DigraphArc;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    /// \brief Constructor
+    ///
+    /// Constructor of the adaptor.
+    SplitNodes(const DGR& g) {
+      Parent::initialize(g);
+    }
+
+    /// \brief Returns \c true if the given node is an in-node.
+    ///
+    /// Returns \c true if the given node is an in-node.
+    static bool inNode(const Node& n) {
+      return Parent::inNode(n);
+    }
+
+    /// \brief Returns \c true if the given node is an out-node.
+    ///
+    /// Returns \c true if the given node is an out-node.
+    static bool outNode(const Node& n) {
+      return Parent::outNode(n);
+    }
+
+    /// \brief Returns \c true if the given arc is an original arc.
+    ///
+    /// Returns \c true if the given arc is one of the arcs in the
+    /// original digraph.
+    static bool origArc(const Arc& a) {
+      return Parent::origArc(a);
+    }
+
+    /// \brief Returns \c true if the given arc is a bind arc.
+    ///
+    /// Returns \c true if the given arc is a bind arc, i.e. it connects
+    /// an in-node and an out-node.
+    static bool bindArc(const Arc& a) {
+      return Parent::bindArc(a);
+    }
+
+    /// \brief Returns the in-node created from the given original node.
+    ///
+    /// Returns the in-node created from the given original node.
+    static Node inNode(const DigraphNode& n) {
+      return Parent::inNode(n);
+    }
+
+    /// \brief Returns the out-node created from the given original node.
+    ///
+    /// Returns the out-node created from the given original node.
+    static Node outNode(const DigraphNode& n) {
+      return Parent::outNode(n);
+    }
+
+    /// \brief Returns the bind arc that corresponds to the given
+    /// original node.
+    ///
+    /// Returns the bind arc in the adaptor that corresponds to the given
+    /// original node, i.e. the arc connecting the in-node and out-node
+    /// of \c n.
+    static Arc arc(const DigraphNode& n) {
+      return Parent::arc(n);
+    }
+
+    /// \brief Returns the arc that corresponds to the given original arc.
+    ///
+    /// Returns the arc in the adaptor that corresponds to the given
+    /// original arc.
+    static Arc arc(const DigraphArc& a) {
+      return Parent::arc(a);
+    }
+
+    /// \brief Node map combined from two original node maps
+    ///
+    /// This map adaptor class adapts two node maps of the original digraph
+    /// to get a node map of the split digraph.
+    /// Its value type is inherited from the first node map type (\c IN).
+    /// \tparam IN The type of the node map for the in-nodes.
+    /// \tparam OUT The type of the node map for the out-nodes.
+    template <typename IN, typename OUT>
+    class CombinedNodeMap {
+    public:
+
+      /// The key type of the map
+      typedef Node Key;
+      /// The value type of the map
+      typedef typename IN::Value Value;
+
+      typedef typename MapTraits<IN>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<IN>::ReturnValue ReturnValue;
+      typedef typename MapTraits<IN>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<IN>::ReturnValue Reference;
+      typedef typename MapTraits<IN>::ConstReturnValue ConstReference;
+
+      /// Constructor
+      CombinedNodeMap(IN& in_map, OUT& out_map)
+        : _in_map(in_map), _out_map(out_map) {}
+
+      /// Returns the value associated with the given key.
+      Value operator[](const Key& key) const {
+        if (SplitNodesBase<const DGR>::inNode(key)) {
+          return _in_map[key];
+        } else {
+          return _out_map[key];
+        }
+      }
+
+      /// Returns a reference to the value associated with the given key.
+      Value& operator[](const Key& key) {
+        if (SplitNodesBase<const DGR>::inNode(key)) {
+          return _in_map[key];
+        } else {
+          return _out_map[key];
+        }
+      }
+
+      /// Sets the value associated with the given key.
+      void set(const Key& key, const Value& value) {
+        if (SplitNodesBase<const DGR>::inNode(key)) {
+          _in_map.set(key, value);
+        } else {
+          _out_map.set(key, value);
+        }
+      }
+
+    private:
+
+      IN& _in_map;
+      OUT& _out_map;
+
+    };
+
+
+    /// \brief Returns a combined node map
+    ///
+    /// This function just returns a combined node map.
+    template <typename IN, typename OUT>
+    static CombinedNodeMap<IN, OUT>
+    combinedNodeMap(IN& in_map, OUT& out_map) {
+      return CombinedNodeMap<IN, OUT>(in_map, out_map);
+    }
+
+    template <typename IN, typename OUT>
+    static CombinedNodeMap<const IN, OUT>
+    combinedNodeMap(const IN& in_map, OUT& out_map) {
+      return CombinedNodeMap<const IN, OUT>(in_map, out_map);
+    }
+
+    template <typename IN, typename OUT>
+    static CombinedNodeMap<IN, const OUT>
+    combinedNodeMap(IN& in_map, const OUT& out_map) {
+      return CombinedNodeMap<IN, const OUT>(in_map, out_map);
+    }
+
+    template <typename IN, typename OUT>
+    static CombinedNodeMap<const IN, const OUT>
+    combinedNodeMap(const IN& in_map, const OUT& out_map) {
+      return CombinedNodeMap<const IN, const OUT>(in_map, out_map);
+    }
+
+    /// \brief Arc map combined from an arc map and a node map of the
+    /// original digraph.
+    ///
+    /// This map adaptor class adapts an arc map and a node map of the
+    /// original digraph to get an arc map of the split digraph.
+    /// Its value type is inherited from the original arc map type (\c AM).
+    /// \tparam AM The type of the arc map.
+    /// \tparam NM the type of the node map.
+    template <typename AM, typename NM>
+    class CombinedArcMap {
+    public:
+
+      /// The key type of the map
+      typedef Arc Key;
+      /// The value type of the map
+      typedef typename AM::Value Value;
+
+      typedef typename MapTraits<AM>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<AM>::ReturnValue ReturnValue;
+      typedef typename MapTraits<AM>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<AM>::ReturnValue Reference;
+      typedef typename MapTraits<AM>::ConstReturnValue ConstReference;
+
+      /// Constructor
+      CombinedArcMap(AM& arc_map, NM& node_map)
+        : _arc_map(arc_map), _node_map(node_map) {}
+
+      /// Returns the value associated with the given key.
+      Value operator[](const Key& arc) const {
+        if (SplitNodesBase<const DGR>::origArc(arc)) {
+          return _arc_map[arc];
+        } else {
+          return _node_map[arc];
+        }
+      }
+
+      /// Returns a reference to the value associated with the given key.
+      Value& operator[](const Key& arc) {
+        if (SplitNodesBase<const DGR>::origArc(arc)) {
+          return _arc_map[arc];
+        } else {
+          return _node_map[arc];
+        }
+      }
+
+      /// Sets the value associated with the given key.
+      void set(const Arc& arc, const Value& val) {
+        if (SplitNodesBase<const DGR>::origArc(arc)) {
+          _arc_map.set(arc, val);
+        } else {
+          _node_map.set(arc, val);
+        }
+      }
+
+    private:
+
+      AM& _arc_map;
+      NM& _node_map;
+
+    };
+
+    /// \brief Returns a combined arc map
+    ///
+    /// This function just returns a combined arc map.
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<ArcMap, NodeMap>
+    combinedArcMap(ArcMap& arc_map, NodeMap& node_map) {
+      return CombinedArcMap<ArcMap, NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<const ArcMap, NodeMap>
+    combinedArcMap(const ArcMap& arc_map, NodeMap& node_map) {
+      return CombinedArcMap<const ArcMap, NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<ArcMap, const NodeMap>
+    combinedArcMap(ArcMap& arc_map, const NodeMap& node_map) {
+      return CombinedArcMap<ArcMap, const NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<const ArcMap, const NodeMap>
+    combinedArcMap(const ArcMap& arc_map, const NodeMap& node_map) {
+      return CombinedArcMap<const ArcMap, const NodeMap>(arc_map, node_map);
+    }
+
+  };
+
+  /// \brief Returns a (read-only) SplitNodes adaptor
+  ///
+  /// This function just returns a (read-only) \ref SplitNodes adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SplitNodes
+  template<typename DGR>
+  SplitNodes<DGR>
+  splitNodes(const DGR& digraph) {
+    return SplitNodes<DGR>(digraph);
+  }
+
+#undef LEMON_SCOPE_FIX
+
+} //namespace lemon
+
+#endif //LEMON_ADAPTORS_H
diff --git a/lemon/arg_parser.cc b/lemon/arg_parser.cc
new file mode 100644
index 0000000..35a73d9
--- /dev/null
+++ b/lemon/arg_parser.cc
@@ -0,0 +1,474 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/arg_parser.h>
+
+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();
+    (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
+  }
+
+  ArgParser::ArgParser(int argc, const char * const *argv)
+    :_argc(argc), _argv(argv), _command_name(argv[0]),
+    _exit_on_problems(true) {
+    funcOption("-help","Print a short help message",_showHelp,this);
+    synonym("help","-help");
+    synonym("h","-help");
+  }
+
+  ArgParser::~ArgParser()
+  {
+    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
+      if(i->second.self_delete)
+        switch(i->second.type) {
+        case BOOL:
+          delete i->second.bool_p;
+          break;
+        case STRING:
+          delete i->second.string_p;
+          break;
+        case DOUBLE:
+          delete i->second.double_p;
+          break;
+        case INTEGER:
+          delete i->second.int_p;
+          break;
+        case UNKNOWN:
+          break;
+        case FUNC:
+          break;
+        }
+  }
+
+
+  ArgParser &ArgParser::intOption(const std::string &name,
+                               const std::string &help,
+                               int value, bool obl)
+  {
+    ParData p;
+    p.int_p=new int(value);
+    p.self_delete=true;
+    p.help=help;
+    p.type=INTEGER;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::doubleOption(const std::string &name,
+                               const std::string &help,
+                               double value, bool obl)
+  {
+    ParData p;
+    p.double_p=new double(value);
+    p.self_delete=true;
+    p.help=help;
+    p.type=DOUBLE;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::boolOption(const std::string &name,
+                               const std::string &help,
+                               bool value, bool obl)
+  {
+    ParData p;
+    p.bool_p=new bool(value);
+    p.self_delete=true;
+    p.help=help;
+    p.type=BOOL;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::stringOption(const std::string &name,
+                               const std::string &help,
+                               std::string value, bool obl)
+  {
+    ParData p;
+    p.string_p=new std::string(value);
+    p.self_delete=true;
+    p.help=help;
+    p.type=STRING;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::refOption(const std::string &name,
+                               const std::string &help,
+                               int &ref, bool obl)
+  {
+    ParData p;
+    p.int_p=&ref;
+    p.self_delete=false;
+    p.help=help;
+    p.type=INTEGER;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::refOption(const std::string &name,
+                                  const std::string &help,
+                                  double &ref, bool obl)
+  {
+    ParData p;
+    p.double_p=&ref;
+    p.self_delete=false;
+    p.help=help;
+    p.type=DOUBLE;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::refOption(const std::string &name,
+                                  const std::string &help,
+                                  bool &ref, bool obl)
+  {
+    ParData p;
+    p.bool_p=&ref;
+    p.self_delete=false;
+    p.help=help;
+    p.type=BOOL;
+    p.mandatory=obl;
+    _opts[name]=p;
+
+    ref = false;
+
+    return *this;
+  }
+
+  ArgParser &ArgParser::refOption(const std::string &name,
+                               const std::string &help,
+                               std::string &ref, bool obl)
+  {
+    ParData p;
+    p.string_p=&ref;
+    p.self_delete=false;
+    p.help=help;
+    p.type=STRING;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::funcOption(const std::string &name,
+                               const std::string &help,
+                               void (*func)(void *),void *data)
+  {
+    ParData p;
+    p.func_p.p=func;
+    p.func_p.data=data;
+    p.self_delete=false;
+    p.help=help;
+    p.type=FUNC;
+    p.mandatory=false;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::optionGroup(const std::string &group,
+                                    const std::string &opt)
+  {
+    Opts::iterator i = _opts.find(opt);
+    LEMON_ASSERT(i!=_opts.end(), "Unknown option: '"+opt+"'");
+    LEMON_ASSERT(!(i->second.ingroup),
+                 "Option already in option group: '"+opt+"'");
+    GroupData &g=_groups[group];
+    g.opts.push_back(opt);
+    i->second.ingroup=true;
+    return *this;
+  }
+
+  ArgParser &ArgParser::onlyOneGroup(const std::string &group)
+  {
+    GroupData &g=_groups[group];
+    g.only_one=true;
+    return *this;
+  }
+
+  ArgParser &ArgParser::synonym(const std::string &syn,
+                                const std::string &opt)
+  {
+    Opts::iterator o = _opts.find(opt);
+    Opts::iterator s = _opts.find(syn);
+    LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'");
+    LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'");
+    ParData p;
+    p.help=opt;
+    p.mandatory=false;
+    p.syn=true;
+    _opts[syn]=p;
+    o->second.has_syn=true;
+    return *this;
+  }
+
+  ArgParser &ArgParser::mandatoryGroup(const std::string &group)
+  {
+    GroupData &g=_groups[group];
+    g.mandatory=true;
+    return *this;
+  }
+
+  ArgParser &ArgParser::other(const std::string &name,
+                              const std::string &help)
+  {
+    _others_help.push_back(OtherArg(name,help));
+    return *this;
+  }
+
+  void ArgParser::show(std::ostream &os,Opts::const_iterator i) const
+  {
+    os << "-" << i->first;
+    if(i->second.has_syn)
+      for(Opts::const_iterator j=_opts.begin();j!=_opts.end();++j)
+        if(j->second.syn&&j->second.help==i->first)
+          os << "|-" << j->first;
+    switch(i->second.type) {
+    case STRING:
+      os << " str";
+      break;
+    case INTEGER:
+      os << " int";
+      break;
+    case DOUBLE:
+      os << " num";
+      break;
+    default:
+      break;
+    }
+  }
+
+  void ArgParser::show(std::ostream &os,Groups::const_iterator i) const
+  {
+    GroupData::Opts::const_iterator o=i->second.opts.begin();
+    while(o!=i->second.opts.end()) {
+      show(os,_opts.find(*o));
+      ++o;
+      if(o!=i->second.opts.end()) os<<'|';
+    }
+  }
+
+  void ArgParser::showHelp(Opts::const_iterator i) const
+  {
+    if(i->second.help.size()==0||i->second.syn) return;
+    std::cerr << "  ";
+    show(std::cerr,i);
+    std::cerr << std::endl;
+    std::cerr << "     " << i->second.help << std::endl;
+  }
+  void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::const_iterator i)
+    const
+  {
+    if(i->help.size()==0) return;
+    std::cerr << "  " << i->name << std::endl
+              << "     " << i->help << std::endl;
+  }
+
+  void ArgParser::shortHelp() const
+  {
+    const unsigned int LINE_LEN=77;
+    const std::string indent("    ");
+    std::cerr << "Usage:\n  " << _command_name;
+    int pos=_command_name.size()+2;
+    for(Groups::const_iterator g=_groups.begin();g!=_groups.end();++g) {
+      std::ostringstream cstr;
+      cstr << ' ';
+      if(!g->second.mandatory) cstr << '[';
+      show(cstr,g);
+      if(!g->second.mandatory) cstr << ']';
+      if(pos+cstr.str().size()>LINE_LEN) {
+        std::cerr << std::endl << indent;
+        pos=indent.size();
+      }
+      std::cerr << cstr.str();
+      pos+=cstr.str().size();
+    }
+    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
+      if(!i->second.ingroup&&!i->second.syn) {
+        std::ostringstream cstr;
+        cstr << ' ';
+        if(!i->second.mandatory) cstr << '[';
+        show(cstr,i);
+        if(!i->second.mandatory) cstr << ']';
+        if(pos+cstr.str().size()>LINE_LEN) {
+          std::cerr << std::endl << indent;
+          pos=indent.size();
+        }
+        std::cerr << cstr.str();
+        pos+=cstr.str().size();
+      }
+    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
+        i!=_others_help.end();++i)
+      {
+        std::ostringstream cstr;
+        cstr << ' ' << i->name;
+
+        if(pos+cstr.str().size()>LINE_LEN) {
+          std::cerr << std::endl << indent;
+          pos=indent.size();
+        }
+        std::cerr << cstr.str();
+        pos+=cstr.str().size();
+      }
+    std::cerr << std::endl;
+  }
+
+  void ArgParser::showHelp() const
+  {
+    shortHelp();
+    std::cerr << "Where:\n";
+    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
+        i!=_others_help.end();++i) showHelp(i);
+    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
+    _terminate(ArgParserException::HELP);
+  }
+
+
+  void ArgParser::unknownOpt(std::string arg) const
+  {
+    std::cerr << "\nUnknown option: " << arg << "\n";
+    std::cerr << "\nType '" << _command_name <<
+      " --help' to obtain a short summary on the usage.\n\n";
+    _terminate(ArgParserException::UNKNOWN_OPT);
+  }
+
+  void ArgParser::requiresValue(std::string arg, OptType t) const
+  {
+    std::cerr << "Argument '" << arg << "' requires a";
+    switch(t) {
+    case STRING:
+      std::cerr << " string";
+      break;
+    case INTEGER:
+      std::cerr << "n integer";
+      break;
+    case DOUBLE:
+      std::cerr << " floating point";
+      break;
+    default:
+      break;
+    }
+    std::cerr << " value\n\n";
+    showHelp();
+  }
+
+
+  void ArgParser::checkMandatories() const
+  {
+    bool ok=true;
+    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
+      if(i->second.mandatory&&!i->second.set)
+        {
+          if(ok)
+            std::cerr << _command_name
+                      << ": The following mandatory arguments are missing.\n";
+          ok=false;
+          showHelp(i);
+        }
+    for(Groups::const_iterator i=_groups.begin();i!=_groups.end();++i)
+      if(i->second.mandatory||i->second.only_one)
+        {
+          int set=0;
+          for(GroupData::Opts::const_iterator o=i->second.opts.begin();
+              o!=i->second.opts.end();++o)
+            if(_opts.find(*o)->second.set) ++set;
+          if(i->second.mandatory&&!set) {
+            std::cerr << _command_name <<
+              ": At least one of the following arguments is mandatory.\n";
+            ok=false;
+            for(GroupData::Opts::const_iterator o=i->second.opts.begin();
+                o!=i->second.opts.end();++o)
+              showHelp(_opts.find(*o));
+          }
+          if(i->second.only_one&&set>1) {
+            std::cerr << _command_name <<
+              ": At most one of the following arguments can be given.\n";
+            ok=false;
+            for(GroupData::Opts::const_iterator o=i->second.opts.begin();
+                o!=i->second.opts.end();++o)
+              showHelp(_opts.find(*o));
+          }
+        }
+    if(!ok) {
+      std::cerr << "\nType '" << _command_name <<
+        " --help' to obtain a short summary on the usage.\n\n";
+      _terminate(ArgParserException::INVALID_OPT);
+    }
+  }
+
+  ArgParser &ArgParser::parse()
+  {
+    for(int ar=1; ar<_argc; ++ar) {
+      std::string arg(_argv[ar]);
+      if (arg[0] != '-' || arg.size() == 1) {
+        _file_args.push_back(arg);
+      }
+      else {
+        Opts::iterator i = _opts.find(arg.substr(1));
+        if(i==_opts.end()) unknownOpt(arg);
+        else {
+          if(i->second.syn) i=_opts.find(i->second.help);
+          ParData &p(i->second);
+          if (p.type==BOOL) *p.bool_p=true;
+          else if (p.type==FUNC) p.func_p.p(p.func_p.data);
+          else if(++ar==_argc) requiresValue(arg, p.type);
+          else {
+            std::string val(_argv[ar]);
+            std::istringstream vals(val);
+            switch(p.type) {
+            case STRING:
+              *p.string_p=val;
+              break;
+            case INTEGER:
+              vals >> *p.int_p;
+              break;
+            case DOUBLE:
+              vals >> *p.double_p;
+              break;
+            default:
+              break;
+            }
+            if(p.type!=STRING&&(!vals||!vals.eof()))
+              requiresValue(arg, p.type);
+          }
+          p.set = true;
+        }
+      }
+    }
+    checkMandatories();
+
+    return *this;
+  }
+
+}
diff --git a/lemon/arg_parser.h b/lemon/arg_parser.h
new file mode 100644
index 0000000..3fbe75c
--- /dev/null
+++ b/lemon/arg_parser.h
@@ -0,0 +1,440 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_ARG_PARSER_H
+#define LEMON_ARG_PARSER_H
+
+#include <vector>
+#include <map>
+#include <list>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <lemon/assert.h>
+
+///\ingroup misc
+///\file
+///\brief A tool to parse command line arguments.
+
+namespace lemon {
+
+  ///Exception used by ArgParser
+
+  ///Exception used by ArgParser.
+  ///
+  class ArgParserException : public Exception {
+  public:
+    /// Reasons for failure
+
+    /// Reasons for failure.
+    ///
+    enum Reason {
+      HELP,         ///< <tt>--help</tt> option was given.
+      UNKNOWN_OPT,  ///< Unknown option was given.
+      INVALID_OPT   ///< Invalid combination of options.
+    };
+
+  private:
+    Reason _reason;
+
+  public:
+    ///Constructor
+    ArgParserException(Reason r) throw() : _reason(r) {}
+    ///Virtual destructor
+    virtual ~ArgParserException() throw() {}
+    ///A short description of the exception
+    virtual const char* what() const throw() {
+      switch(_reason)
+        {
+        case HELP:
+          return "lemon::ArgParseException: ask for help";
+          break;
+        case UNKNOWN_OPT:
+          return "lemon::ArgParseException: unknown option";
+          break;
+        case INVALID_OPT:
+          return "lemon::ArgParseException: invalid combination of options";
+          break;
+        }
+      return "";
+    }
+    ///Return the reason for the failure
+    Reason reason() const {return _reason; }
+  };
+
+
+  ///Command line arguments parser
+
+  ///\ingroup misc
+  ///Command line arguments parser.
+  ///
+  ///For a complete example see the \ref arg_parser_demo.cc demo file.
+  class ArgParser {
+
+    static void _showHelp(void *p);
+  protected:
+
+    int _argc;
+    const char * const *_argv;
+
+    enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
+
+    class ParData {
+    public:
+      union {
+        bool *bool_p;
+        int *int_p;
+        double *double_p;
+        std::string *string_p;
+        struct {
+          void (*p)(void *);
+          void *data;
+        } func_p;
+
+      };
+      std::string help;
+      bool mandatory;
+      OptType type;
+      bool set;
+      bool ingroup;
+      bool has_syn;
+      bool syn;
+      bool self_delete;
+      ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
+                  has_syn(false), syn(false), self_delete(false) {}
+    };
+
+    typedef std::map<std::string,ParData> Opts;
+    Opts _opts;
+
+    class GroupData
+    {
+    public:
+      typedef std::list<std::string> Opts;
+      Opts opts;
+      bool only_one;
+      bool mandatory;
+      GroupData() :only_one(false), mandatory(false) {}
+    };
+
+    typedef std::map<std::string,GroupData> Groups;
+    Groups _groups;
+
+    struct OtherArg
+    {
+      std::string name;
+      std::string help;
+      OtherArg(std::string n, std::string h) :name(n), help(h) {}
+
+    };
+
+    std::vector<OtherArg> _others_help;
+    std::vector<std::string> _file_args;
+    std::string _command_name;
+
+
+  private:
+    //Bind a function to an option.
+
+    //\param name The name of the option. The leading '-' must be omitted.
+    //\param help A help string.
+    //\retval func The function to be called when the option is given. It
+    //  must be of type "void f(void *)"
+    //\param data Data to be passed to \c func
+    ArgParser &funcOption(const std::string &name,
+                    const std::string &help,
+                    void (*func)(void *),void *data);
+
+    bool _exit_on_problems;
+
+    void _terminate(ArgParserException::Reason reason) const;
+
+  public:
+
+    ///Constructor
+    ArgParser(int argc, const char * const *argv);
+
+    ~ArgParser();
+
+    ///\name Options
+    ///
+
+    ///@{
+
+    ///Add a new integer type option
+
+    ///Add a new integer type option.
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\param value A default value for the option.
+    ///\param obl Indicate if the option is mandatory.
+    ArgParser &intOption(const std::string &name,
+                    const std::string &help,
+                    int value=0, bool obl=false);
+
+    ///Add a new floating point type option
+
+    ///Add a new floating point type option.
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\param value A default value for the option.
+    ///\param obl Indicate if the option is mandatory.
+    ArgParser &doubleOption(const std::string &name,
+                      const std::string &help,
+                      double value=0, bool obl=false);
+
+    ///Add a new bool type option
+
+    ///Add a new bool type option.
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\param value A default value for the option.
+    ///\param obl Indicate if the option is mandatory.
+    ///\note A mandatory bool obtion is of very little use.
+    ArgParser &boolOption(const std::string &name,
+                      const std::string &help,
+                      bool value=false, bool obl=false);
+
+    ///Add a new string type option
+
+    ///Add a new string type option.
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\param value A default value for the option.
+    ///\param obl Indicate if the option is mandatory.
+    ArgParser &stringOption(const std::string &name,
+                      const std::string &help,
+                      std::string value="", bool obl=false);
+
+    ///Give help string for non-parsed arguments.
+
+    ///With this function you can give help string for non-parsed arguments.
+    ///The parameter \c name will be printed in the short usage line, while
+    ///\c help gives a more detailed description.
+    ArgParser &other(const std::string &name,
+                     const std::string &help="");
+
+    ///@}
+
+    ///\name Options with External Storage
+    ///Using this functions, the value of the option will be directly written
+    ///into a variable once the option appears in the command line.
+
+    ///@{
+
+    ///Add a new integer type option with a storage reference
+
+    ///Add a new integer type option with a storage reference.
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\param obl Indicate if the option is mandatory.
+    ///\retval ref The value of the argument will be written to this variable.
+    ArgParser &refOption(const std::string &name,
+                    const std::string &help,
+                    int &ref, bool obl=false);
+
+    ///Add a new floating type option with a storage reference
+
+    ///Add a new floating type option with a storage reference.
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\param obl Indicate if the option is mandatory.
+    ///\retval ref The value of the argument will be written to this variable.
+    ArgParser &refOption(const std::string &name,
+                      const std::string &help,
+                      double &ref, bool obl=false);
+
+    ///Add a new bool type option with a storage reference
+
+    ///Add a new bool type option with a storage reference.
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\param obl Indicate if the option is mandatory.
+    ///\retval ref The value of the argument will be written to this variable.
+    ///\note A mandatory bool obtion is of very little use.
+    ArgParser &refOption(const std::string &name,
+                      const std::string &help,
+                      bool &ref, bool obl=false);
+
+    ///Add a new string type option with a storage reference
+
+    ///Add a new string type option with a storage reference.
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\param obl Indicate if the option is mandatory.
+    ///\retval ref The value of the argument will be written to this variable.
+    ArgParser &refOption(const std::string &name,
+                      const std::string &help,
+                      std::string &ref, bool obl=false);
+
+    ///@}
+
+    ///\name Option Groups and Synonyms
+    ///
+
+    ///@{
+
+    ///Bundle some options into a group
+
+    /// You can group some option by calling this function repeatedly for each
+    /// option to be grouped with the same groupname.
+    ///\param group The group name.
+    ///\param opt The option name.
+    ArgParser &optionGroup(const std::string &group,
+                           const std::string &opt);
+
+    ///Make the members of a group exclusive
+
+    ///If you call this function for a group, than at most one of them can be
+    ///given at the same time.
+    ArgParser &onlyOneGroup(const std::string &group);
+
+    ///Make a group mandatory
+
+    ///Using this function, at least one of the members of \c group
+    ///must be given.
+    ArgParser &mandatoryGroup(const std::string &group);
+
+    ///Create synonym to an option
+
+    ///With this function you can create a synonym \c syn of the
+    ///option \c opt.
+    ArgParser &synonym(const std::string &syn,
+                           const std::string &opt);
+
+    ///@}
+
+  private:
+    void show(std::ostream &os,Opts::const_iterator i) const;
+    void show(std::ostream &os,Groups::const_iterator i) const;
+    void showHelp(Opts::const_iterator i) const;
+    void showHelp(std::vector<OtherArg>::const_iterator i) const;
+
+    void unknownOpt(std::string arg) const;
+
+    void requiresValue(std::string arg, OptType t) const;
+    void checkMandatories() const;
+
+    void shortHelp() const;
+    void showHelp() const;
+  public:
+
+    ///Start the parsing process
+    ArgParser &parse();
+
+    /// Synonym for parse()
+    ArgParser &run()
+    {
+      return parse();
+    }
+
+    ///Give back the command name (the 0th argument)
+    const std::string &commandName() const { return _command_name; }
+
+    ///Check if an opion has been given to the command.
+    bool given(std::string op) const
+    {
+      Opts::const_iterator i = _opts.find(op);
+      return i!=_opts.end()?i->second.set:false;
+    }
+
+
+    ///Magic type for operator[]
+
+    ///This is the type of the return value of ArgParser::operator[]().
+    ///It automatically converts to \c int, \c double, \c bool or
+    ///\c std::string if the type of the option matches, which is checked
+    ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
+    ///type checking).
+    class RefType
+    {
+      const ArgParser &_parser;
+      std::string _name;
+    public:
+      ///\e
+      RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
+      ///\e
+      operator bool()
+      {
+        Opts::const_iterator i = _parser._opts.find(_name);
+        LEMON_ASSERT(i!=_parser._opts.end(),
+                     std::string()+"Unkown option: '"+_name+"'");
+        LEMON_ASSERT(i->second.type==ArgParser::BOOL,
+                     std::string()+"'"+_name+"' is a bool option");
+        return *(i->second.bool_p);
+      }
+      ///\e
+      operator std::string()
+      {
+        Opts::const_iterator i = _parser._opts.find(_name);
+        LEMON_ASSERT(i!=_parser._opts.end(),
+                     std::string()+"Unkown option: '"+_name+"'");
+        LEMON_ASSERT(i->second.type==ArgParser::STRING,
+                     std::string()+"'"+_name+"' is a string option");
+        return *(i->second.string_p);
+      }
+      ///\e
+      operator double()
+      {
+        Opts::const_iterator i = _parser._opts.find(_name);
+        LEMON_ASSERT(i!=_parser._opts.end(),
+                     std::string()+"Unkown option: '"+_name+"'");
+        LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
+                     i->second.type==ArgParser::INTEGER,
+                     std::string()+"'"+_name+"' is a floating point option");
+        return i->second.type==ArgParser::DOUBLE ?
+          *(i->second.double_p) : *(i->second.int_p);
+      }
+      ///\e
+      operator int()
+      {
+        Opts::const_iterator i = _parser._opts.find(_name);
+        LEMON_ASSERT(i!=_parser._opts.end(),
+                     std::string()+"Unkown option: '"+_name+"'");
+        LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
+                     std::string()+"'"+_name+"' is an integer option");
+        return *(i->second.int_p);
+      }
+
+    };
+
+    ///Give back the value of an option
+
+    ///Give back the value of an option.
+    ///\sa RefType
+    RefType operator[](const std::string &n) const
+    {
+      return RefType(*this, n);
+    }
+
+    ///Give back the non-option type arguments.
+
+    ///Give back a reference to a vector consisting of the program arguments
+    ///not starting with a '-' character.
+    const std::vector<std::string> &files() const { return _file_args; }
+
+    ///Throw instead of exit in case of problems
+    void throwOnProblems()
+    {
+      _exit_on_problems=false;
+    }
+  };
+}
+
+#endif // LEMON_ARG_PARSER_H
diff --git a/lemon/assert.h b/lemon/assert.h
new file mode 100644
index 0000000..f6c1dfc
--- /dev/null
+++ b/lemon/assert.h
@@ -0,0 +1,214 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_ASSERT_H
+#define LEMON_ASSERT_H
+
+/// \ingroup exceptions
+/// \file
+/// \brief Extended assertion handling
+
+#include <lemon/error.h>
+
+namespace lemon {
+
+  inline void assert_fail_abort(const char *file, int line,
+                                const char *function, const char* message,
+                                const char *assertion)
+  {
+    std::cerr << file << ":" << line << ": ";
+    if (function)
+      std::cerr << function << ": ";
+    std::cerr << message;
+    if (assertion)
+      std::cerr << " (assertion '" << assertion << "' failed)";
+    std::cerr << std::endl;
+    std::abort();
+  }
+
+  namespace _assert_bits {
+
+
+    inline const char* cstringify(const std::string& str) {
+      return str.c_str();
+    }
+
+    inline const char* cstringify(const char* str) {
+      return str;
+    }
+  }
+}
+
+#endif // LEMON_ASSERT_H
+
+#undef LEMON_ASSERT
+#undef LEMON_DEBUG
+
+#if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
+  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
+#error "LEMON assertion system is not set properly"
+#endif
+
+#if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
+     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||     \
+     defined(LEMON_ENABLE_ASSERTS)) &&                  \
+  (defined(LEMON_DISABLE_ASSERTS) ||                    \
+   defined(NDEBUG))
+#error "LEMON assertion system is not set properly"
+#endif
+
+
+#if defined LEMON_ASSERT_ABORT
+#  undef LEMON_ASSERT_HANDLER
+#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
+#elif defined LEMON_ASSERT_CUSTOM
+#  undef LEMON_ASSERT_HANDLER
+#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
+#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
+#  endif
+#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
+#elif defined LEMON_DISABLE_ASSERTS
+#  undef LEMON_ASSERT_HANDLER
+#elif defined NDEBUG
+#  undef LEMON_ASSERT_HANDLER
+#else
+#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
+#endif
+
+#ifndef LEMON_FUNCTION_NAME
+#  if defined __GNUC__
+#    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
+#  elif defined _MSC_VER
+#    define LEMON_FUNCTION_NAME (__FUNCSIG__)
+#  elif __STDC_VERSION__ >= 199901L
+#    define LEMON_FUNCTION_NAME (__func__)
+#  else
+#    define LEMON_FUNCTION_NAME ("<unknown>")
+#  endif
+#endif
+
+#ifdef DOXYGEN
+
+/// \ingroup exceptions
+///
+/// \brief Macro for assertion with customizable message
+///
+/// Macro for assertion with customizable message.
+/// \param exp An expression that must be convertible to \c bool.  If it is \c
+/// false, then an assertion is raised. The concrete behaviour depends on the
+/// settings of the assertion system.
+/// \param msg A <tt>const char*</tt> parameter, which can be used to provide
+/// information about the circumstances of the failed assertion.
+///
+/// The assertions are enabled in the default behaviour.
+/// You can disable them with the following code:
+/// \code
+/// #define LEMON_DISABLE_ASSERTS
+/// \endcode
+/// or with compilation parameters:
+/// \code
+/// g++ -DLEMON_DISABLE_ASSERTS
+/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
+/// \endcode
+/// The checking is also disabled when the standard macro \c NDEBUG is defined.
+///
+/// As a default behaviour the failed assertion prints a short log message to
+/// the standard error and aborts the execution.
+///
+/// However, the following modes can be used in the assertion system:
+/// - \c LEMON_ASSERT_ABORT The failed assertion prints a short log message to
+///   the standard error and aborts the program. It is the default behaviour.
+/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
+///   function.
+///   \code
+///     void custom_assert_handler(const char* file, int line,
+///                                const char* function, const char* message,
+///                                const char* assertion);
+///   \endcode
+///   The name of the function should be defined as the \c
+///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
+///   \code
+///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
+///   \endcode
+///   Whenever an assertion is occured, the custom assertion
+///   handler is called with appropiate parameters.
+///
+/// The assertion mode can also be changed within one compilation unit.
+/// If the macros are redefined with other settings and the
+/// \ref lemon/assert.h "assert.h" file is reincluded, then the
+/// behaviour is changed appropiately to the new settings.
+#  define LEMON_ASSERT(exp, msg)                                        \
+  (static_cast<void> (!!(exp) ? 0 : (                                   \
+    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
+                         LEMON_FUNCTION_NAME,                           \
+                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
+
+/// \ingroup exceptions
+///
+/// \brief Macro for internal assertions
+///
+/// Macro for internal assertions, it is used in the library to check
+/// the consistency of results of algorithms, several pre- and
+/// postconditions and invariants. The checking is disabled by
+/// default, but it can be turned on with the macro \c
+/// LEMON_ENABLE_DEBUG.
+/// \code
+/// #define LEMON_ENABLE_DEBUG
+/// \endcode
+/// or with compilation parameters:
+/// \code
+/// g++ -DLEMON_ENABLE_DEBUG
+/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
+/// \endcode
+///
+/// This macro works like the \c LEMON_ASSERT macro, therefore the
+/// current behaviour depends on the settings of \c LEMON_ASSERT
+/// macro.
+///
+/// \see LEMON_ASSERT
+#  define LEMON_DEBUG(exp, msg)                                         \
+  (static_cast<void> (!!(exp) ? 0 : (                                   \
+    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
+                         LEMON_FUNCTION_NAME,                           \
+                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
+
+#else
+
+#  ifndef LEMON_ASSERT_HANDLER
+#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
+#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
+#  else
+#    define LEMON_ASSERT(exp, msg)                                      \
+       (static_cast<void> (!!(exp) ? 0 : (                              \
+        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
+                             LEMON_FUNCTION_NAME,                       \
+                             ::lemon::_assert_bits::cstringify(msg),    \
+                             #exp), 0)))
+#    if defined LEMON_ENABLE_DEBUG
+#      define LEMON_DEBUG(exp, msg)                                     \
+         (static_cast<void> (!!(exp) ? 0 : (                            \
+           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
+                                LEMON_FUNCTION_NAME,                    \
+                                ::lemon::_assert_bits::cstringify(msg), \
+                                #exp), 0)))
+#    else
+#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
+#    endif
+#  endif
+
+#endif
diff --git a/lemon/base.cc b/lemon/base.cc
new file mode 100644
index 0000000..a057b41
--- /dev/null
+++ b/lemon/base.cc
@@ -0,0 +1,37 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Some basic non-inline functions and static global data.
+
+#include<lemon/tolerance.h>
+#include<lemon/core.h>
+#include<lemon/time_measure.h>
+namespace lemon {
+
+  float Tolerance<float>::def_epsilon = static_cast<float>(1e-4);
+  double Tolerance<double>::def_epsilon = 1e-10;
+  long double Tolerance<long double>::def_epsilon = 1e-14;
+
+#ifndef LEMON_ONLY_TEMPLATES
+  const Invalid INVALID = Invalid();
+#endif
+
+  TimeStamp::Format TimeStamp::_format = TimeStamp::NORMAL;
+
+} //namespace lemon
diff --git a/lemon/bellman_ford.h b/lemon/bellman_ford.h
new file mode 100644
index 0000000..310758e
--- /dev/null
+++ b/lemon/bellman_ford.h
@@ -0,0 +1,1116 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BELLMAN_FORD_H
+#define LEMON_BELLMAN_FORD_H
+
+/// \ingroup shortest_path
+/// \file
+/// \brief Bellman-Ford algorithm.
+
+#include <lemon/list_graph.h>
+#include <lemon/bits/path_dump.h>
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+
+#include <limits>
+
+namespace lemon {
+
+  /// \brief Default OperationTraits for the BellmanFord algorithm class.
+  ///
+  /// This operation traits class defines all computational operations
+  /// and constants that are used in the Bellman-Ford algorithm.
+  /// The default implementation is based on the \c numeric_limits class.
+  /// If the numeric type does not have infinity value, then the maximum
+  /// value is used as extremal infinity value.
+  template <
+    typename V,
+    bool has_inf = std::numeric_limits<V>::has_infinity>
+  struct BellmanFordDefaultOperationTraits {
+    /// \e
+    typedef V Value;
+    /// \brief Gives back the zero value of the type.
+    static Value zero() {
+      return static_cast<Value>(0);
+    }
+    /// \brief Gives back the positive infinity value of the type.
+    static Value infinity() {
+      return std::numeric_limits<Value>::infinity();
+    }
+    /// \brief Gives back the sum of the given two elements.
+    static Value plus(const Value& left, const Value& right) {
+      return left + right;
+    }
+    /// \brief Gives back \c true only if the first value is less than
+    /// the second.
+    static bool less(const Value& left, const Value& right) {
+      return left < right;
+    }
+  };
+
+  template <typename V>
+  struct BellmanFordDefaultOperationTraits<V, false> {
+    typedef V Value;
+    static Value zero() {
+      return static_cast<Value>(0);
+    }
+    static Value infinity() {
+      return std::numeric_limits<Value>::max();
+    }
+    static Value plus(const Value& left, const Value& right) {
+      if (left == infinity() || right == infinity()) return infinity();
+      return left + right;
+    }
+    static bool less(const Value& left, const Value& right) {
+      return left < right;
+    }
+  };
+
+  /// \brief Default traits class of BellmanFord class.
+  ///
+  /// Default traits class of BellmanFord class.
+  /// \param GR The type of the digraph.
+  /// \param LEN The type of the length map.
+  template<typename GR, typename LEN>
+  struct BellmanFordDefaultTraits {
+    /// The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc lengths.
+    ///
+    /// The type of the map that stores the arc lengths.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LEN LengthMap;
+
+    /// The type of the arc lengths.
+    typedef typename LEN::Value Value;
+
+    /// \brief Operation traits for Bellman-Ford algorithm.
+    ///
+    /// It defines the used operations and the infinity value for the
+    /// given \c Value type.
+    /// \see BellmanFordDefaultOperationTraits
+    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
+
+    /// \brief The type of the map that stores the last arcs of the
+    /// shortest paths.
+    ///
+    /// The type of the map that stores the last
+    /// arcs of the shortest paths.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
+
+    /// \brief Instantiates a \c PredMap.
+    ///
+    /// This function instantiates a \ref PredMap.
+    /// \param g is the digraph to which we would like to define the
+    /// \ref PredMap.
+    static PredMap *createPredMap(const GR& g) {
+      return new PredMap(g);
+    }
+
+    /// \brief The type of the map that stores the distances of the nodes.
+    ///
+    /// The type of the map that stores the distances of the nodes.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
+
+    /// \brief Instantiates a \c DistMap.
+    ///
+    /// This function instantiates a \ref DistMap.
+    /// \param g is the digraph to which we would like to define the
+    /// \ref DistMap.
+    static DistMap *createDistMap(const GR& g) {
+      return new DistMap(g);
+    }
+
+  };
+
+  /// \brief %BellmanFord algorithm class.
+  ///
+  /// \ingroup shortest_path
+  /// This class provides an efficient implementation of the Bellman-Ford
+  /// algorithm. The maximum time complexity of the algorithm is
+  /// <tt>O(nm)</tt>.
+  ///
+  /// The Bellman-Ford algorithm solves the single-source shortest path
+  /// problem when the arcs can have negative lengths, but the digraph
+  /// should not contain directed cycles with negative total length.
+  /// If all arc costs are non-negative, consider to use the Dijkstra
+  /// algorithm instead, since it is more efficient.
+  ///
+  /// The arc lengths are passed to the algorithm using a
+  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
+  /// kind of length. The type of the length values is determined by the
+  /// \ref concepts::ReadMap::Value "Value" type of the length map.
+  ///
+  /// There is also a \ref bellmanFord() "function-type interface" for the
+  /// Bellman-Ford algorithm, which is convenient in the simplier cases and
+  /// it can be used easier.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// The default type is \ref ListDigraph.
+  /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
+  /// the lengths of the arcs. The default map type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref BellmanFordDefaultTraits
+  /// "BellmanFordDefaultTraits<GR, LEN>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN, typename TR>
+#else
+  template <typename GR=ListDigraph,
+            typename LEN=typename GR::template ArcMap<int>,
+            typename TR=BellmanFordDefaultTraits<GR,LEN> >
+#endif
+  class BellmanFord {
+  public:
+
+    ///The type of the underlying digraph.
+    typedef typename TR::Digraph Digraph;
+
+    /// \brief The type of the arc lengths.
+    typedef typename TR::LengthMap::Value Value;
+    /// \brief The type of the map that stores the arc lengths.
+    typedef typename TR::LengthMap LengthMap;
+    /// \brief The type of the map that stores the last
+    /// arcs of the shortest paths.
+    typedef typename TR::PredMap PredMap;
+    /// \brief The type of the map that stores the distances of the nodes.
+    typedef typename TR::DistMap DistMap;
+    /// The type of the paths.
+    typedef PredMapPath<Digraph, PredMap> Path;
+    ///\brief The \ref lemon::BellmanFordDefaultOperationTraits
+    /// "operation traits class" of the algorithm.
+    typedef typename TR::OperationTraits OperationTraits;
+
+    ///\brief The \ref lemon::BellmanFordDefaultTraits "traits class"
+    ///of the algorithm.
+    typedef TR Traits;
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    // Pointer to the underlying digraph.
+    const Digraph *_gr;
+    // Pointer to the length map
+    const LengthMap *_length;
+    // Pointer to the map of predecessors arcs.
+    PredMap *_pred;
+    // Indicates if _pred is locally allocated (true) or not.
+    bool _local_pred;
+    // Pointer to the map of distances.
+    DistMap *_dist;
+    // Indicates if _dist is locally allocated (true) or not.
+    bool _local_dist;
+
+    typedef typename Digraph::template NodeMap<bool> MaskMap;
+    MaskMap *_mask;
+
+    std::vector<Node> _process;
+
+    // Creates the maps if necessary.
+    void create_maps() {
+      if(!_pred) {
+        _local_pred = true;
+        _pred = Traits::createPredMap(*_gr);
+      }
+      if(!_dist) {
+        _local_dist = true;
+        _dist = Traits::createDistMap(*_gr);
+      }
+      if(!_mask) {
+        _mask = new MaskMap(*_gr);
+      }
+    }
+
+  public :
+
+    typedef BellmanFord Create;
+
+    /// \name Named Template Parameters
+
+    ///@{
+
+    template <class T>
+    struct SetPredMapTraits : public Traits {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph&) {
+        LEMON_ASSERT(false, "PredMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c PredMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c PredMap type.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetPredMap
+      : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
+      typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetDistMapTraits : public Traits {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph&) {
+        LEMON_ASSERT(false, "DistMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c DistMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c DistMap type.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetDistMap
+      : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
+      typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetOperationTraitsTraits : public Traits {
+      typedef T OperationTraits;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c OperationTraits type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c OperationTraits type.
+    /// For more information, see \ref BellmanFordDefaultOperationTraits.
+    template <class T>
+    struct SetOperationTraits
+      : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
+      typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
+      Create;
+    };
+
+    ///@}
+
+  protected:
+
+    BellmanFord() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param g The digraph the algorithm runs on.
+    /// \param length The length map used by the algorithm.
+    BellmanFord(const Digraph& g, const LengthMap& length) :
+      _gr(&g), _length(&length),
+      _pred(0), _local_pred(false),
+      _dist(0), _local_dist(false), _mask(0) {}
+
+    ///Destructor.
+    ~BellmanFord() {
+      if(_local_pred) delete _pred;
+      if(_local_dist) delete _dist;
+      if(_mask) delete _mask;
+    }
+
+    /// \brief Sets the length map.
+    ///
+    /// Sets the length map.
+    /// \return <tt>(*this)</tt>
+    BellmanFord &lengthMap(const LengthMap &map) {
+      _length = ↦
+      return *this;
+    }
+
+    /// \brief Sets the map that stores the predecessor arcs.
+    ///
+    /// Sets the map that stores the predecessor arcs.
+    /// If you don't use this function before calling \ref run()
+    /// or \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    BellmanFord &predMap(PredMap &map) {
+      if(_local_pred) {
+        delete _pred;
+        _local_pred=false;
+      }
+      _pred = ↦
+      return *this;
+    }
+
+    /// \brief Sets the map that stores the distances of the nodes.
+    ///
+    /// Sets the map that stores the distances of the nodes calculated
+    /// by the algorithm.
+    /// If you don't use this function before calling \ref run()
+    /// or \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    BellmanFord &distMap(DistMap &map) {
+      if(_local_dist) {
+        delete _dist;
+        _local_dist=false;
+      }
+      _dist = ↦
+      return *this;
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the Bellman-Ford algorithm is to use
+    /// one of the member functions called \ref run().\n
+    /// If you need better control on the execution, you have to call
+    /// \ref init() first, then you can add several source nodes
+    /// with \ref addSource(). Finally the actual path computation can be
+    /// performed with \ref start(), \ref checkedStart() or
+    /// \ref limitedStart().
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures. The optional parameter
+    /// is the initial distance of each node.
+    void init(const Value value = OperationTraits::infinity()) {
+      create_maps();
+      for (NodeIt it(*_gr); it != INVALID; ++it) {
+        _pred->set(it, INVALID);
+        _dist->set(it, value);
+      }
+      _process.clear();
+      if (OperationTraits::less(value, OperationTraits::infinity())) {
+        for (NodeIt it(*_gr); it != INVALID; ++it) {
+          _process.push_back(it);
+          _mask->set(it, true);
+        }
+      } else {
+        for (NodeIt it(*_gr); it != INVALID; ++it) {
+          _mask->set(it, false);
+        }
+      }
+    }
+
+    /// \brief Adds a new source node.
+    ///
+    /// This function adds a new source node. The optional second parameter
+    /// is the initial distance of the node.
+    void addSource(Node source, Value dst = OperationTraits::zero()) {
+      _dist->set(source, dst);
+      if (!(*_mask)[source]) {
+        _process.push_back(source);
+        _mask->set(source, true);
+      }
+    }
+
+    /// \brief Executes one round from the Bellman-Ford algorithm.
+    ///
+    /// If the algoritm calculated the distances in the previous round
+    /// exactly for the paths of at most \c k arcs, then this function
+    /// will calculate the distances exactly for the paths of at most
+    /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
+    /// calculates the shortest path distances exactly for the paths
+    /// consisting of at most \c k arcs.
+    ///
+    /// \warning The paths with limited arc number cannot be retrieved
+    /// easily with \ref path() or \ref predArc() functions. If you also
+    /// need the shortest paths and not only the distances, you should
+    /// store the \ref predMap() "predecessor map" after each iteration
+    /// and build the path manually.
+    ///
+    /// \return \c true when the algorithm have not found more shorter
+    /// paths.
+    ///
+    /// \see ActiveIt
+    bool processNextRound() {
+      for (int i = 0; i < int(_process.size()); ++i) {
+        _mask->set(_process[i], false);
+      }
+      std::vector<Node> nextProcess;
+      std::vector<Value> values(_process.size());
+      for (int i = 0; i < int(_process.size()); ++i) {
+        values[i] = (*_dist)[_process[i]];
+      }
+      for (int i = 0; i < int(_process.size()); ++i) {
+        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
+          Node target = _gr->target(it);
+          Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
+          if (OperationTraits::less(relaxed, (*_dist)[target])) {
+            _pred->set(target, it);
+            _dist->set(target, relaxed);
+            if (!(*_mask)[target]) {
+              _mask->set(target, true);
+              nextProcess.push_back(target);
+            }
+          }
+        }
+      }
+      _process.swap(nextProcess);
+      return _process.empty();
+    }
+
+    /// \brief Executes one weak round from the Bellman-Ford algorithm.
+    ///
+    /// If the algorithm calculated the distances in the previous round
+    /// at least for the paths of at most \c k arcs, then this function
+    /// will calculate the distances at least for the paths of at most
+    /// <tt>k+1</tt> arcs.
+    /// This function does not make it possible to calculate the shortest
+    /// path distances exactly for paths consisting of at most \c k arcs,
+    /// this is why it is called weak round.
+    ///
+    /// \return \c true when the algorithm have not found more shorter
+    /// paths.
+    ///
+    /// \see ActiveIt
+    bool processNextWeakRound() {
+      for (int i = 0; i < int(_process.size()); ++i) {
+        _mask->set(_process[i], false);
+      }
+      std::vector<Node> nextProcess;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
+          Node target = _gr->target(it);
+          Value relaxed =
+            OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
+          if (OperationTraits::less(relaxed, (*_dist)[target])) {
+            _pred->set(target, it);
+            _dist->set(target, relaxed);
+            if (!(*_mask)[target]) {
+              _mask->set(target, true);
+              nextProcess.push_back(target);
+            }
+          }
+        }
+      }
+      _process.swap(nextProcess);
+      return _process.empty();
+    }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the root node(s)
+    /// in order to compute the shortest path to each node.
+    ///
+    /// The algorithm computes
+    /// - the shortest path tree (forest),
+    /// - the distance of each node from the root(s).
+    ///
+    /// \pre init() must be called and at least one root node should be
+    /// added with addSource() before using this function.
+    void start() {
+      int num = countNodes(*_gr) - 1;
+      for (int i = 0; i < num; ++i) {
+        if (processNextWeakRound()) break;
+      }
+    }
+
+    /// \brief Executes the algorithm and checks the negative cycles.
+    ///
+    /// Executes the algorithm and checks the negative cycles.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the root node(s)
+    /// in order to compute the shortest path to each node and also checks
+    /// if the digraph contains cycles with negative total length.
+    ///
+    /// The algorithm computes
+    /// - the shortest path tree (forest),
+    /// - the distance of each node from the root(s).
+    ///
+    /// \return \c false if there is a negative cycle in the digraph.
+    ///
+    /// \pre init() must be called and at least one root node should be
+    /// added with addSource() before using this function.
+    bool checkedStart() {
+      int num = countNodes(*_gr);
+      for (int i = 0; i < num; ++i) {
+        if (processNextWeakRound()) return true;
+      }
+      return _process.empty();
+    }
+
+    /// \brief Executes the algorithm with arc number limit.
+    ///
+    /// Executes the algorithm with arc number limit.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the root node(s)
+    /// in order to compute the shortest path distance for each node
+    /// using only the paths consisting of at most \c num arcs.
+    ///
+    /// The algorithm computes
+    /// - the limited distance of each node from the root(s),
+    /// - the predecessor arc for each node.
+    ///
+    /// \warning The paths with limited arc number cannot be retrieved
+    /// easily with \ref path() or \ref predArc() functions. If you also
+    /// need the shortest paths and not only the distances, you should
+    /// store the \ref predMap() "predecessor map" after each iteration
+    /// and build the path manually.
+    ///
+    /// \pre init() must be called and at least one root node should be
+    /// added with addSource() before using this function.
+    void limitedStart(int num) {
+      for (int i = 0; i < num; ++i) {
+        if (processNextRound()) break;
+      }
+    }
+
+    /// \brief Runs the algorithm from the given root node.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the given root
+    /// node \c s in order to compute the shortest path to each node.
+    ///
+    /// The algorithm computes
+    /// - the shortest path tree (forest),
+    /// - the distance of each node from the root(s).
+    ///
+    /// \note bf.run(s) is just a shortcut of the following code.
+    /// \code
+    ///   bf.init();
+    ///   bf.addSource(s);
+    ///   bf.start();
+    /// \endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    /// \brief Runs the algorithm from the given root node with arc
+    /// number limit.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the given root
+    /// node \c s in order to compute the shortest path distance for each
+    /// node using only the paths consisting of at most \c num arcs.
+    ///
+    /// The algorithm computes
+    /// - the limited distance of each node from the root(s),
+    /// - the predecessor arc for each node.
+    ///
+    /// \warning The paths with limited arc number cannot be retrieved
+    /// easily with \ref path() or \ref predArc() functions. If you also
+    /// need the shortest paths and not only the distances, you should
+    /// store the \ref predMap() "predecessor map" after each iteration
+    /// and build the path manually.
+    ///
+    /// \note bf.run(s, num) is just a shortcut of the following code.
+    /// \code
+    ///   bf.init();
+    ///   bf.addSource(s);
+    ///   bf.limitedStart(num);
+    /// \endcode
+    void run(Node s, int num) {
+      init();
+      addSource(s);
+      limitedStart(num);
+    }
+
+    ///@}
+
+    /// \brief LEMON iterator for getting the active nodes.
+    ///
+    /// This class provides a common style LEMON iterator that traverses
+    /// the active nodes of the Bellman-Ford algorithm after the last
+    /// phase. These nodes should be checked in the next phase to
+    /// find augmenting arcs outgoing from them.
+    class ActiveIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor for getting the active nodes of the given BellmanFord
+      /// instance.
+      ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_process.size() - 1;
+      }
+
+      /// \brief Invalid constructor.
+      ///
+      /// Invalid constructor.
+      ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
+
+      /// \brief Conversion to \c Node.
+      ///
+      /// Conversion to \c Node.
+      operator Node() const {
+        return _index >= 0 ? _algorithm->_process[_index] : INVALID;
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      ActiveIt& operator++() {
+        --_index;
+        return *this;
+      }
+
+      bool operator==(const ActiveIt& it) const {
+        return static_cast<Node>(*this) == static_cast<Node>(it);
+      }
+      bool operator!=(const ActiveIt& it) const {
+        return static_cast<Node>(*this) != static_cast<Node>(it);
+      }
+      bool operator<(const ActiveIt& it) const {
+        return static_cast<Node>(*this) < static_cast<Node>(it);
+      }
+
+    private:
+      const BellmanFord* _algorithm;
+      int _index;
+    };
+
+    /// \name Query Functions
+    /// The result of the Bellman-Ford algorithm can be obtained using these
+    /// functions.\n
+    /// Either \ref run() or \ref init() should be called before using them.
+
+    ///@{
+
+    /// \brief The shortest path to the given node.
+    ///
+    /// Gives back the shortest path to the given node from the root(s).
+    ///
+    /// \warning \c t should be reached from the root(s).
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Path path(Node t) const
+    {
+      return Path(*_gr, *_pred, t);
+    }
+
+    /// \brief The distance of the given node from the root(s).
+    ///
+    /// Returns the distance of the given node from the root(s).
+    ///
+    /// \warning If node \c v is not reached from the root(s), then
+    /// the return value of this function is undefined.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value dist(Node v) const { return (*_dist)[v]; }
+
+    /// \brief Returns the 'previous arc' of the shortest path tree for
+    /// the given node.
+    ///
+    /// This function returns the 'previous arc' of the shortest path
+    /// tree for node \c v, i.e. it returns the last arc of a
+    /// shortest path from a root to \c v. It is \c INVALID if \c v
+    /// is not reached from the root(s) or if \c v is a root.
+    ///
+    /// The shortest path tree used here is equal to the shortest path
+    /// tree used in \ref predNode() and \ref predMap().
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Arc predArc(Node v) const { return (*_pred)[v]; }
+
+    /// \brief Returns the 'previous node' of the shortest path tree for
+    /// the given node.
+    ///
+    /// This function returns the 'previous node' of the shortest path
+    /// tree for node \c v, i.e. it returns the last but one node of
+    /// a shortest path from a root to \c v. It is \c INVALID if \c v
+    /// is not reached from the root(s) or if \c v is a root.
+    ///
+    /// The shortest path tree used here is equal to the shortest path
+    /// tree used in \ref predArc() and \ref predMap().
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Node predNode(Node v) const {
+      return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
+    }
+
+    /// \brief Returns a const reference to the node map that stores the
+    /// distances of the nodes.
+    ///
+    /// Returns a const reference to the node map that stores the distances
+    /// of the nodes calculated by the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const DistMap &distMap() const { return *_dist;}
+
+    /// \brief Returns a const reference to the node map that stores the
+    /// predecessor arcs.
+    ///
+    /// Returns a const reference to the node map that stores the predecessor
+    /// arcs, which form the shortest path tree (forest).
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const PredMap &predMap() const { return *_pred; }
+
+    /// \brief Checks if a node is reached from the root(s).
+    ///
+    /// Returns \c true if \c v is reached from the root(s).
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    bool reached(Node v) const {
+      return (*_dist)[v] != OperationTraits::infinity();
+    }
+
+    /// \brief Gives back a negative cycle.
+    ///
+    /// This function gives back a directed cycle with negative total
+    /// length if the algorithm has already found one.
+    /// Otherwise it gives back an empty path.
+    lemon::Path<Digraph> negativeCycle() const {
+      typename Digraph::template NodeMap<int> state(*_gr, -1);
+      lemon::Path<Digraph> cycle;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        if (state[_process[i]] != -1) continue;
+        for (Node v = _process[i]; (*_pred)[v] != INVALID;
+             v = _gr->source((*_pred)[v])) {
+          if (state[v] == i) {
+            cycle.addFront((*_pred)[v]);
+            for (Node u = _gr->source((*_pred)[v]); u != v;
+                 u = _gr->source((*_pred)[u])) {
+              cycle.addFront((*_pred)[u]);
+            }
+            return cycle;
+          }
+          else if (state[v] >= 0) {
+            break;
+          }
+          state[v] = i;
+        }
+      }
+      return cycle;
+    }
+
+    ///@}
+  };
+
+  /// \brief Default traits class of bellmanFord() function.
+  ///
+  /// Default traits class of bellmanFord() function.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
+  template <typename GR, typename LEN>
+  struct BellmanFordWizardDefaultTraits {
+    /// The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc lengths.
+    ///
+    /// The type of the map that stores the arc lengths.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LEN LengthMap;
+
+    /// The type of the arc lengths.
+    typedef typename LEN::Value Value;
+
+    /// \brief Operation traits for Bellman-Ford algorithm.
+    ///
+    /// It defines the used operations and the infinity value for the
+    /// given \c Value type.
+    /// \see BellmanFordDefaultOperationTraits
+    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
+
+    /// \brief The type of the map that stores the last
+    /// arcs of the shortest paths.
+    ///
+    /// The type of the map that stores the last arcs of the shortest paths.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
+
+    /// \brief Instantiates a \c PredMap.
+    ///
+    /// This function instantiates a \ref PredMap.
+    /// \param g is the digraph to which we would like to define the
+    /// \ref PredMap.
+    static PredMap *createPredMap(const GR &g) {
+      return new PredMap(g);
+    }
+
+    /// \brief The type of the map that stores the distances of the nodes.
+    ///
+    /// The type of the map that stores the distances of the nodes.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename GR::template NodeMap<Value> DistMap;
+
+    /// \brief Instantiates a \c DistMap.
+    ///
+    /// This function instantiates a \ref DistMap.
+    /// \param g is the digraph to which we would like to define the
+    /// \ref DistMap.
+    static DistMap *createDistMap(const GR &g) {
+      return new DistMap(g);
+    }
+
+    ///The type of the shortest paths.
+
+    ///The type of the shortest paths.
+    ///It must meet the \ref concepts::Path "Path" concept.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  /// \brief Default traits class used by BellmanFordWizard.
+  ///
+  /// Default traits class used by BellmanFordWizard.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
+  template <typename GR, typename LEN>
+  class BellmanFordWizardBase
+    : public BellmanFordWizardDefaultTraits<GR, LEN> {
+
+    typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
+  protected:
+    // Type of the nodes in the digraph.
+    typedef typename Base::Digraph::Node Node;
+
+    // Pointer to the underlying digraph.
+    void *_graph;
+    // Pointer to the length map
+    void *_length;
+    // Pointer to the map of predecessors arcs.
+    void *_pred;
+    // Pointer to the map of distances.
+    void *_dist;
+    //Pointer to the shortest path to the target node.
+    void *_path;
+    //Pointer to the distance of the target node.
+    void *_di;
+
+    public:
+    /// Constructor.
+
+    /// This constructor does not require parameters, it initiates
+    /// all of the attributes to default values \c 0.
+    BellmanFordWizardBase() :
+      _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
+
+    /// Constructor.
+
+    /// This constructor requires two parameters,
+    /// others are initiated to \c 0.
+    /// \param gr The digraph the algorithm runs on.
+    /// \param len The length map.
+    BellmanFordWizardBase(const GR& gr,
+                          const LEN& len) :
+      _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
+      _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
+      _pred(0), _dist(0), _path(0), _di(0) {}
+
+  };
+
+  /// \brief Auxiliary class for the function-type interface of the
+  /// \ref BellmanFord "Bellman-Ford" algorithm.
+  ///
+  /// This auxiliary class is created to implement the
+  /// \ref bellmanFord() "function-type interface" of the
+  /// \ref BellmanFord "Bellman-Ford" algorithm.
+  /// It does not have own \ref run() method, it uses the
+  /// functions and features of the plain \ref BellmanFord.
+  ///
+  /// This class should only be used through the \ref bellmanFord()
+  /// function, which makes it easier to use the algorithm.
+  ///
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm.
+  template<class TR>
+  class BellmanFordWizard : public TR {
+    typedef TR Base;
+
+    typedef typename TR::Digraph Digraph;
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt ArcIt;
+
+    typedef typename TR::LengthMap LengthMap;
+    typedef typename LengthMap::Value Value;
+    typedef typename TR::PredMap PredMap;
+    typedef typename TR::DistMap DistMap;
+    typedef typename TR::Path Path;
+
+  public:
+    /// Constructor.
+    BellmanFordWizard() : TR() {}
+
+    /// \brief Constructor that requires parameters.
+    ///
+    /// Constructor that requires parameters.
+    /// These parameters will be the default values for the traits class.
+    /// \param gr The digraph the algorithm runs on.
+    /// \param len The length map.
+    BellmanFordWizard(const Digraph& gr, const LengthMap& len)
+      : TR(gr, len) {}
+
+    /// \brief Copy constructor
+    BellmanFordWizard(const TR &b) : TR(b) {}
+
+    ~BellmanFordWizard() {}
+
+    /// \brief Runs the Bellman-Ford algorithm from the given source node.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the given source
+    /// node in order to compute the shortest path to each node.
+    void run(Node s) {
+      BellmanFord<Digraph,LengthMap,TR>
+        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
+           *reinterpret_cast<const LengthMap*>(Base::_length));
+      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      bf.run(s);
+    }
+
+    /// \brief Runs the Bellman-Ford algorithm to find the shortest path
+    /// between \c s and \c t.
+    ///
+    /// This method runs the Bellman-Ford algorithm from node \c s
+    /// in order to compute the shortest path to node \c t.
+    /// Actually, it computes the shortest path to each node, but using
+    /// this function you can retrieve the distance and the shortest path
+    /// for a single target node easier.
+    ///
+    /// \return \c true if \c t is reachable form \c s.
+    bool run(Node s, Node t) {
+      BellmanFord<Digraph,LengthMap,TR>
+        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
+           *reinterpret_cast<const LengthMap*>(Base::_length));
+      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      bf.run(s);
+      if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
+      if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
+      return bf.reached(t);
+    }
+
+    template<class T>
+    struct SetPredMapBase : public Base {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &) { return 0; };
+      SetPredMapBase(const TR &b) : TR(b) {}
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// the predecessor map.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// the map that stores the predecessor arcs of the nodes.
+    template<class T>
+    BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
+      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BellmanFordWizard<SetPredMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetDistMapBase : public Base {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph &) { return 0; };
+      SetDistMapBase(const TR &b) : TR(b) {}
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// the distance map.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// the map that stores the distances of the nodes calculated
+    /// by the algorithm.
+    template<class T>
+    BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
+      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BellmanFordWizard<SetDistMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetPathBase : public Base {
+      typedef T Path;
+      SetPathBase(const TR &b) : TR(b) {}
+    };
+
+    /// \brief \ref named-func-param "Named parameter" for getting
+    /// the shortest path to the target node.
+    ///
+    /// \ref named-func-param "Named parameter" for getting
+    /// the shortest path to the target node.
+    template<class T>
+    BellmanFordWizard<SetPathBase<T> > path(const T &t)
+    {
+      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BellmanFordWizard<SetPathBase<T> >(*this);
+    }
+
+    /// \brief \ref named-func-param "Named parameter" for getting
+    /// the distance of the target node.
+    ///
+    /// \ref named-func-param "Named parameter" for getting
+    /// the distance of the target node.
+    BellmanFordWizard dist(const Value &d)
+    {
+      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
+      return *this;
+    }
+
+  };
+
+  /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
+  /// algorithm.
+  ///
+  /// \ingroup shortest_path
+  /// Function type interface for the \ref BellmanFord "Bellman-Ford"
+  /// algorithm.
+  ///
+  /// This function also has several \ref named-templ-func-param
+  /// "named parameters", they are declared as the members of class
+  /// \ref BellmanFordWizard.
+  /// The following examples show how to use these parameters.
+  /// \code
+  ///   // Compute shortest path from node s to each node
+  ///   bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
+  ///
+  ///   // Compute shortest path from s to t
+  ///   bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
+  /// \endcode
+  /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
+  /// to the end of the parameter list.
+  /// \sa BellmanFordWizard
+  /// \sa BellmanFord
+  template<typename GR, typename LEN>
+  BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
+  bellmanFord(const GR& digraph,
+              const LEN& length)
+  {
+    return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
+  }
+
+} //END OF NAMESPACE LEMON
+
+#endif
+
diff --git a/lemon/bfs.h b/lemon/bfs.h
new file mode 100644
index 0000000..e5f4e5c
--- /dev/null
+++ b/lemon/bfs.h
@@ -0,0 +1,1754 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_BFS_H
+#define LEMON_BFS_H
+
+///\ingroup search
+///\file
+///\brief BFS algorithm.
+
+#include <lemon/list_graph.h>
+#include <lemon/bits/path_dump.h>
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+
+namespace lemon {
+
+  ///Default traits class of Bfs class.
+
+  ///Default traits class of Bfs class.
+  ///\tparam GR Digraph type.
+  template<class GR>
+  struct BfsDefaultTraits
+  {
+    ///The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    ///\brief The type of the map that stores the predecessor
+    ///arcs of the shortest paths.
+    ///
+    ///The type of the map that stores the predecessor
+    ///arcs of the shortest paths.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+    ///Instantiates a \c PredMap.
+
+    ///This function instantiates a \ref PredMap.
+    ///\param g is the digraph, to which we would like to define the
+    ///\ref PredMap.
+    static PredMap *createPredMap(const Digraph &g)
+    {
+      return new PredMap(g);
+    }
+
+    ///The type of the map that indicates which nodes are processed.
+
+    ///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.
+    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
+    ///Instantiates a \c ProcessedMap.
+
+    ///This function instantiates a \ref ProcessedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the \ref ProcessedMap
+#ifdef DOXYGEN
+    static ProcessedMap *createProcessedMap(const Digraph &g)
+#else
+    static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+    {
+      return new ProcessedMap();
+    }
+
+    ///The type of the map that indicates which nodes are reached.
+
+    ///The type of the map that indicates which nodes are reached.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Digraph::template NodeMap<bool> ReachedMap;
+    ///Instantiates a \c ReachedMap.
+
+    ///This function instantiates a \ref ReachedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the \ref ReachedMap.
+    static ReachedMap *createReachedMap(const Digraph &g)
+    {
+      return new ReachedMap(g);
+    }
+
+    ///The type of the map that stores the distances of the nodes.
+
+    ///The type of the map that stores the distances of the nodes.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<int> DistMap;
+    ///Instantiates a \c DistMap.
+
+    ///This function instantiates a \ref DistMap.
+    ///\param g is the digraph, to which we would like to define the
+    ///\ref DistMap.
+    static DistMap *createDistMap(const Digraph &g)
+    {
+      return new DistMap(g);
+    }
+  };
+
+  ///%BFS algorithm class.
+
+  ///\ingroup search
+  ///This class provides an efficient implementation of the %BFS algorithm.
+  ///
+  ///There is also a \ref bfs() "function-type interface" for the BFS
+  ///algorithm, which is convenient in the simplier cases and it can be
+  ///used easier.
+  ///
+  ///\tparam GR The type of the digraph the algorithm runs on.
+  ///The default type is \ref ListDigraph.
+  ///\tparam 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,
+            typename TR>
+#else
+  template <typename GR=ListDigraph,
+            typename TR=BfsDefaultTraits<GR> >
+#endif
+  class Bfs {
+  public:
+
+    ///The type of the digraph the algorithm runs on.
+    typedef typename TR::Digraph Digraph;
+
+    ///\brief The type of the map that stores the predecessor arcs of the
+    ///shortest paths.
+    typedef typename TR::PredMap PredMap;
+    ///The type of the map that stores the distances of the nodes.
+    typedef typename TR::DistMap DistMap;
+    ///The type of the map that indicates which nodes are reached.
+    typedef typename TR::ReachedMap ReachedMap;
+    ///The type of the map that indicates which nodes are processed.
+    typedef typename TR::ProcessedMap ProcessedMap;
+    ///The type of the paths.
+    typedef PredMapPath<Digraph, PredMap> Path;
+
+    ///The \ref lemon::BfsDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    //Pointer to the underlying digraph.
+    const Digraph *G;
+    //Pointer to the map of predecessor arcs.
+    PredMap *_pred;
+    //Indicates if _pred is locally allocated (true) or not.
+    bool local_pred;
+    //Pointer to the map of distances.
+    DistMap *_dist;
+    //Indicates if _dist is locally allocated (true) or not.
+    bool local_dist;
+    //Pointer to the map of reached status of the nodes.
+    ReachedMap *_reached;
+    //Indicates if _reached is locally allocated (true) or not.
+    bool local_reached;
+    //Pointer to the map of processed status of the nodes.
+    ProcessedMap *_processed;
+    //Indicates if _processed is locally allocated (true) or not.
+    bool local_processed;
+
+    std::vector<typename Digraph::Node> _queue;
+    int _queue_head,_queue_tail,_queue_next_dist;
+    int _curr_dist;
+
+    //Creates the maps if necessary.
+    void create_maps()
+    {
+      if(!_pred) {
+        local_pred = true;
+        _pred = Traits::createPredMap(*G);
+      }
+      if(!_dist) {
+        local_dist = true;
+        _dist = Traits::createDistMap(*G);
+      }
+      if(!_reached) {
+        local_reached = true;
+        _reached = Traits::createReachedMap(*G);
+      }
+      if(!_processed) {
+        local_processed = true;
+        _processed = Traits::createProcessedMap(*G);
+      }
+    }
+
+  protected:
+
+    Bfs() {}
+
+  public:
+
+    typedef Bfs Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <class T>
+    struct SetPredMapTraits : public Traits {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "PredMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c PredMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c PredMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
+      typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetDistMapTraits : public Traits {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "DistMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c DistMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c DistMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
+      typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetReachedMapTraits : public Traits {
+      typedef T ReachedMap;
+      static ReachedMap *createReachedMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "ReachedMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c ReachedMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c ReachedMap type.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    template <class T>
+    struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
+      typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetProcessedMapTraits : public Traits {
+      typedef T ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "ProcessedMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
+      typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
+    };
+
+    struct SetStandardProcessedMapTraits : public Traits {
+      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &g)
+      {
+        return new ProcessedMap(g);
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///If you don't set it explicitly, it will be automatically allocated.
+    struct SetStandardProcessedMap :
+      public Bfs< Digraph, SetStandardProcessedMapTraits > {
+      typedef Bfs< Digraph, SetStandardProcessedMapTraits > Create;
+    };
+
+    ///@}
+
+  public:
+
+    ///Constructor.
+
+    ///Constructor.
+    ///\param g The digraph the algorithm runs on.
+    Bfs(const Digraph &g) :
+      G(&g),
+      _pred(NULL), local_pred(false),
+      _dist(NULL), local_dist(false),
+      _reached(NULL), local_reached(false),
+      _processed(NULL), local_processed(false)
+    { }
+
+    ///Destructor.
+    ~Bfs()
+    {
+      if(local_pred) delete _pred;
+      if(local_dist) delete _dist;
+      if(local_reached) delete _reached;
+      if(local_processed) delete _processed;
+    }
+
+    ///Sets the map that stores the predecessor arcs.
+
+    ///Sets the map that stores the predecessor arcs.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Bfs &predMap(PredMap &m)
+    {
+      if(local_pred) {
+        delete _pred;
+        local_pred=false;
+      }
+      _pred = &m;
+      return *this;
+    }
+
+    ///Sets the map that indicates which nodes are reached.
+
+    ///Sets the map that indicates which nodes are reached.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Bfs &reachedMap(ReachedMap &m)
+    {
+      if(local_reached) {
+        delete _reached;
+        local_reached=false;
+      }
+      _reached = &m;
+      return *this;
+    }
+
+    ///Sets the map that indicates which nodes are processed.
+
+    ///Sets the map that indicates which nodes are processed.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Bfs &processedMap(ProcessedMap &m)
+    {
+      if(local_processed) {
+        delete _processed;
+        local_processed=false;
+      }
+      _processed = &m;
+      return *this;
+    }
+
+    ///Sets the map that stores the distances of the nodes.
+
+    ///Sets the map that stores the distances of the nodes calculated by
+    ///the algorithm.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Bfs &distMap(DistMap &m)
+    {
+      if(local_dist) {
+        delete _dist;
+        local_dist=false;
+      }
+      _dist = &m;
+      return *this;
+    }
+
+  public:
+
+    ///\name Execution Control
+    ///The simplest way to execute the BFS algorithm is to use one of the
+    ///member functions called \ref run(Node) "run()".\n
+    ///If you need better control on the execution, you have to call
+    ///\ref init() first, then you can add several source nodes with
+    ///\ref addSource(). Finally the actual path computation can be
+    ///performed with one of the \ref start() functions.
+
+    ///@{
+
+    ///\brief Initializes the internal data structures.
+    ///
+    ///Initializes the internal data structures.
+    void init()
+    {
+      create_maps();
+      _queue.resize(countNodes(*G));
+      _queue_head=_queue_tail=0;
+      _curr_dist=1;
+      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
+        _pred->set(u,INVALID);
+        _reached->set(u,false);
+        _processed->set(u,false);
+      }
+    }
+
+    ///Adds a new source node.
+
+    ///Adds a new source node to the set of nodes to be processed.
+    ///
+    void addSource(Node s)
+    {
+      if(!(*_reached)[s])
+        {
+          _reached->set(s,true);
+          _pred->set(s,INVALID);
+          _dist->set(s,0);
+          _queue[_queue_head++]=s;
+          _queue_next_dist=_queue_head;
+        }
+    }
+
+    ///Processes the next node.
+
+    ///Processes the next node.
+    ///
+    ///\return The processed node.
+    ///
+    ///\pre The queue must not be empty.
+    Node processNextNode()
+    {
+      if(_queue_tail==_queue_next_dist) {
+        _curr_dist++;
+        _queue_next_dist=_queue_head;
+      }
+      Node n=_queue[_queue_tail++];
+      _processed->set(n,true);
+      Node m;
+      for(OutArcIt e(*G,n);e!=INVALID;++e)
+        if(!(*_reached)[m=G->target(e)]) {
+          _queue[_queue_head++]=m;
+          _reached->set(m,true);
+          _pred->set(m,e);
+          _dist->set(m,_curr_dist);
+        }
+      return n;
+    }
+
+    ///Processes the next node.
+
+    ///Processes the next node and checks if the given target node
+    ///is reached. If the target node is reachable from the processed
+    ///node, then the \c reach parameter will be set to \c true.
+    ///
+    ///\param target The target node.
+    ///\retval reach Indicates if the target node is reached.
+    ///It should be initially \c false.
+    ///
+    ///\return The processed node.
+    ///
+    ///\pre The queue must not be empty.
+    Node processNextNode(Node target, bool& reach)
+    {
+      if(_queue_tail==_queue_next_dist) {
+        _curr_dist++;
+        _queue_next_dist=_queue_head;
+      }
+      Node n=_queue[_queue_tail++];
+      _processed->set(n,true);
+      Node m;
+      for(OutArcIt e(*G,n);e!=INVALID;++e)
+        if(!(*_reached)[m=G->target(e)]) {
+          _queue[_queue_head++]=m;
+          _reached->set(m,true);
+          _pred->set(m,e);
+          _dist->set(m,_curr_dist);
+          reach = reach || (target == m);
+        }
+      return n;
+    }
+
+    ///Processes the next node.
+
+    ///Processes the next node and checks if at least one of reached
+    ///nodes has \c true value in the \c nm node map. If one node
+    ///with \c true value is reachable from the processed node, then the
+    ///\c rnode parameter will be set to the first of such nodes.
+    ///
+    ///\param nm A \c bool (or convertible) node map that indicates the
+    ///possible targets.
+    ///\retval rnode The reached target node.
+    ///It should be initially \c INVALID.
+    ///
+    ///\return The processed node.
+    ///
+    ///\pre The queue must not be empty.
+    template<class NM>
+    Node processNextNode(const NM& nm, Node& rnode)
+    {
+      if(_queue_tail==_queue_next_dist) {
+        _curr_dist++;
+        _queue_next_dist=_queue_head;
+      }
+      Node n=_queue[_queue_tail++];
+      _processed->set(n,true);
+      Node m;
+      for(OutArcIt e(*G,n);e!=INVALID;++e)
+        if(!(*_reached)[m=G->target(e)]) {
+          _queue[_queue_head++]=m;
+          _reached->set(m,true);
+          _pred->set(m,e);
+          _dist->set(m,_curr_dist);
+          if (nm[m] && rnode == INVALID) rnode = m;
+        }
+      return n;
+    }
+
+    ///The next node to be processed.
+
+    ///Returns the next node to be processed or \c INVALID if the queue
+    ///is empty.
+    Node nextNode() const
+    {
+      return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID;
+    }
+
+    ///Returns \c false if there are nodes to be processed.
+
+    ///Returns \c false if there are nodes to be processed
+    ///in the queue.
+    bool emptyQueue() const { return _queue_tail==_queue_head; }
+
+    ///Returns the number of the nodes to be processed.
+
+    ///Returns the number of the nodes to be processed
+    ///in the queue.
+    int queueSize() const { return _queue_head-_queue_tail; }
+
+    ///Executes the algorithm.
+
+    ///Executes the algorithm.
+    ///
+    ///This method runs the %BFS algorithm from the root node(s)
+    ///in order to compute the shortest path to each node.
+    ///
+    ///The algorithm computes
+    ///- the shortest path tree (forest),
+    ///- the distance of each node from the root(s).
+    ///
+    ///\pre init() must be called and at least one root node should be
+    ///added with addSource() before using this function.
+    ///
+    ///\note <tt>b.start()</tt> is just a shortcut of the following code.
+    ///\code
+    ///  while ( !b.emptyQueue() ) {
+    ///    b.processNextNode();
+    ///  }
+    ///\endcode
+    void start()
+    {
+      while ( !emptyQueue() ) processNextNode();
+    }
+
+    ///Executes the algorithm until the given target node is reached.
+
+    ///Executes the algorithm until the given target node is reached.
+    ///
+    ///This method runs the %BFS algorithm from the root node(s)
+    ///in order to compute the shortest path to \c t.
+    ///
+    ///The algorithm computes
+    ///- the shortest path to \c t,
+    ///- the distance of \c t from the root(s).
+    ///
+    ///\pre init() must be called and at least one root node should be
+    ///added with addSource() before using this function.
+    ///
+    ///\note <tt>b.start(t)</tt> is just a shortcut of the following code.
+    ///\code
+    ///  bool reach = false;
+    ///  while ( !b.emptyQueue() && !reach ) {
+    ///    b.processNextNode(t, reach);
+    ///  }
+    ///\endcode
+    void start(Node t)
+    {
+      bool reach = false;
+      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
+    }
+
+    ///Executes the algorithm until a condition is met.
+
+    ///Executes the algorithm until a condition is met.
+    ///
+    ///This method runs the %BFS algorithm from the root node(s) in
+    ///order to compute the shortest path to a node \c v with
+    /// <tt>nm[v]</tt> true, if such a node can be found.
+    ///
+    ///\param nm A \c bool (or convertible) node map. The algorithm
+    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
+    ///
+    ///\return The reached node \c v with <tt>nm[v]</tt> true or
+    ///\c INVALID if no such node was found.
+    ///
+    ///\pre init() must be called and at least one root node should be
+    ///added with addSource() before using this function.
+    ///
+    ///\note <tt>b.start(nm)</tt> is just a shortcut of the following code.
+    ///\code
+    ///  Node rnode = INVALID;
+    ///  while ( !b.emptyQueue() && rnode == INVALID ) {
+    ///    b.processNextNode(nm, rnode);
+    ///  }
+    ///  return rnode;
+    ///\endcode
+    template<class NodeBoolMap>
+    Node start(const NodeBoolMap &nm)
+    {
+      Node rnode = INVALID;
+      while ( !emptyQueue() && rnode == INVALID ) {
+        processNextNode(nm, rnode);
+      }
+      return rnode;
+    }
+
+    ///Runs the algorithm from the given source node.
+
+    ///This method runs the %BFS algorithm from node \c s
+    ///in order to compute the shortest path to each node.
+    ///
+    ///The algorithm computes
+    ///- the shortest path tree,
+    ///- the distance of each node from the root.
+    ///
+    ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
+    ///\code
+    ///  b.init();
+    ///  b.addSource(s);
+    ///  b.start();
+    ///\endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    ///Finds the shortest path between \c s and \c t.
+
+    ///This method runs the %BFS algorithm from node \c s
+    ///in order to compute the shortest path to node \c t
+    ///(it stops searching when \c t is processed).
+    ///
+    ///\return \c true if \c t is reachable form \c s.
+    ///
+    ///\note Apart from the return value, <tt>b.run(s,t)</tt> is just a
+    ///shortcut of the following code.
+    ///\code
+    ///  b.init();
+    ///  b.addSource(s);
+    ///  b.start(t);
+    ///\endcode
+    bool run(Node s,Node t) {
+      init();
+      addSource(s);
+      start(t);
+      return reached(t);
+    }
+
+    ///Runs the algorithm to visit all nodes in the digraph.
+
+    ///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.
+    ///\code
+    ///  b.init();
+    ///  for (NodeIt n(gr); n != INVALID; ++n) {
+    ///    if (!b.reached(n)) {
+    ///      b.addSource(n);
+    ///      b.start();
+    ///    }
+    ///  }
+    ///\endcode
+    void run() {
+      init();
+      for (NodeIt n(*G); n != INVALID; ++n) {
+        if (!reached(n)) {
+          addSource(n);
+          start();
+        }
+      }
+    }
+
+    ///@}
+
+    ///\name Query Functions
+    ///The results of the BFS algorithm can be obtained using these
+    ///functions.\n
+    ///Either \ref run(Node) "run()" or \ref start() should be called
+    ///before using them.
+
+    ///@{
+
+    ///The shortest path to the given node.
+
+    ///Returns the shortest path to the given node from the root(s).
+    ///
+    ///\warning \c t should be reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Path path(Node t) const { return Path(*G, *_pred, t); }
+
+    ///The distance of the given node from the root(s).
+
+    ///Returns the distance of the given node from the root(s).
+    ///
+    ///\warning If node \c v is not reached from the root(s), then
+    ///the return value of this function is undefined.
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    int dist(Node v) const { return (*_dist)[v]; }
+
+    ///\brief Returns the 'previous arc' of the shortest path tree for
+    ///the given node.
+    ///
+    ///This function returns the 'previous arc' of the shortest path
+    ///tree for the node \c v, i.e. it returns the last arc of a
+    ///shortest path from a root to \c v. It is \c INVALID if \c v
+    ///is not reached from the root(s) or if \c v is a root.
+    ///
+    ///The shortest path tree used here is equal to the shortest path
+    ///tree used in \ref predNode() and \ref predMap().
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Arc predArc(Node v) const { return (*_pred)[v];}
+
+    ///\brief Returns the 'previous node' of the shortest path tree for
+    ///the given node.
+    ///
+    ///This function returns the 'previous node' of the shortest path
+    ///tree for the node \c v, i.e. it returns the last but one node
+    ///of a shortest path from a root to \c v. It is \c INVALID
+    ///if \c v is not reached from the root(s) or if \c v is a root.
+    ///
+    ///The shortest path tree used here is equal to the shortest path
+    ///tree used in \ref predArc() and \ref predMap().
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
+                                  G->source((*_pred)[v]); }
+
+    ///\brief Returns a const reference to the node map that stores the
+    /// distances of the nodes.
+    ///
+    ///Returns a const reference to the node map that stores the distances
+    ///of the nodes calculated by the algorithm.
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    const DistMap &distMap() const { return *_dist;}
+
+    ///\brief Returns a const reference to the node map that stores the
+    ///predecessor arcs.
+    ///
+    ///Returns a const reference to the node map that stores the predecessor
+    ///arcs, which form the shortest path tree (forest).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    const PredMap &predMap() const { return *_pred;}
+
+    ///Checks if the given node is reached from the root(s).
+
+    ///Returns \c true if \c v is reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    bool reached(Node v) const { return (*_reached)[v]; }
+
+    ///@}
+  };
+
+  ///Default traits class of bfs() function.
+
+  ///Default traits class of bfs() function.
+  ///\tparam GR Digraph type.
+  template<class GR>
+  struct BfsWizardDefaultTraits
+  {
+    ///The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    ///\brief The type of the map that stores the predecessor
+    ///arcs of the shortest paths.
+    ///
+    ///The type of the map that stores the predecessor
+    ///arcs of the shortest paths.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+    ///Instantiates a PredMap.
+
+    ///This function instantiates a PredMap.
+    ///\param g is the digraph, to which we would like to define the
+    ///PredMap.
+    static PredMap *createPredMap(const Digraph &g)
+    {
+      return new PredMap(g);
+    }
+
+    ///The type of the map that indicates which nodes are processed.
+
+    ///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.
+    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
+    ///Instantiates a ProcessedMap.
+
+    ///This function instantiates a ProcessedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the ProcessedMap.
+#ifdef DOXYGEN
+    static ProcessedMap *createProcessedMap(const Digraph &g)
+#else
+    static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+    {
+      return new ProcessedMap();
+    }
+
+    ///The type of the map that indicates which nodes are reached.
+
+    ///The type of the map that indicates which nodes are reached.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Digraph::template NodeMap<bool> ReachedMap;
+    ///Instantiates a ReachedMap.
+
+    ///This function instantiates a ReachedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the ReachedMap.
+    static ReachedMap *createReachedMap(const Digraph &g)
+    {
+      return new ReachedMap(g);
+    }
+
+    ///The type of the map that stores the distances of the nodes.
+
+    ///The type of the map that stores the distances of the nodes.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<int> DistMap;
+    ///Instantiates a DistMap.
+
+    ///This function instantiates a DistMap.
+    ///\param g is the digraph, to which we would like to define
+    ///the DistMap
+    static DistMap *createDistMap(const Digraph &g)
+    {
+      return new DistMap(g);
+    }
+
+    ///The type of the shortest paths.
+
+    ///The type of the shortest paths.
+    ///It must conform to the \ref concepts::Path "Path" concept.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  /// Default traits class used by BfsWizard
+
+  /// Default traits class used by BfsWizard.
+  /// \tparam GR The type of the digraph.
+  template<class GR>
+  class BfsWizardBase : public BfsWizardDefaultTraits<GR>
+  {
+
+    typedef BfsWizardDefaultTraits<GR> Base;
+  protected:
+    //The type of the nodes in the digraph.
+    typedef typename Base::Digraph::Node Node;
+
+    //Pointer to the digraph the algorithm runs on.
+    void *_g;
+    //Pointer to the map of reached nodes.
+    void *_reached;
+    //Pointer to the map of processed nodes.
+    void *_processed;
+    //Pointer to the map of predecessors arcs.
+    void *_pred;
+    //Pointer to the map of distances.
+    void *_dist;
+    //Pointer to the shortest path to the target node.
+    void *_path;
+    //Pointer to the distance of the target node.
+    int *_di;
+
+    public:
+    /// Constructor.
+
+    /// This constructor does not require parameters, it initiates
+    /// all of the attributes to \c 0.
+    BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
+                      _dist(0), _path(0), _di(0) {}
+
+    /// Constructor.
+
+    /// This constructor requires one parameter,
+    /// others are initiated to \c 0.
+    /// \param g The digraph the algorithm runs on.
+    BfsWizardBase(const GR &g) :
+      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
+      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
+
+  };
+
+  /// Auxiliary class for the function-type interface of BFS algorithm.
+
+  /// This auxiliary class is created to implement the
+  /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
+  /// It does not have own \ref run(Node) "run()" method, it uses the
+  /// functions and features of the plain \ref Bfs.
+  ///
+  /// This class should only be used through the \ref bfs() function,
+  /// 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
+  {
+    typedef TR Base;
+
+    typedef typename TR::Digraph Digraph;
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    typedef typename TR::PredMap PredMap;
+    typedef typename TR::DistMap DistMap;
+    typedef typename TR::ReachedMap ReachedMap;
+    typedef typename TR::ProcessedMap ProcessedMap;
+    typedef typename TR::Path Path;
+
+  public:
+
+    /// Constructor.
+    BfsWizard() : TR() {}
+
+    /// Constructor that requires parameters.
+
+    /// Constructor that requires parameters.
+    /// These parameters will be the default values for the traits class.
+    /// \param g The digraph the algorithm runs on.
+    BfsWizard(const Digraph &g) :
+      TR(g) {}
+
+    ///Copy constructor
+    BfsWizard(const TR &b) : TR(b) {}
+
+    ~BfsWizard() {}
+
+    ///Runs BFS algorithm from the given source node.
+
+    ///This method runs BFS algorithm from node \c s
+    ///in order to compute the shortest path to each node.
+    void run(Node s)
+    {
+      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
+      if (Base::_pred)
+        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist)
+        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      if (Base::_reached)
+        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
+      if (Base::_processed)
+        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+      if (s!=INVALID)
+        alg.run(s);
+      else
+        alg.run();
+    }
+
+    ///Finds the shortest path between \c s and \c t.
+
+    ///This method runs BFS algorithm from node \c s
+    ///in order to compute the shortest path to node \c t
+    ///(it stops searching when \c t is processed).
+    ///
+    ///\return \c true if \c t is reachable form \c s.
+    bool run(Node s, Node t)
+    {
+      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
+      if (Base::_pred)
+        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist)
+        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      if (Base::_reached)
+        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
+      if (Base::_processed)
+        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+      alg.run(s,t);
+      if (Base::_path)
+        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
+      if (Base::_di)
+        *Base::_di = alg.dist(t);
+      return alg.reached(t);
+    }
+
+    ///Runs BFS algorithm to visit all nodes in the digraph.
+
+    ///This method runs BFS algorithm in order to visit all nodes
+    ///in the digraph.
+    void run()
+    {
+      run(INVALID);
+    }
+
+    template<class T>
+    struct SetPredMapBase : public Base {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &) { return 0; };
+      SetPredMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the predecessor map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the predecessor arcs of the nodes.
+    template<class T>
+    BfsWizard<SetPredMapBase<T> > predMap(const T &t)
+    {
+      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BfsWizard<SetPredMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetReachedMapBase : public Base {
+      typedef T ReachedMap;
+      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
+      SetReachedMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the reached map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are reached.
+    template<class T>
+    BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
+    {
+      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BfsWizard<SetReachedMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetDistMapBase : public Base {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph &) { return 0; };
+      SetDistMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the distance map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the distances of the nodes calculated
+    ///by the algorithm.
+    template<class T>
+    BfsWizard<SetDistMapBase<T> > distMap(const T &t)
+    {
+      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BfsWizard<SetDistMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetProcessedMapBase : public Base {
+      typedef T ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
+      SetProcessedMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-func-param "Named parameter" for setting
+    ///the processed map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are processed.
+    template<class T>
+    BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
+    {
+      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BfsWizard<SetProcessedMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetPathBase : public Base {
+      typedef T Path;
+      SetPathBase(const TR &b) : TR(b) {}
+    };
+    ///\brief \ref named-func-param "Named parameter"
+    ///for getting the shortest path to the target node.
+    ///
+    ///\ref named-func-param "Named parameter"
+    ///for getting the shortest path to the target node.
+    template<class T>
+    BfsWizard<SetPathBase<T> > path(const T &t)
+    {
+      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BfsWizard<SetPathBase<T> >(*this);
+    }
+
+    ///\brief \ref named-func-param "Named parameter"
+    ///for getting the distance of the target node.
+    ///
+    ///\ref named-func-param "Named parameter"
+    ///for getting the distance of the target node.
+    BfsWizard dist(const int &d)
+    {
+      Base::_di=const_cast<int*>(&d);
+      return *this;
+    }
+
+  };
+
+  ///Function-type interface for BFS algorithm.
+
+  /// \ingroup search
+  ///Function-type interface for BFS algorithm.
+  ///
+  ///This function also has several \ref named-func-param "named parameters",
+  ///they are declared as the members of class \ref BfsWizard.
+  ///The following examples show how to use these parameters.
+  ///\code
+  ///  // Compute shortest path from node s to each node
+  ///  bfs(g).predMap(preds).distMap(dists).run(s);
+  ///
+  ///  // Compute shortest path from s to t
+  ///  bool reached = bfs(g).path(p).dist(d).run(s,t);
+  ///\endcode
+  ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()"
+  ///to the end of the parameter list.
+  ///\sa BfsWizard
+  ///\sa Bfs
+  template<class GR>
+  BfsWizard<BfsWizardBase<GR> >
+  bfs(const GR &digraph)
+  {
+    return BfsWizard<BfsWizardBase<GR> >(digraph);
+  }
+
+#ifdef DOXYGEN
+  /// \brief Visitor class for BFS.
+  ///
+  /// This class defines the interface of the BfsVisit events, and
+  /// it could be the base of a real visitor class.
+  template <typename GR>
+  struct BfsVisitor {
+    typedef GR Digraph;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::Node Node;
+    /// \brief Called for the source node(s) of the BFS.
+    ///
+    /// This function is called for the source node(s) of the BFS.
+    void start(const Node& node) {}
+    /// \brief Called when a node is reached first time.
+    ///
+    /// This function is called when a node is reached first time.
+    void reach(const Node& node) {}
+    /// \brief Called when a node is processed.
+    ///
+    /// This function is called when a node is processed.
+    void process(const Node& node) {}
+    /// \brief Called when an arc reaches a new node.
+    ///
+    /// This function is called when the BFS finds an arc whose target node
+    /// is not reached yet.
+    void discover(const Arc& arc) {}
+    /// \brief Called when an arc is examined but its target node is
+    /// already discovered.
+    ///
+    /// This function is called when an arc is examined but its target node is
+    /// already discovered.
+    void examine(const Arc& arc) {}
+  };
+#else
+  template <typename GR>
+  struct BfsVisitor {
+    typedef GR Digraph;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::Node Node;
+    void start(const Node&) {}
+    void reach(const Node&) {}
+    void process(const Node&) {}
+    void discover(const Arc&) {}
+    void examine(const Arc&) {}
+
+    template <typename _Visitor>
+    struct Constraints {
+      void constraints() {
+        Arc arc;
+        Node node;
+        visitor.start(node);
+        visitor.reach(node);
+        visitor.process(node);
+        visitor.discover(arc);
+        visitor.examine(arc);
+      }
+      _Visitor& visitor;
+      Constraints() {}
+    };
+  };
+#endif
+
+  /// \brief Default traits class of BfsVisit class.
+  ///
+  /// Default traits class of BfsVisit class.
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  template<class GR>
+  struct BfsVisitDefaultTraits {
+
+    /// \brief The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that indicates which nodes are reached.
+    ///
+    /// The type of the map that indicates which nodes are reached.
+    /// It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Digraph::template NodeMap<bool> ReachedMap;
+
+    /// \brief Instantiates a ReachedMap.
+    ///
+    /// This function instantiates a ReachedMap.
+    /// \param digraph is the digraph, to which
+    /// we would like to define the ReachedMap.
+    static ReachedMap *createReachedMap(const Digraph &digraph) {
+      return new ReachedMap(digraph);
+    }
+
+  };
+
+  /// \ingroup search
+  ///
+  /// \brief BFS algorithm class with visitor interface.
+  ///
+  /// This class provides an efficient implementation of the BFS algorithm
+  /// with visitor interface.
+  ///
+  /// The BfsVisit class provides an alternative interface to the Bfs
+  /// class. It works with callback mechanism, the BfsVisit object calls
+  /// the member functions of the \c Visitor class on every BFS event.
+  ///
+  /// This interface of the BFS algorithm should be used in special cases
+  /// when extra actions have to be performed in connection with certain
+  /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
+  /// instead.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// The default type is \ref ListDigraph.
+  /// The value of GR is not used directly by \ref BfsVisit,
+  /// it is only passed to \ref BfsVisitDefaultTraits.
+  /// \tparam VS The Visitor type that is used by the algorithm.
+  /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
+  /// does not observe the BFS events. If you want to observe the BFS
+  /// events, you should implement your own visitor class.
+  /// \tparam 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>
+#else
+  template <typename GR = ListDigraph,
+            typename VS = BfsVisitor<GR>,
+            typename TR = BfsVisitDefaultTraits<GR> >
+#endif
+  class BfsVisit {
+  public:
+
+    ///The traits class.
+    typedef TR Traits;
+
+    ///The type of the digraph the algorithm runs on.
+    typedef typename Traits::Digraph Digraph;
+
+    ///The visitor type used by the algorithm.
+    typedef VS Visitor;
+
+    ///The type of the map that indicates which nodes are reached.
+    typedef typename Traits::ReachedMap ReachedMap;
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    //Pointer to the underlying digraph.
+    const Digraph *_digraph;
+    //Pointer to the visitor object.
+    Visitor *_visitor;
+    //Pointer to the map of reached status of the nodes.
+    ReachedMap *_reached;
+    //Indicates if _reached is locally allocated (true) or not.
+    bool local_reached;
+
+    std::vector<typename Digraph::Node> _list;
+    int _list_front, _list_back;
+
+    //Creates the maps if necessary.
+    void create_maps() {
+      if(!_reached) {
+        local_reached = true;
+        _reached = Traits::createReachedMap(*_digraph);
+      }
+    }
+
+  protected:
+
+    BfsVisit() {}
+
+  public:
+
+    typedef BfsVisit Create;
+
+    /// \name Named Template Parameters
+
+    ///@{
+    template <class T>
+    struct SetReachedMapTraits : public Traits {
+      typedef T ReachedMap;
+      static ReachedMap *createReachedMap(const Digraph &digraph) {
+        LEMON_ASSERT(false, "ReachedMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// ReachedMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
+    template <class T>
+    struct SetReachedMap : public BfsVisit< Digraph, Visitor,
+                                            SetReachedMapTraits<T> > {
+      typedef BfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
+    };
+    ///@}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param visitor The visitor object of the algorithm.
+    BfsVisit(const Digraph& digraph, Visitor& visitor)
+      : _digraph(&digraph), _visitor(&visitor),
+        _reached(0), local_reached(false) {}
+
+    /// \brief Destructor.
+    ~BfsVisit() {
+      if(local_reached) delete _reached;
+    }
+
+    /// \brief Sets the map that indicates which nodes are reached.
+    ///
+    /// Sets the map that indicates which nodes are reached.
+    /// If you don't use this function before calling \ref run(Node) "run()"
+    /// or \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt> (*this) </tt>
+    BfsVisit &reachedMap(ReachedMap &m) {
+      if(local_reached) {
+        delete _reached;
+        local_reached = false;
+      }
+      _reached = &m;
+      return *this;
+    }
+
+  public:
+
+    /// \name Execution Control
+    /// The simplest way to execute the BFS algorithm is to use one of the
+    /// member functions called \ref run(Node) "run()".\n
+    /// If you need better control on the execution, you have to call
+    /// \ref init() first, then you can add several source nodes with
+    /// \ref addSource(). Finally the actual path computation can be
+    /// performed with one of the \ref start() functions.
+
+    /// @{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures.
+    void init() {
+      create_maps();
+      _list.resize(countNodes(*_digraph));
+      _list_front = _list_back = -1;
+      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
+        _reached->set(u, false);
+      }
+    }
+
+    /// \brief Adds a new source node.
+    ///
+    /// Adds a new source node to the set of nodes to be processed.
+    void addSource(Node s) {
+      if(!(*_reached)[s]) {
+          _reached->set(s,true);
+          _visitor->start(s);
+          _visitor->reach(s);
+          _list[++_list_back] = s;
+        }
+    }
+
+    /// \brief Processes the next node.
+    ///
+    /// Processes the next node.
+    ///
+    /// \return The processed node.
+    ///
+    /// \pre The queue must not be empty.
+    Node processNextNode() {
+      Node n = _list[++_list_front];
+      _visitor->process(n);
+      Arc e;
+      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
+        Node m = _digraph->target(e);
+        if (!(*_reached)[m]) {
+          _visitor->discover(e);
+          _visitor->reach(m);
+          _reached->set(m, true);
+          _list[++_list_back] = m;
+        } else {
+          _visitor->examine(e);
+        }
+      }
+      return n;
+    }
+
+    /// \brief Processes the next node.
+    ///
+    /// Processes the next node and checks if the given target node
+    /// is reached. If the target node is reachable from the processed
+    /// node, then the \c reach parameter will be set to \c true.
+    ///
+    /// \param target The target node.
+    /// \retval reach Indicates if the target node is reached.
+    /// It should be initially \c false.
+    ///
+    /// \return The processed node.
+    ///
+    /// \pre The queue must not be empty.
+    Node processNextNode(Node target, bool& reach) {
+      Node n = _list[++_list_front];
+      _visitor->process(n);
+      Arc e;
+      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
+        Node m = _digraph->target(e);
+        if (!(*_reached)[m]) {
+          _visitor->discover(e);
+          _visitor->reach(m);
+          _reached->set(m, true);
+          _list[++_list_back] = m;
+          reach = reach || (target == m);
+        } else {
+          _visitor->examine(e);
+        }
+      }
+      return n;
+    }
+
+    /// \brief Processes the next node.
+    ///
+    /// Processes the next node and checks if at least one of reached
+    /// nodes has \c true value in the \c nm node map. If one node
+    /// with \c true value is reachable from the processed node, then the
+    /// \c rnode parameter will be set to the first of such nodes.
+    ///
+    /// \param nm A \c bool (or convertible) node map that indicates the
+    /// possible targets.
+    /// \retval rnode The reached target node.
+    /// It should be initially \c INVALID.
+    ///
+    /// \return The processed node.
+    ///
+    /// \pre The queue must not be empty.
+    template <typename NM>
+    Node processNextNode(const NM& nm, Node& rnode) {
+      Node n = _list[++_list_front];
+      _visitor->process(n);
+      Arc e;
+      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
+        Node m = _digraph->target(e);
+        if (!(*_reached)[m]) {
+          _visitor->discover(e);
+          _visitor->reach(m);
+          _reached->set(m, true);
+          _list[++_list_back] = m;
+          if (nm[m] && rnode == INVALID) rnode = m;
+        } else {
+          _visitor->examine(e);
+        }
+      }
+      return n;
+    }
+
+    /// \brief The next node to be processed.
+    ///
+    /// Returns the next node to be processed or \c INVALID if the queue
+    /// is empty.
+    Node nextNode() const {
+      return _list_front != _list_back ? _list[_list_front + 1] : INVALID;
+    }
+
+    /// \brief Returns \c false if there are nodes
+    /// to be processed.
+    ///
+    /// Returns \c false if there are nodes
+    /// to be processed in the queue.
+    bool emptyQueue() const { return _list_front == _list_back; }
+
+    /// \brief Returns the number of the nodes to be processed.
+    ///
+    /// Returns the number of the nodes to be processed in the queue.
+    int queueSize() const { return _list_back - _list_front; }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    /// This method runs the %BFS algorithm from the root node(s)
+    /// in order to compute the shortest path to each node.
+    ///
+    /// The algorithm computes
+    /// - the shortest path tree (forest),
+    /// - the distance of each node from the root(s).
+    ///
+    /// \pre init() must be called and at least one root node should be added
+    /// with addSource() before using this function.
+    ///
+    /// \note <tt>b.start()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   while ( !b.emptyQueue() ) {
+    ///     b.processNextNode();
+    ///   }
+    /// \endcode
+    void start() {
+      while ( !emptyQueue() ) processNextNode();
+    }
+
+    /// \brief Executes the algorithm until the given target node is reached.
+    ///
+    /// Executes the algorithm until the given target node is reached.
+    ///
+    /// This method runs the %BFS algorithm from the root node(s)
+    /// in order to compute the shortest path to \c t.
+    ///
+    /// The algorithm computes
+    /// - the shortest path to \c t,
+    /// - the distance of \c t from the root(s).
+    ///
+    /// \pre init() must be called and at least one root node should be
+    /// added with addSource() before using this function.
+    ///
+    /// \note <tt>b.start(t)</tt> is just a shortcut of the following code.
+    /// \code
+    ///   bool reach = false;
+    ///   while ( !b.emptyQueue() && !reach ) {
+    ///     b.processNextNode(t, reach);
+    ///   }
+    /// \endcode
+    void start(Node t) {
+      bool reach = false;
+      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
+    }
+
+    /// \brief Executes the algorithm until a condition is met.
+    ///
+    /// Executes the algorithm until a condition is met.
+    ///
+    /// This method runs the %BFS algorithm from the root node(s) in
+    /// order to compute the shortest path to a node \c v with
+    /// <tt>nm[v]</tt> true, if such a node can be found.
+    ///
+    /// \param nm must be a bool (or convertible) node map. The
+    /// algorithm will stop when it reaches a node \c v with
+    /// <tt>nm[v]</tt> true.
+    ///
+    /// \return The reached node \c v with <tt>nm[v]</tt> true or
+    /// \c INVALID if no such node was found.
+    ///
+    /// \pre init() must be called and at least one root node should be
+    /// added with addSource() before using this function.
+    ///
+    /// \note <tt>b.start(nm)</tt> is just a shortcut of the following code.
+    /// \code
+    ///   Node rnode = INVALID;
+    ///   while ( !b.emptyQueue() && rnode == INVALID ) {
+    ///     b.processNextNode(nm, rnode);
+    ///   }
+    ///   return rnode;
+    /// \endcode
+    template <typename NM>
+    Node start(const NM &nm) {
+      Node rnode = INVALID;
+      while ( !emptyQueue() && rnode == INVALID ) {
+        processNextNode(nm, rnode);
+      }
+      return rnode;
+    }
+
+    /// \brief Runs the algorithm from the given source node.
+    ///
+    /// This method runs the %BFS algorithm from node \c s
+    /// in order to compute the shortest path to each node.
+    ///
+    /// The algorithm computes
+    /// - the shortest path tree,
+    /// - the distance of each node from the root.
+    ///
+    /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
+    ///\code
+    ///   b.init();
+    ///   b.addSource(s);
+    ///   b.start();
+    ///\endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    /// \brief Finds the shortest path between \c s and \c t.
+    ///
+    /// This method runs the %BFS algorithm from node \c s
+    /// in order to compute the shortest path to node \c t
+    /// (it stops searching when \c t is processed).
+    ///
+    /// \return \c true if \c t is reachable form \c s.
+    ///
+    /// \note Apart from the return value, <tt>b.run(s,t)</tt> is just a
+    /// shortcut of the following code.
+    ///\code
+    ///   b.init();
+    ///   b.addSource(s);
+    ///   b.start(t);
+    ///\endcode
+    bool run(Node s,Node t) {
+      init();
+      addSource(s);
+      start(t);
+      return reached(t);
+    }
+
+    /// \brief Runs the algorithm to visit all nodes in the digraph.
+    ///
+    /// 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.
+    ///\code
+    ///  b.init();
+    ///  for (NodeIt n(gr); n != INVALID; ++n) {
+    ///    if (!b.reached(n)) {
+    ///      b.addSource(n);
+    ///      b.start();
+    ///    }
+    ///  }
+    ///\endcode
+    void run() {
+      init();
+      for (NodeIt it(*_digraph); it != INVALID; ++it) {
+        if (!reached(it)) {
+          addSource(it);
+          start();
+        }
+      }
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    /// The results of the BFS algorithm can be obtained using these
+    /// functions.\n
+    /// Either \ref run(Node) "run()" or \ref start() should be called
+    /// before using them.
+
+    ///@{
+
+    /// \brief Checks if the given node is reached from the root(s).
+    ///
+    /// Returns \c true if \c v is reached from the root(s).
+    ///
+    /// \pre Either \ref run(Node) "run()" or \ref init()
+    /// must be called before using this function.
+    bool reached(Node v) const { return (*_reached)[v]; }
+
+    ///@}
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif
diff --git a/lemon/bin_heap.h b/lemon/bin_heap.h
new file mode 100644
index 0000000..02c6658
--- /dev/null
+++ b/lemon/bin_heap.h
@@ -0,0 +1,347 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_BIN_HEAP_H
+#define LEMON_BIN_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Binary heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  /// \brief Binary heap data structure.
+  ///
+  /// This class implements the \e binary \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class BinHeap {
+  public:
+
+    /// 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 BinHeap(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.
+    BinHeap(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)/2; }
+
+    static int secondChild(int i) { return 2*i+2; }
+    bool less(const Pair &p1, const Pair &p2) const {
+      return _comp(p1.second, p2.second);
+    }
+
+    int 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);
+      return hole;
+    }
+
+    int bubbleDown(int hole, Pair p, int length) {
+      int child = secondChild(hole);
+      while(child < length) {
+        if( less(_data[child-1], _data[child]) ) {
+          --child;
+        }
+        if( !less(_data[child], p) )
+          goto ok;
+        move(_data[child], hole);
+        hole = child;
+        child = secondChild(hole);
+      }
+      child--;
+      if( child<length && less(_data[child], p) ) {
+        move(_data[child], hole);
+        hole=child;
+      }
+    ok:
+      move(p, hole);
+      return 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 ( bubbleUp(h, _data[n]) == h) {
+          bubbleDown(h, _data[n], 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 BinHeap
+
+} // namespace lemon
+
+#endif // LEMON_BIN_HEAP_H
diff --git a/lemon/binomial_heap.h b/lemon/binomial_heap.h
new file mode 100644
index 0000000..5bc1378
--- /dev/null
+++ b/lemon/binomial_heap.h
@@ -0,0 +1,445 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BINOMIAL_HEAP_H
+#define LEMON_BINOMIAL_HEAP_H
+
+///\file
+///\ingroup heaps
+///\brief Binomial Heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+#include <lemon/math.h>
+#include <lemon/counter.h>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Binomial heap data structure.
+  ///
+  /// This class implements the \e binomial \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The methods \ref increase() and \ref erase() are not efficient
+  /// in a binomial heap. In case of many calls of these operations,
+  /// it is better to use other heap structure, e.g. \ref BinHeap
+  /// "binary heap".
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class BinomialHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    class Store;
+
+    std::vector<Store> _data;
+    int _min, _head;
+    ItemIntMap &_iim;
+    Compare _comp;
+    int _num_items;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit BinomialHeap(ItemIntMap &map)
+      : _min(0), _head(-1), _iim(map), _num_items(0) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    BinomialHeap(ItemIntMap &map, const Compare &comp)
+      : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num_items; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num_items==0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _min=0; _num_items=0; _head=-1;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param item The item.
+    /// \param value The priority.
+    void set (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if ( i >= 0 && _data[i].in ) {
+        if ( _comp(value, _data[i].prio) ) decrease(item, value);
+        if ( _comp(_data[i].prio, value) ) increase(item, value);
+      } else push(item, value);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param item The item to insert.
+    /// \param value The priority of the item.
+    /// \pre \e item must not be stored in the heap.
+    void push (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if ( i<0 ) {
+        int s=_data.size();
+        _iim.set( item,s );
+        Store st;
+        st.name=item;
+        st.prio=value;
+        _data.push_back(st);
+        i=s;
+      }
+      else {
+        _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
+        _data[i].degree=0;
+        _data[i].in=true;
+        _data[i].prio=value;
+      }
+
+      if( 0==_num_items ) {
+        _head=i;
+        _min=i;
+      } else {
+        merge(i);
+        if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
+      }
+      ++_num_items;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[_min].name; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[_min].prio; }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param item The item.
+    /// \pre \e item must be in the heap.
+    const Prio& operator[](const Item& item) const {
+      return _data[_iim[item]].prio;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      _data[_min].in=false;
+
+      int head_child=-1;
+      if ( _data[_min].child!=-1 ) {
+        int child=_data[_min].child;
+        int neighb;
+        while( child!=-1 ) {
+          neighb=_data[child].right_neighbor;
+          _data[child].parent=-1;
+          _data[child].right_neighbor=head_child;
+          head_child=child;
+          child=neighb;
+        }
+      }
+
+      if ( _data[_head].right_neighbor==-1 ) {
+        // there was only one root
+        _head=head_child;
+      }
+      else {
+        // there were more roots
+        if( _head!=_min )  { unlace(_min); }
+        else { _head=_data[_head].right_neighbor; }
+        merge(head_child);
+      }
+      _min=findMin();
+      --_num_items;
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param item The item to delete.
+    /// \pre \e item must be in the heap.
+    void erase (const Item& item) {
+      int i=_iim[item];
+      if ( i >= 0 && _data[i].in ) {
+        decrease( item, _data[_min].prio-1 );
+        pop();
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at least \e value.
+    void decrease (Item item, const Prio& value) {
+      int i=_iim[item];
+      int p=_data[i].parent;
+      _data[i].prio=value;
+
+      while( p!=-1 && _comp(value, _data[p].prio) ) {
+        _data[i].name=_data[p].name;
+        _data[i].prio=_data[p].prio;
+        _data[p].name=item;
+        _data[p].prio=value;
+        _iim[_data[i].name]=i;
+        i=p;
+        p=_data[p].parent;
+      }
+      _iim[item]=i;
+      if ( _comp(value, _data[_min].prio) ) _min=i;
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at most \e value.
+    void increase (Item item, const Prio& value) {
+      erase(item);
+      push(item, value);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param item The item.
+    State state(const Item &item) const {
+      int i=_iim[item];
+      if( i>=0 ) {
+        if ( _data[i].in ) i=0;
+        else i=-2;
+      }
+      return State(i);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    // Find the minimum of the roots
+    int findMin() {
+      if( _head!=-1 ) {
+        int min_loc=_head, min_val=_data[_head].prio;
+        for( int x=_data[_head].right_neighbor; x!=-1;
+             x=_data[x].right_neighbor ) {
+          if( _comp( _data[x].prio,min_val ) ) {
+            min_val=_data[x].prio;
+            min_loc=x;
+          }
+        }
+        return min_loc;
+      }
+      else return -1;
+    }
+
+    // Merge the heap with another heap starting at the given position
+    void merge(int a) {
+      if( _head==-1 || a==-1 ) return;
+      if( _data[a].right_neighbor==-1 &&
+          _data[a].degree<=_data[_head].degree ) {
+        _data[a].right_neighbor=_head;
+        _head=a;
+      } else {
+        interleave(a);
+      }
+      if( _data[_head].right_neighbor==-1 ) return;
+
+      int x=_head;
+      int x_prev=-1, x_next=_data[x].right_neighbor;
+      while( x_next!=-1 ) {
+        if( _data[x].degree!=_data[x_next].degree ||
+            ( _data[x_next].right_neighbor!=-1 &&
+              _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
+          x_prev=x;
+          x=x_next;
+        }
+        else {
+          if( _comp(_data[x_next].prio,_data[x].prio) ) {
+            if( x_prev==-1 ) {
+              _head=x_next;
+            } else {
+              _data[x_prev].right_neighbor=x_next;
+            }
+            fuse(x,x_next);
+            x=x_next;
+          }
+          else {
+            _data[x].right_neighbor=_data[x_next].right_neighbor;
+            fuse(x_next,x);
+          }
+        }
+        x_next=_data[x].right_neighbor;
+      }
+    }
+
+    // Interleave the elements of the given list into the list of the roots
+    void interleave(int a) {
+      int p=_head, q=a;
+      int curr=_data.size();
+      _data.push_back(Store());
+
+      while( p!=-1 || q!=-1 ) {
+        if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
+          _data[curr].right_neighbor=p;
+          curr=p;
+          p=_data[p].right_neighbor;
+        }
+        else {
+          _data[curr].right_neighbor=q;
+          curr=q;
+          q=_data[q].right_neighbor;
+        }
+      }
+
+      _head=_data.back().right_neighbor;
+      _data.pop_back();
+    }
+
+    // Lace node a under node b
+    void fuse(int a, int b) {
+      _data[a].parent=b;
+      _data[a].right_neighbor=_data[b].child;
+      _data[b].child=a;
+
+      ++_data[b].degree;
+    }
+
+    // Unlace node a (if it has siblings)
+    void unlace(int a) {
+      int neighb=_data[a].right_neighbor;
+      int other=_head;
+
+      while( _data[other].right_neighbor!=a )
+        other=_data[other].right_neighbor;
+      _data[other].right_neighbor=neighb;
+    }
+
+  private:
+
+    class Store {
+      friend class BinomialHeap;
+
+      Item name;
+      int parent;
+      int right_neighbor;
+      int child;
+      int degree;
+      bool in;
+      Prio prio;
+
+      Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
+        in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_BINOMIAL_HEAP_H
+
diff --git a/lemon/bits/alteration_notifier.h b/lemon/bits/alteration_notifier.h
new file mode 100644
index 0000000..d14fe36
--- /dev/null
+++ b/lemon/bits/alteration_notifier.h
@@ -0,0 +1,472 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_ALTERATION_NOTIFIER_H
+#define LEMON_BITS_ALTERATION_NOTIFIER_H
+
+#include <vector>
+#include <list>
+
+#include <lemon/core.h>
+#include <lemon/bits/lock.h>
+
+//\ingroup graphbits
+//\file
+//\brief Observer notifier for graph alteration observers.
+
+namespace lemon {
+
+  // \ingroup graphbits
+  //
+  // \brief Notifier class to notify observes about alterations in
+  // a container.
+  //
+  // The simple graphs can be refered as two containers: a node container
+  // and an edge container. But they do not store values directly, they
+  // are just key continars for more value containers, which are the
+  // node and edge maps.
+  //
+  // The node and edge sets of the graphs can be changed as we add or erase
+  // nodes and edges in the graph. LEMON would like to handle easily
+  // that the node and edge maps should contain values for all nodes or
+  // edges. If we want to check on every indicing if the map contains
+  // the current indicing key that cause a drawback in the performance
+  // in the library. We use another solution: we notify all maps about
+  // an alteration in the graph, which cause only drawback on the
+  // alteration of the graph.
+  //
+  // This class provides an interface to a node or edge container.
+  // The first() and next() member functions make possible
+  // to iterate on the keys of the container.
+  // The id() function returns an integer id for each key.
+  // The maxId() function gives back an upper bound of the ids.
+  //
+  // For the proper functonality of this class, we should notify it
+  // about each alteration in the container. The alterations have four type:
+  // add(), erase(), build() and clear(). The add() and
+  // erase() signal that only one or few items added or erased to or
+  // from the graph. If all items are erased from the graph or if a new graph
+  // is built from an empty graph, then it can be signaled with the
+  // clear() and build() members. Important rule that if we erase items
+  // from graphs we should first signal the alteration and after that erase
+  // them from the container, on the other way on item addition we should
+  // first extend the container and just after that signal the alteration.
+  //
+  // The alteration can be observed with a class inherited from the
+  // ObserverBase nested class. The signals can be handled with
+  // overriding the virtual functions defined in the base class.  The
+  // observer base can be attached to the notifier with the
+  // attach() member and can be detached with detach() function. The
+  // alteration handlers should not call any function which signals
+  // an other alteration in the same notifier and should not
+  // detach any observer from the notifier.
+  //
+  // Alteration observers try to be exception safe. If an add() or
+  // a clear() function throws an exception then the remaining
+  // observeres will not be notified and the fulfilled additions will
+  // be rolled back by calling the erase() or clear() functions.
+  // Hence erase() and clear() should not throw exception.
+  // Actullay, they can throw only \ref ImmediateDetach exception,
+  // which detach the observer from the notifier.
+  //
+  // There are some cases, when the alteration observing is not completly
+  // reliable. If we want to carry out the node degree in the graph
+  // as in the \ref InDegMap and we use the reverseArc(), then it cause
+  // unreliable functionality. Because the alteration observing signals
+  // only erasing and adding but not the reversing, it will stores bad
+  // degrees. Apart form that the subgraph adaptors cannot even signal
+  // the alterations because just a setting in the filter map can modify
+  // the graph and this cannot be watched in any way.
+  //
+  // \param _Container The container which is observed.
+  // \param _Item The item type which is obserbved.
+
+  template <typename _Container, typename _Item>
+  class AlterationNotifier {
+  public:
+
+    typedef True Notifier;
+
+    typedef _Container Container;
+    typedef _Item Item;
+
+    // \brief Exception which can be called from clear() and
+    // erase().
+    //
+    // From the clear() and erase() function only this
+    // exception is allowed to throw. The exception immediatly
+    // detaches the current observer from the notifier. Because the
+    // clear() and erase() should not throw other exceptions
+    // it can be used to invalidate the observer.
+    struct ImmediateDetach {};
+
+    // \brief ObserverBase is the base class for the observers.
+    //
+    // ObserverBase is the abstract base class for the observers.
+    // It will be notified about an item was inserted into or
+    // erased from the graph.
+    //
+    // The observer interface contains some pure virtual functions
+    // to override. The add() and erase() functions are
+    // to notify the oberver when one item is added or erased.
+    //
+    // The build() and clear() members are to notify the observer
+    // about the container is built from an empty container or
+    // is cleared to an empty container.
+    class ObserverBase {
+    protected:
+      typedef AlterationNotifier Notifier;
+
+      friend class AlterationNotifier;
+
+      // \brief Default constructor.
+      //
+      // Default constructor for ObserverBase.
+      ObserverBase() : _notifier(0) {}
+
+      // \brief Constructor which attach the observer into notifier.
+      //
+      // Constructor which attach the observer into notifier.
+      ObserverBase(AlterationNotifier& nf) {
+        attach(nf);
+      }
+
+      // \brief Constructor which attach the obserever to the same notifier.
+      //
+      // Constructor which attach the obserever to the same notifier as
+      // the other observer is attached to.
+      ObserverBase(const ObserverBase& copy) {
+        if (copy.attached()) {
+          attach(*copy.notifier());
+        }
+      }
+
+      // \brief Destructor
+      virtual ~ObserverBase() {
+        if (attached()) {
+          detach();
+        }
+      }
+
+      // \brief Attaches the observer into an AlterationNotifier.
+      //
+      // This member attaches the observer into an AlterationNotifier.
+      void attach(AlterationNotifier& nf) {
+        nf.attach(*this);
+      }
+
+      // \brief Detaches the observer into an AlterationNotifier.
+      //
+      // This member detaches the observer from an AlterationNotifier.
+      void detach() {
+        _notifier->detach(*this);
+      }
+
+      // \brief Gives back a pointer to the notifier which the map
+      // attached into.
+      //
+      // This function gives back a pointer to the notifier which the map
+      // attached into.
+      Notifier* notifier() const { return const_cast<Notifier*>(_notifier); }
+
+      // Gives back true when the observer is attached into a notifier.
+      bool attached() const { return _notifier != 0; }
+
+    private:
+
+      ObserverBase& operator=(const ObserverBase& copy);
+
+    protected:
+
+      Notifier* _notifier;
+      typename std::list<ObserverBase*>::iterator _index;
+
+      // \brief The member function to notificate the observer about an
+      // item is added to the container.
+      //
+      // The add() member function notificates the observer about an item
+      // is added to the container. It have to be overrided in the
+      // subclasses.
+      virtual void add(const Item&) = 0;
+
+      // \brief The member function to notificate the observer about
+      // more item is added to the container.
+      //
+      // The add() member function notificates the observer about more item
+      // is added to the container. It have to be overrided in the
+      // subclasses.
+      virtual void add(const std::vector<Item>& items) = 0;
+
+      // \brief The member function to notificate the observer about an
+      // item is erased from the container.
+      //
+      // The erase() member function notificates the observer about an
+      // item is erased from the container. It have to be overrided in
+      // the subclasses.
+      virtual void erase(const Item&) = 0;
+
+      // \brief The member function to notificate the observer about
+      // more item is erased from the container.
+      //
+      // The erase() member function notificates the observer about more item
+      // is erased from the container. It have to be overrided in the
+      // subclasses.
+      virtual void erase(const std::vector<Item>& items) = 0;
+
+      // \brief The member function to notificate the observer about the
+      // container is built.
+      //
+      // The build() member function notificates the observer about the
+      // container is built from an empty container. It have to be
+      // overrided in the subclasses.
+      virtual void build() = 0;
+
+      // \brief The member function to notificate the observer about all
+      // items are erased from the container.
+      //
+      // The clear() member function notificates the observer about all
+      // items are erased from the container. It have to be overrided in
+      // the subclasses.
+      virtual void clear() = 0;
+
+    };
+
+  protected:
+
+    const Container* container;
+
+    typedef std::list<ObserverBase*> Observers;
+    Observers _observers;
+    lemon::bits::Lock _lock;
+
+  public:
+
+    // \brief Default constructor.
+    //
+    // The default constructor of the AlterationNotifier.
+    // It creates an empty notifier.
+    AlterationNotifier()
+      : container(0) {}
+
+    // \brief Constructor.
+    //
+    // Constructor with the observed container parameter.
+    AlterationNotifier(const Container& _container)
+      : container(&_container) {}
+
+    // \brief Copy Constructor of the AlterationNotifier.
+    //
+    // Copy constructor of the AlterationNotifier.
+    // It creates only an empty notifier because the copiable
+    // notifier's observers have to be registered still into that notifier.
+    AlterationNotifier(const AlterationNotifier& _notifier)
+      : container(_notifier.container) {}
+
+    // \brief Destructor.
+    //
+    // Destructor of the AlterationNotifier.
+    ~AlterationNotifier() {
+      typename Observers::iterator it;
+      for (it = _observers.begin(); it != _observers.end(); ++it) {
+        (*it)->_notifier = 0;
+      }
+    }
+
+    // \brief Sets the container.
+    //
+    // Sets the container.
+    void setContainer(const Container& _container) {
+      container = &_container;
+    }
+
+  protected:
+
+    AlterationNotifier& operator=(const AlterationNotifier&);
+
+  public:
+
+    // \brief First item in the container.
+    //
+    // Returns the first item in the container. It is
+    // for start the iteration on the container.
+    void first(Item& item) const {
+      container->first(item);
+    }
+
+    // \brief Next item in the container.
+    //
+    // Returns the next item in the container. It is
+    // for iterate on the container.
+    void next(Item& item) const {
+      container->next(item);
+    }
+
+    // \brief Returns the id of the item.
+    //
+    // Returns the id of the item provided by the container.
+    int id(const Item& item) const {
+      return container->id(item);
+    }
+
+    // \brief Returns the maximum id of the container.
+    //
+    // Returns the maximum id of the container.
+    int maxId() const {
+      return container->maxId(Item());
+    }
+
+  protected:
+
+    void attach(ObserverBase& observer) {
+      _lock.lock();
+      observer._index = _observers.insert(_observers.begin(), &observer);
+      observer._notifier = this;
+      _lock.unlock();
+    }
+
+    void detach(ObserverBase& observer) {
+      _lock.lock();
+      _observers.erase(observer._index);
+      observer._index = _observers.end();
+      observer._notifier = 0;
+      _lock.unlock();
+    }
+
+  public:
+
+    // \brief Notifies all the registed observers about an item added to
+    // the container.
+    //
+    // It notifies all the registed observers about an item added to
+    // the container.
+    void add(const Item& item) {
+      typename Observers::reverse_iterator it;
+      try {
+        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
+          (*it)->add(item);
+        }
+      } catch (...) {
+        typename Observers::iterator jt;
+        for (jt = it.base(); jt != _observers.end(); ++jt) {
+          (*jt)->erase(item);
+        }
+        throw;
+      }
+    }
+
+    // \brief Notifies all the registed observers about more item added to
+    // the container.
+    //
+    // It notifies all the registed observers about more item added to
+    // the container.
+    void add(const std::vector<Item>& items) {
+      typename Observers::reverse_iterator it;
+      try {
+        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
+          (*it)->add(items);
+        }
+      } catch (...) {
+        typename Observers::iterator jt;
+        for (jt = it.base(); jt != _observers.end(); ++jt) {
+          (*jt)->erase(items);
+        }
+        throw;
+      }
+    }
+
+    // \brief Notifies all the registed observers about an item erased from
+    // the container.
+    //
+    // It notifies all the registed observers about an item erased from
+    // the container.
+    void erase(const Item& item) throw() {
+      typename Observers::iterator it = _observers.begin();
+      while (it != _observers.end()) {
+        try {
+          (*it)->erase(item);
+          ++it;
+        } catch (const ImmediateDetach&) {
+          (*it)->_index = _observers.end();
+          (*it)->_notifier = 0;
+          it = _observers.erase(it);
+        }
+      }
+    }
+
+    // \brief Notifies all the registed observers about more item erased
+    // from the container.
+    //
+    // It notifies all the registed observers about more item erased from
+    // the container.
+    void erase(const std::vector<Item>& items) {
+      typename Observers::iterator it = _observers.begin();
+      while (it != _observers.end()) {
+        try {
+          (*it)->erase(items);
+          ++it;
+        } catch (const ImmediateDetach&) {
+          (*it)->_index = _observers.end();
+          (*it)->_notifier = 0;
+          it = _observers.erase(it);
+        }
+      }
+    }
+
+    // \brief Notifies all the registed observers about the container is
+    // built.
+    //
+    // Notifies all the registed observers about the container is built
+    // from an empty container.
+    void build() {
+      typename Observers::reverse_iterator it;
+      try {
+        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
+          (*it)->build();
+        }
+      } catch (...) {
+        typename Observers::iterator jt;
+        for (jt = it.base(); jt != _observers.end(); ++jt) {
+          (*jt)->clear();
+        }
+        throw;
+      }
+    }
+
+    // \brief Notifies all the registed observers about all items are
+    // erased.
+    //
+    // Notifies all the registed observers about all items are erased
+    // from the container.
+    void clear() {
+      typename Observers::iterator it = _observers.begin();
+      while (it != _observers.end()) {
+        try {
+          (*it)->clear();
+          ++it;
+        } catch (const ImmediateDetach&) {
+          (*it)->_index = _observers.end();
+          (*it)->_notifier = 0;
+          it = _observers.erase(it);
+        }
+      }
+    }
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/array_map.h b/lemon/bits/array_map.h
new file mode 100644
index 0000000..355ee00
--- /dev/null
+++ b/lemon/bits/array_map.h
@@ -0,0 +1,351 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_ARRAY_MAP_H
+#define LEMON_BITS_ARRAY_MAP_H
+
+#include <memory>
+
+#include <lemon/bits/traits.h>
+#include <lemon/bits/alteration_notifier.h>
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
+
+// \ingroup graphbits
+// \file
+// \brief Graph map based on the array storage.
+
+namespace lemon {
+
+  // \ingroup graphbits
+  //
+  // \brief Graph map based on the array storage.
+  //
+  // The ArrayMap template class is graph map structure that automatically
+  // updates the map when a key is added to or erased from the graph.
+  // This map uses the allocators to implement the container functionality.
+  //
+  // The template parameters are the Graph, the current Item type and
+  // the Value type of the map.
+  template <typename _Graph, typename _Item, typename _Value>
+  class ArrayMap
+    : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
+  public:
+    // The graph type.
+    typedef _Graph GraphType;
+    // The item type.
+    typedef _Item Item;
+    // The reference map tag.
+    typedef True ReferenceMapTag;
+
+    // The key type of the map.
+    typedef _Item Key;
+    // The value type of the map.
+    typedef _Value Value;
+
+    // The const reference type of the map.
+    typedef const _Value& ConstReference;
+    // The reference type of the map.
+    typedef _Value& Reference;
+
+    // The map type.
+    typedef ArrayMap Map;
+
+    // The notifier type.
+    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
+
+  private:
+
+    // The MapBase of the Map which imlements the core regisitry function.
+    typedef typename Notifier::ObserverBase Parent;
+
+    typedef std::allocator<Value> Allocator;
+
+  public:
+
+    // \brief Graph initialized map constructor.
+    //
+    // Graph initialized map constructor.
+    explicit ArrayMap(const GraphType& graph) {
+      Parent::attach(graph.notifier(Item()));
+      allocate_memory();
+      Notifier* nf = Parent::notifier();
+      Item it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        int id = nf->id(it);;
+        allocator.construct(&(values[id]), Value());
+      }
+    }
+
+    // \brief Constructor to use default value to initialize the map.
+    //
+    // It constructs a map and initialize all of the the map.
+    ArrayMap(const GraphType& graph, const Value& value) {
+      Parent::attach(graph.notifier(Item()));
+      allocate_memory();
+      Notifier* nf = Parent::notifier();
+      Item it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        int id = nf->id(it);;
+        allocator.construct(&(values[id]), value);
+      }
+    }
+
+  private:
+    // \brief Constructor to copy a map of the same map type.
+    //
+    // Constructor to copy a map of the same map type.
+    ArrayMap(const ArrayMap& copy) : Parent() {
+      if (copy.attached()) {
+        attach(*copy.notifier());
+      }
+      capacity = copy.capacity;
+      if (capacity == 0) return;
+      values = allocator.allocate(capacity);
+      Notifier* nf = Parent::notifier();
+      Item it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        int id = nf->id(it);;
+        allocator.construct(&(values[id]), copy.values[id]);
+      }
+    }
+
+    // \brief Assign operator.
+    //
+    // This operator assigns for each item in the map the
+    // value mapped to the same item in the copied map.
+    // The parameter map should be indiced with the same
+    // itemset because this assign operator does not change
+    // the container of the map.
+    ArrayMap& operator=(const ArrayMap& cmap) {
+      return operator=<ArrayMap>(cmap);
+    }
+
+
+    // \brief Template assign operator.
+    //
+    // The given parameter should conform to the ReadMap
+    // concecpt and could be indiced by the current item set of
+    // the NodeMap. In this case the value for each item
+    // is assigned by the value of the given ReadMap.
+    template <typename CMap>
+    ArrayMap& operator=(const CMap& cmap) {
+      checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
+      const typename Parent::Notifier* nf = Parent::notifier();
+      Item it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        set(it, cmap[it]);
+      }
+      return *this;
+    }
+
+  public:
+    // \brief The destructor of the map.
+    //
+    // The destructor of the map.
+    virtual ~ArrayMap() {
+      if (attached()) {
+        clear();
+        detach();
+      }
+    }
+
+  protected:
+
+    using Parent::attach;
+    using Parent::detach;
+    using Parent::attached;
+
+  public:
+
+    // \brief The subscript operator.
+    //
+    // The subscript operator. The map can be subscripted by the
+    // actual keys of the graph.
+    Value& operator[](const Key& key) {
+      int id = Parent::notifier()->id(key);
+      return values[id];
+    }
+
+    // \brief The const subscript operator.
+    //
+    // The const subscript operator. The map can be subscripted by the
+    // actual keys of the graph.
+    const Value& operator[](const Key& key) const {
+      int id = Parent::notifier()->id(key);
+      return values[id];
+    }
+
+    // \brief Setter function of the map.
+    //
+    // Setter function of the map. Equivalent with map[key] = val.
+    // This is a compatibility feature with the not dereferable maps.
+    void set(const Key& key, const Value& val) {
+      (*this)[key] = val;
+    }
+
+  protected:
+
+    // \brief Adds a new key to the map.
+    //
+    // It adds a new key to the map. It is called by the observer notifier
+    // and it overrides the add() member function of the observer base.
+    virtual void add(const Key& key) {
+      Notifier* nf = Parent::notifier();
+      int id = nf->id(key);
+      if (id >= capacity) {
+        int new_capacity = (capacity == 0 ? 1 : capacity);
+        while (new_capacity <= id) {
+          new_capacity <<= 1;
+        }
+        Value* new_values = allocator.allocate(new_capacity);
+        Item it;
+        for (nf->first(it); it != INVALID; nf->next(it)) {
+          int jd = nf->id(it);;
+          if (id != jd) {
+            allocator.construct(&(new_values[jd]), values[jd]);
+            allocator.destroy(&(values[jd]));
+          }
+        }
+        if (capacity != 0) allocator.deallocate(values, capacity);
+        values = new_values;
+        capacity = new_capacity;
+      }
+      allocator.construct(&(values[id]), Value());
+    }
+
+    // \brief Adds more new keys to the map.
+    //
+    // It adds more new keys to the map. It is called by the observer notifier
+    // and it overrides the add() member function of the observer base.
+    virtual void add(const std::vector<Key>& keys) {
+      Notifier* nf = Parent::notifier();
+      int max_id = -1;
+      for (int i = 0; i < int(keys.size()); ++i) {
+        int id = nf->id(keys[i]);
+        if (id > max_id) {
+          max_id = id;
+        }
+      }
+      if (max_id >= capacity) {
+        int new_capacity = (capacity == 0 ? 1 : capacity);
+        while (new_capacity <= max_id) {
+          new_capacity <<= 1;
+        }
+        Value* new_values = allocator.allocate(new_capacity);
+        Item it;
+        for (nf->first(it); it != INVALID; nf->next(it)) {
+          int id = nf->id(it);
+          bool found = false;
+          for (int i = 0; i < int(keys.size()); ++i) {
+            int jd = nf->id(keys[i]);
+            if (id == jd) {
+              found = true;
+              break;
+            }
+          }
+          if (found) continue;
+          allocator.construct(&(new_values[id]), values[id]);
+          allocator.destroy(&(values[id]));
+        }
+        if (capacity != 0) allocator.deallocate(values, capacity);
+        values = new_values;
+        capacity = new_capacity;
+      }
+      for (int i = 0; i < int(keys.size()); ++i) {
+        int id = nf->id(keys[i]);
+        allocator.construct(&(values[id]), Value());
+      }
+    }
+
+    // \brief Erase a key from the map.
+    //
+    // Erase a key from the map. It is called by the observer notifier
+    // and it overrides the erase() member function of the observer base.
+    virtual void erase(const Key& key) {
+      int id = Parent::notifier()->id(key);
+      allocator.destroy(&(values[id]));
+    }
+
+    // \brief Erase more keys from the map.
+    //
+    // Erase more keys from the map. It is called by the observer notifier
+    // and it overrides the erase() member function of the observer base.
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        int id = Parent::notifier()->id(keys[i]);
+        allocator.destroy(&(values[id]));
+      }
+    }
+
+    // \brief Builds the map.
+    //
+    // It builds the map. It is called by the observer notifier
+    // and it overrides the build() member function of the observer base.
+    virtual void build() {
+      Notifier* nf = Parent::notifier();
+      allocate_memory();
+      Item it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        int id = nf->id(it);;
+        allocator.construct(&(values[id]), Value());
+      }
+    }
+
+    // \brief Clear the map.
+    //
+    // It erase all items from the map. It is called by the observer notifier
+    // and it overrides the clear() member function of the observer base.
+    virtual void clear() {
+      Notifier* nf = Parent::notifier();
+      if (capacity != 0) {
+        Item it;
+        for (nf->first(it); it != INVALID; nf->next(it)) {
+          int id = nf->id(it);
+          allocator.destroy(&(values[id]));
+        }
+        allocator.deallocate(values, capacity);
+        capacity = 0;
+      }
+    }
+
+  private:
+
+    void allocate_memory() {
+      int max_id = Parent::notifier()->maxId();
+      if (max_id == -1) {
+        capacity = 0;
+        values = 0;
+        return;
+      }
+      capacity = 1;
+      while (capacity <= max_id) {
+        capacity <<= 1;
+      }
+      values = allocator.allocate(capacity);
+    }
+
+    int capacity;
+    Value* values;
+    Allocator allocator;
+
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/bezier.h b/lemon/bits/bezier.h
new file mode 100644
index 0000000..9d8d141
--- /dev/null
+++ b/lemon/bits/bezier.h
@@ -0,0 +1,174 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_BEZIER_H
+#define LEMON_BEZIER_H
+
+//\ingroup misc
+//\file
+//\brief Classes to compute with Bezier curves.
+//
+//Up to now this file is used internally by \ref graph_to_eps.h
+
+#include<lemon/dim2.h>
+
+namespace lemon {
+  namespace dim2 {
+
+class BezierBase {
+public:
+  typedef lemon::dim2::Point<double> Point;
+protected:
+  static Point conv(Point x,Point y,double t) {return (1-t)*x+t*y;}
+};
+
+class Bezier1 : public BezierBase
+{
+public:
+  Point p1,p2;
+
+  Bezier1() {}
+  Bezier1(Point _p1, Point _p2) :p1(_p1), p2(_p2) {}
+
+  Point operator()(double t) const
+  {
+    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
+    return conv(p1,p2,t);
+  }
+  Bezier1 before(double t) const
+  {
+    return Bezier1(p1,conv(p1,p2,t));
+  }
+
+  Bezier1 after(double t) const
+  {
+    return Bezier1(conv(p1,p2,t),p2);
+  }
+
+  Bezier1 revert() const { return Bezier1(p2,p1);}
+  Bezier1 operator()(double a,double b) const { return before(b).after(a/b); }
+  Point grad() const { return p2-p1; }
+  Point norm() const { return rot90(p2-p1); }
+  Point grad(double) const { return grad(); }
+  Point norm(double t) const { return rot90(grad(t)); }
+};
+
+class Bezier2 : public BezierBase
+{
+public:
+  Point p1,p2,p3;
+
+  Bezier2() {}
+  Bezier2(Point _p1, Point _p2, Point _p3) :p1(_p1), p2(_p2), p3(_p3) {}
+  Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
+  Point operator()(double t) const
+  {
+    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
+    return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
+  }
+  Bezier2 before(double t) const
+  {
+    Point q(conv(p1,p2,t));
+    Point r(conv(p2,p3,t));
+    return Bezier2(p1,q,conv(q,r,t));
+  }
+
+  Bezier2 after(double t) const
+  {
+    Point q(conv(p1,p2,t));
+    Point r(conv(p2,p3,t));
+    return Bezier2(conv(q,r,t),r,p3);
+  }
+  Bezier2 revert() const { return Bezier2(p3,p2,p1);}
+  Bezier2 operator()(double a,double b) const { return before(b).after(a/b); }
+  Bezier1 grad() const { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
+  Bezier1 norm() const { return Bezier1(2.0*rot90(p2-p1),2.0*rot90(p3-p2)); }
+  Point grad(double t) const { return grad()(t); }
+  Point norm(double t) const { return rot90(grad(t)); }
+};
+
+class Bezier3 : public BezierBase
+{
+public:
+  Point p1,p2,p3,p4;
+
+  Bezier3() {}
+  Bezier3(Point _p1, Point _p2, Point _p3, Point _p4)
+    : p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
+  Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)),
+                              p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
+  Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
+                              p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
+
+  Point operator()(double t) const
+    {
+      //    return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
+      return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
+        (3*t*t*(1-t))*p3+(t*t*t)*p4;
+    }
+  Bezier3 before(double t) const
+    {
+      Point p(conv(p1,p2,t));
+      Point q(conv(p2,p3,t));
+      Point r(conv(p3,p4,t));
+      Point a(conv(p,q,t));
+      Point b(conv(q,r,t));
+      Point c(conv(a,b,t));
+      return Bezier3(p1,p,a,c);
+    }
+
+  Bezier3 after(double t) const
+    {
+      Point p(conv(p1,p2,t));
+      Point q(conv(p2,p3,t));
+      Point r(conv(p3,p4,t));
+      Point a(conv(p,q,t));
+      Point b(conv(q,r,t));
+      Point c(conv(a,b,t));
+      return Bezier3(c,b,r,p4);
+    }
+  Bezier3 revert() const { return Bezier3(p4,p3,p2,p1);}
+  Bezier3 operator()(double a,double b) const { return before(b).after(a/b); }
+  Bezier2 grad() const { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
+  Bezier2 norm() const { return Bezier2(3.0*rot90(p2-p1),
+                                  3.0*rot90(p3-p2),
+                                  3.0*rot90(p4-p3)); }
+  Point grad(double t) const { return grad()(t); }
+  Point norm(double t) const { return rot90(grad(t)); }
+
+  template<class R,class F,class S,class D>
+  R recSplit(F &_f,const S &_s,D _d) const
+  {
+    const Point a=(p1+p2)/2;
+    const Point b=(p2+p3)/2;
+    const Point c=(p3+p4)/2;
+    const Point d=(a+b)/2;
+    const Point e=(b+c)/2;
+    // const Point f=(d+e)/2;
+    R f1=_f(Bezier3(p1,a,d,e),_d);
+    R f2=_f(Bezier3(e,d,c,p4),_d);
+    return _s(f1,f2);
+  }
+
+};
+
+
+} //END OF NAMESPACE dim2
+} //END OF NAMESPACE lemon
+
+#endif // LEMON_BEZIER_H
diff --git a/lemon/bits/default_map.h b/lemon/bits/default_map.h
new file mode 100644
index 0000000..23728e4
--- /dev/null
+++ b/lemon/bits/default_map.h
@@ -0,0 +1,182 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_DEFAULT_MAP_H
+#define LEMON_BITS_DEFAULT_MAP_H
+
+#include <lemon/config.h>
+#include <lemon/bits/array_map.h>
+#include <lemon/bits/vector_map.h>
+//#include <lemon/bits/debug_map.h>
+
+//\ingroup graphbits
+//\file
+//\brief Graph maps that construct and destruct their elements dynamically.
+
+namespace lemon {
+
+
+  //#ifndef LEMON_USE_DEBUG_MAP
+
+  template <typename _Graph, typename _Item, typename _Value>
+  struct DefaultMapSelector {
+    typedef ArrayMap<_Graph, _Item, _Value> Map;
+  };
+
+  // bool
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, bool> {
+    typedef VectorMap<_Graph, _Item, bool> Map;
+  };
+
+  // char
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, char> {
+    typedef VectorMap<_Graph, _Item, char> Map;
+  };
+
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, signed char> {
+    typedef VectorMap<_Graph, _Item, signed char> Map;
+  };
+
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, unsigned char> {
+    typedef VectorMap<_Graph, _Item, unsigned char> Map;
+  };
+
+
+  // int
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, signed int> {
+    typedef VectorMap<_Graph, _Item, signed int> Map;
+  };
+
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, unsigned int> {
+    typedef VectorMap<_Graph, _Item, unsigned int> Map;
+  };
+
+
+  // short
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, signed short> {
+    typedef VectorMap<_Graph, _Item, signed short> Map;
+  };
+
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, unsigned short> {
+    typedef VectorMap<_Graph, _Item, unsigned short> Map;
+  };
+
+
+  // long
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, signed long> {
+    typedef VectorMap<_Graph, _Item, signed long> Map;
+  };
+
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, unsigned long> {
+    typedef VectorMap<_Graph, _Item, unsigned long> Map;
+  };
+
+
+#if defined LEMON_HAVE_LONG_LONG
+
+  // long long
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, signed long long> {
+    typedef VectorMap<_Graph, _Item, signed long long> Map;
+  };
+
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, unsigned long long> {
+    typedef VectorMap<_Graph, _Item, unsigned long long> Map;
+  };
+
+#endif
+
+
+  // float
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, float> {
+    typedef VectorMap<_Graph, _Item, float> Map;
+  };
+
+
+  // double
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, double> {
+    typedef VectorMap<_Graph, _Item,  double> Map;
+  };
+
+
+  // long double
+  template <typename _Graph, typename _Item>
+  struct DefaultMapSelector<_Graph, _Item, long double> {
+    typedef VectorMap<_Graph, _Item, long double> Map;
+  };
+
+
+  // pointer
+  template <typename _Graph, typename _Item, typename _Ptr>
+  struct DefaultMapSelector<_Graph, _Item, _Ptr*> {
+    typedef VectorMap<_Graph, _Item, _Ptr*> Map;
+  };
+
+// #else
+
+//   template <typename _Graph, typename _Item, typename _Value>
+//   struct DefaultMapSelector {
+//     typedef DebugMap<_Graph, _Item, _Value> Map;
+//   };
+
+// #endif
+
+  // DefaultMap class
+  template <typename _Graph, typename _Item, typename _Value>
+  class DefaultMap
+    : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
+    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
+
+  public:
+    typedef DefaultMap<_Graph, _Item, _Value> Map;
+
+    typedef typename Parent::GraphType GraphType;
+    typedef typename Parent::Value Value;
+
+    explicit DefaultMap(const GraphType& graph) : Parent(graph) {}
+    DefaultMap(const GraphType& graph, const Value& value)
+      : Parent(graph, value) {}
+
+    DefaultMap& operator=(const DefaultMap& cmap) {
+      return operator=<DefaultMap>(cmap);
+    }
+
+    template <typename CMap>
+    DefaultMap& operator=(const CMap& cmap) {
+      Parent::operator=(cmap);
+      return *this;
+    }
+
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/edge_set_extender.h b/lemon/bits/edge_set_extender.h
new file mode 100644
index 0000000..364ca2e
--- /dev/null
+++ b/lemon/bits/edge_set_extender.h
@@ -0,0 +1,627 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_EDGE_SET_EXTENDER_H
+#define LEMON_BITS_EDGE_SET_EXTENDER_H
+
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/bits/default_map.h>
+#include <lemon/bits/map_extender.h>
+
+//\ingroup digraphbits
+//\file
+//\brief Extenders for the arc set types
+namespace lemon {
+
+  // \ingroup digraphbits
+  //
+  // \brief Extender for the ArcSets
+  template <typename Base>
+  class ArcSetExtender : public Base {
+    typedef Base Parent;
+
+  public:
+
+    typedef ArcSetExtender Digraph;
+
+    // Base extensions
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    Node fromId(int id, Node) const {
+      return Parent::nodeFromId(id);
+    }
+
+    Arc fromId(int id, Arc) const {
+      return Parent::arcFromId(id);
+    }
+
+    Node oppositeNode(const Node &n, const Arc &e) const {
+      if (n == Parent::source(e))
+        return Parent::target(e);
+      else if(n==Parent::target(e))
+        return Parent::source(e);
+      else
+        return INVALID;
+    }
+
+
+    // Alteration notifier extensions
+
+    // The arc observer registry.
+    typedef AlterationNotifier<ArcSetExtender, Arc> ArcNotifier;
+
+  protected:
+
+    mutable ArcNotifier arc_notifier;
+
+  public:
+
+    using Parent::notifier;
+
+    // Gives back the arc alteration notifier.
+    ArcNotifier& notifier(Arc) const {
+      return arc_notifier;
+    }
+
+    // Iterable extensions
+
+    class NodeIt : public Node {
+      const Digraph* digraph;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
+        _graph.first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Digraph& _graph, const Node& node)
+        : Node(node), digraph(&_graph) {}
+
+      NodeIt& operator++() {
+        digraph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Digraph* digraph;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
+        _graph.first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Digraph& _graph, const Arc& e) :
+        Arc(e), digraph(&_graph) { }
+
+      ArcIt& operator++() {
+        digraph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Digraph* digraph;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const Digraph& _graph, const Node& node)
+        : digraph(&_graph) {
+        _graph.firstOut(*this, node);
+      }
+
+      OutArcIt(const Digraph& _graph, const Arc& arc)
+        : Arc(arc), digraph(&_graph) {}
+
+      OutArcIt& operator++() {
+        digraph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Digraph* digraph;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const Digraph& _graph, const Node& node)
+        : digraph(&_graph) {
+        _graph.firstIn(*this, node);
+      }
+
+      InArcIt(const Digraph& _graph, const Arc& arc) :
+        Arc(arc), digraph(&_graph) {}
+
+      InArcIt& operator++() {
+        digraph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the source in this case) of the iterator
+    Node baseNode(const OutArcIt &e) const {
+      return Parent::source(static_cast<const Arc&>(e));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the target in this case) of the
+    // iterator
+    Node runningNode(const OutArcIt &e) const {
+      return Parent::target(static_cast<const Arc&>(e));
+    }
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the target in this case) of the iterator
+    Node baseNode(const InArcIt &e) const {
+      return Parent::target(static_cast<const Arc&>(e));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the source in this case) of the
+    // iterator
+    Node runningNode(const InArcIt &e) const {
+      return Parent::source(static_cast<const Arc&>(e));
+    }
+
+    using Parent::first;
+
+    // Mappable extension
+
+    template <typename _Value>
+    class ArcMap
+      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
+      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
+
+    public:
+      explicit ArcMap(const Digraph& _g)
+        : Parent(_g) {}
+      ArcMap(const Digraph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
+
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+
+    // Alteration extension
+
+    Arc addArc(const Node& from, const Node& to) {
+      Arc arc = Parent::addArc(from, to);
+      notifier(Arc()).add(arc);
+      return arc;
+    }
+
+    void clear() {
+      notifier(Arc()).clear();
+      Parent::clear();
+    }
+
+    void erase(const Arc& arc) {
+      notifier(Arc()).erase(arc);
+      Parent::erase(arc);
+    }
+
+    ArcSetExtender() {
+      arc_notifier.setContainer(*this);
+    }
+
+    ~ArcSetExtender() {
+      arc_notifier.clear();
+    }
+
+  };
+
+
+  // \ingroup digraphbits
+  //
+  // \brief Extender for the EdgeSets
+  template <typename Base>
+  class EdgeSetExtender : public Base {
+    typedef Base Parent;
+
+  public:
+
+    typedef EdgeSetExtender Graph;
+
+    typedef True UndirectedTag;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    int maxId(Edge) const {
+      return Parent::maxEdgeId();
+    }
+
+    Node fromId(int id, Node) const {
+      return Parent::nodeFromId(id);
+    }
+
+    Arc fromId(int id, Arc) const {
+      return Parent::arcFromId(id);
+    }
+
+    Edge fromId(int id, Edge) const {
+      return Parent::edgeFromId(id);
+    }
+
+    Node oppositeNode(const Node &n, const Edge &e) const {
+      if( n == Parent::u(e))
+        return Parent::v(e);
+      else if( n == Parent::v(e))
+        return Parent::u(e);
+      else
+        return INVALID;
+    }
+
+    Arc oppositeArc(const Arc &e) const {
+      return Parent::direct(e, !Parent::direction(e));
+    }
+
+    using Parent::direct;
+    Arc direct(const Edge &e, const Node &s) const {
+      return Parent::direct(e, Parent::u(e) == s);
+    }
+
+    typedef AlterationNotifier<EdgeSetExtender, Arc> ArcNotifier;
+    typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
+
+
+  protected:
+
+    mutable ArcNotifier arc_notifier;
+    mutable EdgeNotifier edge_notifier;
+
+  public:
+
+    using Parent::notifier;
+
+    ArcNotifier& notifier(Arc) const {
+      return arc_notifier;
+    }
+
+    EdgeNotifier& notifier(Edge) const {
+      return edge_notifier;
+    }
+
+
+    class NodeIt : public Node {
+      const Graph* graph;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const Graph& _graph) : graph(&_graph) {
+        _graph.first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Graph& _graph, const Node& node)
+        : Node(node), graph(&_graph) {}
+
+      NodeIt& operator++() {
+        graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Graph* graph;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const Graph& _graph) : graph(&_graph) {
+        _graph.first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Graph& _graph, const Arc& e) :
+        Arc(e), graph(&_graph) { }
+
+      ArcIt& operator++() {
+        graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Graph* graph;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const Graph& _graph, const Node& node)
+        : graph(&_graph) {
+        _graph.firstOut(*this, node);
+      }
+
+      OutArcIt(const Graph& _graph, const Arc& arc)
+        : Arc(arc), graph(&_graph) {}
+
+      OutArcIt& operator++() {
+        graph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Graph* graph;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const Graph& _graph, const Node& node)
+        : graph(&_graph) {
+        _graph.firstIn(*this, node);
+      }
+
+      InArcIt(const Graph& _graph, const Arc& arc) :
+        Arc(arc), graph(&_graph) {}
+
+      InArcIt& operator++() {
+        graph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+
+    class EdgeIt : public Parent::Edge {
+      const Graph* graph;
+    public:
+
+      EdgeIt() { }
+
+      EdgeIt(Invalid i) : Edge(i) { }
+
+      explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
+        _graph.first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const Graph& _graph, const Edge& e) :
+        Edge(e), graph(&_graph) { }
+
+      EdgeIt& operator++() {
+        graph->next(*this);
+        return *this;
+      }
+
+    };
+
+    class IncEdgeIt : public Parent::Edge {
+      friend class EdgeSetExtender;
+      const Graph* graph;
+      bool direction;
+    public:
+
+      IncEdgeIt() { }
+
+      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
+
+      IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
+        _graph.firstInc(*this, direction, n);
+      }
+
+      IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
+        : graph(&_graph), Edge(ue) {
+        direction = (_graph.source(ue) == n);
+      }
+
+      IncEdgeIt& operator++() {
+        graph->nextInc(*this, direction);
+        return *this;
+      }
+    };
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the source in this case) of the iterator
+    Node baseNode(const OutArcIt &e) const {
+      return Parent::source(static_cast<const Arc&>(e));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the target in this case) of the
+    // iterator
+    Node runningNode(const OutArcIt &e) const {
+      return Parent::target(static_cast<const Arc&>(e));
+    }
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the target in this case) of the iterator
+    Node baseNode(const InArcIt &e) const {
+      return Parent::target(static_cast<const Arc&>(e));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the source in this case) of the
+    // iterator
+    Node runningNode(const InArcIt &e) const {
+      return Parent::source(static_cast<const Arc&>(e));
+    }
+
+    // Base node of the iterator
+    //
+    // Returns the base node of the iterator
+    Node baseNode(const IncEdgeIt &e) const {
+      return e.direction ? this->u(e) : this->v(e);
+    }
+    // Running node of the iterator
+    //
+    // Returns the running node of the iterator
+    Node runningNode(const IncEdgeIt &e) const {
+      return e.direction ? this->v(e) : this->u(e);
+    }
+
+
+    template <typename _Value>
+    class ArcMap
+      : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
+      typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
+
+    public:
+      explicit ArcMap(const Graph& _g)
+        : Parent(_g) {}
+      ArcMap(const Graph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
+
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+
+    template <typename _Value>
+    class EdgeMap
+      : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
+      typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
+
+    public:
+      explicit EdgeMap(const Graph& _g)
+        : Parent(_g) {}
+
+      EdgeMap(const Graph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
+
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+
+    // Alteration extension
+
+    Edge addEdge(const Node& from, const Node& to) {
+      Edge edge = Parent::addEdge(from, to);
+      notifier(Edge()).add(edge);
+      std::vector<Arc> arcs;
+      arcs.push_back(Parent::direct(edge, true));
+      arcs.push_back(Parent::direct(edge, false));
+      notifier(Arc()).add(arcs);
+      return edge;
+    }
+
+    void clear() {
+      notifier(Arc()).clear();
+      notifier(Edge()).clear();
+      Parent::clear();
+    }
+
+    void erase(const Edge& edge) {
+      std::vector<Arc> arcs;
+      arcs.push_back(Parent::direct(edge, true));
+      arcs.push_back(Parent::direct(edge, false));
+      notifier(Arc()).erase(arcs);
+      notifier(Edge()).erase(edge);
+      Parent::erase(edge);
+    }
+
+
+    EdgeSetExtender() {
+      arc_notifier.setContainer(*this);
+      edge_notifier.setContainer(*this);
+    }
+
+    ~EdgeSetExtender() {
+      edge_notifier.clear();
+      arc_notifier.clear();
+    }
+
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/enable_if.h b/lemon/bits/enable_if.h
new file mode 100644
index 0000000..f0d8de4
--- /dev/null
+++ b/lemon/bits/enable_if.h
@@ -0,0 +1,131 @@
+/* -*- 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.
+ *
+ */
+
+// This file contains a modified version of the enable_if library from BOOST.
+// See the appropriate copyright notice below.
+
+// Boost enable_if library
+
+// Copyright 2003 (c) The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
+//             Jeremiah Willcock (jewillco at osl.iu.edu)
+//             Andrew Lumsdaine (lums at osl.iu.edu)
+
+
+#ifndef LEMON_BITS_ENABLE_IF_H
+#define LEMON_BITS_ENABLE_IF_H
+
+//\file
+//\brief Miscellaneous basic utilities
+
+namespace lemon
+{
+
+  // Basic type for defining "tags". A "YES" condition for \c enable_if.
+
+  // Basic type for defining "tags". A "YES" condition for \c enable_if.
+  //
+  //\sa False
+  struct True {
+    //\e
+    static const bool value = true;
+  };
+
+  // Basic type for defining "tags". A "NO" condition for \c enable_if.
+
+  // Basic type for defining "tags". A "NO" condition for \c enable_if.
+  //
+  //\sa True
+  struct False {
+    //\e
+    static const bool value = false;
+  };
+
+
+
+  template <typename T>
+  struct Wrap {
+    const T &value;
+    Wrap(const T &t) : value(t) {}
+  };
+
+  /**************** dummy class to avoid ambiguity ****************/
+
+  template<int T> struct dummy { dummy(int) {} };
+
+  /**************** enable_if from BOOST ****************/
+
+  template <typename Type, typename T = void>
+  struct exists {
+    typedef T type;
+  };
+
+
+  template <bool B, class T = void>
+  struct enable_if_c {
+    typedef T type;
+  };
+
+  template <class T>
+  struct enable_if_c<false, T> {};
+
+  template <class Cond, class T = void>
+  struct enable_if : public enable_if_c<Cond::value, T> {};
+
+  template <bool B, class T>
+  struct lazy_enable_if_c {
+    typedef typename T::type type;
+  };
+
+  template <class T>
+  struct lazy_enable_if_c<false, T> {};
+
+  template <class Cond, class T>
+  struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
+
+
+  template <bool B, class T = void>
+  struct disable_if_c {
+    typedef T type;
+  };
+
+  template <class T>
+  struct disable_if_c<true, T> {};
+
+  template <class Cond, class T = void>
+  struct disable_if : public disable_if_c<Cond::value, T> {};
+
+  template <bool B, class T>
+  struct lazy_disable_if_c {
+    typedef typename T::type type;
+  };
+
+  template <class T>
+  struct lazy_disable_if_c<true, T> {};
+
+  template <class Cond, class T>
+  struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
+
+} // namespace lemon
+
+#endif
diff --git a/lemon/bits/graph_adaptor_extender.h b/lemon/bits/graph_adaptor_extender.h
new file mode 100644
index 0000000..c38c8e1
--- /dev/null
+++ b/lemon/bits/graph_adaptor_extender.h
@@ -0,0 +1,401 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
+#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
+
+#include <lemon/core.h>
+#include <lemon/error.h>
+
+namespace lemon {
+
+  template <typename _Digraph>
+  class DigraphAdaptorExtender : public _Digraph {
+    typedef _Digraph Parent;
+
+  public:
+
+    typedef _Digraph Digraph;
+    typedef DigraphAdaptorExtender Adaptor;
+
+    // Base extensions
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    Node fromId(int id, Node) const {
+      return Parent::nodeFromId(id);
+    }
+
+    Arc fromId(int id, Arc) const {
+      return Parent::arcFromId(id);
+    }
+
+    Node oppositeNode(const Node &n, const Arc &e) const {
+      if (n == Parent::source(e))
+        return Parent::target(e);
+      else if(n==Parent::target(e))
+        return Parent::source(e);
+      else
+        return INVALID;
+    }
+
+    class NodeIt : public Node {
+      const Adaptor* _adaptor;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Adaptor& adaptor, const Node& node)
+        : Node(node), _adaptor(&adaptor) {}
+
+      NodeIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Adaptor& adaptor, const Arc& e) :
+        Arc(e), _adaptor(&adaptor) { }
+
+      ArcIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const Adaptor& adaptor, const Node& node)
+        : _adaptor(&adaptor) {
+        _adaptor->firstOut(*this, node);
+      }
+
+      OutArcIt(const Adaptor& adaptor, const Arc& arc)
+        : Arc(arc), _adaptor(&adaptor) {}
+
+      OutArcIt& operator++() {
+        _adaptor->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const Adaptor& adaptor, const Node& node)
+        : _adaptor(&adaptor) {
+        _adaptor->firstIn(*this, node);
+      }
+
+      InArcIt(const Adaptor& adaptor, const Arc& arc) :
+        Arc(arc), _adaptor(&adaptor) {}
+
+      InArcIt& operator++() {
+        _adaptor->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+    Node baseNode(const OutArcIt &e) const {
+      return Parent::source(e);
+    }
+    Node runningNode(const OutArcIt &e) const {
+      return Parent::target(e);
+    }
+
+    Node baseNode(const InArcIt &e) const {
+      return Parent::target(e);
+    }
+    Node runningNode(const InArcIt &e) const {
+      return Parent::source(e);
+    }
+
+  };
+
+  template <typename _Graph>
+  class GraphAdaptorExtender : public _Graph {
+    typedef _Graph Parent;
+
+  public:
+
+    typedef _Graph Graph;
+    typedef GraphAdaptorExtender Adaptor;
+
+    typedef True UndirectedTag;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    // Graph extension
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    int maxId(Edge) const {
+      return Parent::maxEdgeId();
+    }
+
+    Node fromId(int id, Node) const {
+      return Parent::nodeFromId(id);
+    }
+
+    Arc fromId(int id, Arc) const {
+      return Parent::arcFromId(id);
+    }
+
+    Edge fromId(int id, Edge) const {
+      return Parent::edgeFromId(id);
+    }
+
+    Node oppositeNode(const Node &n, const Edge &e) const {
+      if( n == Parent::u(e))
+        return Parent::v(e);
+      else if( n == Parent::v(e))
+        return Parent::u(e);
+      else
+        return INVALID;
+    }
+
+    Arc oppositeArc(const Arc &a) const {
+      return Parent::direct(a, !Parent::direction(a));
+    }
+
+    using Parent::direct;
+    Arc direct(const Edge &e, const Node &s) const {
+      return Parent::direct(e, Parent::u(e) == s);
+    }
+
+
+    class NodeIt : public Node {
+      const Adaptor* _adaptor;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Adaptor& adaptor, const Node& node)
+        : Node(node), _adaptor(&adaptor) {}
+
+      NodeIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Adaptor& adaptor, const Arc& e) :
+        Arc(e), _adaptor(&adaptor) { }
+
+      ArcIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const Adaptor& adaptor, const Node& node)
+        : _adaptor(&adaptor) {
+        _adaptor->firstOut(*this, node);
+      }
+
+      OutArcIt(const Adaptor& adaptor, const Arc& arc)
+        : Arc(arc), _adaptor(&adaptor) {}
+
+      OutArcIt& operator++() {
+        _adaptor->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const Adaptor& adaptor, const Node& node)
+        : _adaptor(&adaptor) {
+        _adaptor->firstIn(*this, node);
+      }
+
+      InArcIt(const Adaptor& adaptor, const Arc& arc) :
+        Arc(arc), _adaptor(&adaptor) {}
+
+      InArcIt& operator++() {
+        _adaptor->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+    class EdgeIt : public Parent::Edge {
+      const Adaptor* _adaptor;
+    public:
+
+      EdgeIt() { }
+
+      EdgeIt(Invalid i) : Edge(i) { }
+
+      explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const Adaptor& adaptor, const Edge& e) :
+        Edge(e), _adaptor(&adaptor) { }
+
+      EdgeIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+    class IncEdgeIt : public Edge {
+      friend class GraphAdaptorExtender;
+      const Adaptor* _adaptor;
+      bool direction;
+    public:
+
+      IncEdgeIt() { }
+
+      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
+
+      IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) {
+        _adaptor->firstInc(static_cast<Edge&>(*this), direction, n);
+      }
+
+      IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n)
+        : _adaptor(&adaptor), Edge(e) {
+        direction = (_adaptor->u(e) == n);
+      }
+
+      IncEdgeIt& operator++() {
+        _adaptor->nextInc(*this, direction);
+        return *this;
+      }
+    };
+
+    Node baseNode(const OutArcIt &a) const {
+      return Parent::source(a);
+    }
+    Node runningNode(const OutArcIt &a) const {
+      return Parent::target(a);
+    }
+
+    Node baseNode(const InArcIt &a) const {
+      return Parent::target(a);
+    }
+    Node runningNode(const InArcIt &a) const {
+      return Parent::source(a);
+    }
+
+    Node baseNode(const IncEdgeIt &e) const {
+      return e.direction ? Parent::u(e) : Parent::v(e);
+    }
+    Node runningNode(const IncEdgeIt &e) const {
+      return e.direction ? Parent::v(e) : Parent::u(e);
+    }
+
+  };
+
+}
+
+
+#endif
diff --git a/lemon/bits/graph_extender.h b/lemon/bits/graph_extender.h
new file mode 100644
index 0000000..755a890
--- /dev/null
+++ b/lemon/bits/graph_extender.h
@@ -0,0 +1,1332 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_GRAPH_EXTENDER_H
+#define LEMON_BITS_GRAPH_EXTENDER_H
+
+#include <lemon/core.h>
+
+#include <lemon/bits/map_extender.h>
+#include <lemon/bits/default_map.h>
+
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
+
+//\ingroup graphbits
+//\file
+//\brief Extenders for the graph types
+namespace lemon {
+
+  // \ingroup graphbits
+  //
+  // \brief Extender for the digraph implementations
+  template <typename Base>
+  class DigraphExtender : public Base {
+    typedef Base Parent;
+
+  public:
+
+    typedef DigraphExtender Digraph;
+
+    // Base extensions
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    static Node fromId(int id, Node) {
+      return Parent::nodeFromId(id);
+    }
+
+    static Arc fromId(int id, Arc) {
+      return Parent::arcFromId(id);
+    }
+
+    Node oppositeNode(const Node &node, const Arc &arc) const {
+      if (node == Parent::source(arc))
+        return Parent::target(arc);
+      else if(node == Parent::target(arc))
+        return Parent::source(arc);
+      else
+        return INVALID;
+    }
+
+    // Alterable extension
+
+    typedef AlterationNotifier<DigraphExtender, Node> NodeNotifier;
+    typedef AlterationNotifier<DigraphExtender, Arc> ArcNotifier;
+
+
+  protected:
+
+    mutable NodeNotifier node_notifier;
+    mutable ArcNotifier arc_notifier;
+
+  public:
+
+    NodeNotifier& notifier(Node) const {
+      return node_notifier;
+    }
+
+    ArcNotifier& notifier(Arc) const {
+      return arc_notifier;
+    }
+
+    class NodeIt : public Node {
+      const Digraph* _digraph;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const Digraph& digraph) : _digraph(&digraph) {
+        _digraph->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Digraph& digraph, const Node& node)
+        : Node(node), _digraph(&digraph) {}
+
+      NodeIt& operator++() {
+        _digraph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Digraph* _digraph;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const Digraph& digraph) : _digraph(&digraph) {
+        _digraph->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Digraph& digraph, const Arc& arc) :
+        Arc(arc), _digraph(&digraph) { }
+
+      ArcIt& operator++() {
+        _digraph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Digraph* _digraph;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const Digraph& digraph, const Node& node)
+        : _digraph(&digraph) {
+        _digraph->firstOut(*this, node);
+      }
+
+      OutArcIt(const Digraph& digraph, const Arc& arc)
+        : Arc(arc), _digraph(&digraph) {}
+
+      OutArcIt& operator++() {
+        _digraph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Digraph* _digraph;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const Digraph& digraph, const Node& node)
+        : _digraph(&digraph) {
+        _digraph->firstIn(*this, node);
+      }
+
+      InArcIt(const Digraph& digraph, const Arc& arc) :
+        Arc(arc), _digraph(&digraph) {}
+
+      InArcIt& operator++() {
+        _digraph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (i.e. the source in this case) of the iterator
+    Node baseNode(const OutArcIt &arc) const {
+      return Parent::source(arc);
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (i.e. the target in this case) of the
+    // iterator
+    Node runningNode(const OutArcIt &arc) const {
+      return Parent::target(arc);
+    }
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (i.e. the target in this case) of the iterator
+    Node baseNode(const InArcIt &arc) const {
+      return Parent::target(arc);
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (i.e. the source in this case) of the
+    // iterator
+    Node runningNode(const InArcIt &arc) const {
+      return Parent::source(arc);
+    }
+
+
+    template <typename _Value>
+    class NodeMap
+      : public MapExtender<DefaultMap<Digraph, Node, _Value> > {
+      typedef MapExtender<DefaultMap<Digraph, Node, _Value> > Parent;
+
+    public:
+      explicit NodeMap(const Digraph& digraph)
+        : Parent(digraph) {}
+      NodeMap(const Digraph& digraph, const _Value& value)
+        : Parent(digraph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap
+      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
+      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
+
+    public:
+      explicit ArcMap(const Digraph& digraph)
+        : Parent(digraph) {}
+      ArcMap(const Digraph& digraph, const _Value& value)
+        : Parent(digraph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+
+    Node addNode() {
+      Node node = Parent::addNode();
+      notifier(Node()).add(node);
+      return node;
+    }
+
+    Arc addArc(const Node& from, const Node& to) {
+      Arc arc = Parent::addArc(from, to);
+      notifier(Arc()).add(arc);
+      return arc;
+    }
+
+    void clear() {
+      notifier(Arc()).clear();
+      notifier(Node()).clear();
+      Parent::clear();
+    }
+
+    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
+    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
+      Parent::build(digraph, nodeRef, arcRef);
+      notifier(Node()).build();
+      notifier(Arc()).build();
+    }
+
+    void erase(const Node& node) {
+      Arc arc;
+      Parent::firstOut(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstOut(arc, node);
+      }
+
+      Parent::firstIn(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstIn(arc, node);
+      }
+
+      notifier(Node()).erase(node);
+      Parent::erase(node);
+    }
+
+    void erase(const Arc& arc) {
+      notifier(Arc()).erase(arc);
+      Parent::erase(arc);
+    }
+
+    DigraphExtender() {
+      node_notifier.setContainer(*this);
+      arc_notifier.setContainer(*this);
+    }
+
+
+    ~DigraphExtender() {
+      arc_notifier.clear();
+      node_notifier.clear();
+    }
+  };
+
+  // \ingroup _graphbits
+  //
+  // \brief Extender for the Graphs
+  template <typename Base>
+  class GraphExtender : public Base {
+    typedef Base Parent;
+
+  public:
+
+    typedef GraphExtender Graph;
+
+    typedef True UndirectedTag;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    // Graph extension
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    int maxId(Edge) const {
+      return Parent::maxEdgeId();
+    }
+
+    static Node fromId(int id, Node) {
+      return Parent::nodeFromId(id);
+    }
+
+    static Arc fromId(int id, Arc) {
+      return Parent::arcFromId(id);
+    }
+
+    static Edge fromId(int id, Edge) {
+      return Parent::edgeFromId(id);
+    }
+
+    Node oppositeNode(const Node &n, const Edge &e) const {
+      if( n == Parent::u(e))
+        return Parent::v(e);
+      else if( n == Parent::v(e))
+        return Parent::u(e);
+      else
+        return INVALID;
+    }
+
+    Arc oppositeArc(const Arc &arc) const {
+      return Parent::direct(arc, !Parent::direction(arc));
+    }
+
+    using Parent::direct;
+    Arc direct(const Edge &edge, const Node &node) const {
+      return Parent::direct(edge, Parent::u(edge) == node);
+    }
+
+    // Alterable extension
+
+    typedef AlterationNotifier<GraphExtender, Node> NodeNotifier;
+    typedef AlterationNotifier<GraphExtender, Arc> ArcNotifier;
+    typedef AlterationNotifier<GraphExtender, Edge> EdgeNotifier;
+
+
+  protected:
+
+    mutable NodeNotifier node_notifier;
+    mutable ArcNotifier arc_notifier;
+    mutable EdgeNotifier edge_notifier;
+
+  public:
+
+    NodeNotifier& notifier(Node) const {
+      return node_notifier;
+    }
+
+    ArcNotifier& notifier(Arc) const {
+      return arc_notifier;
+    }
+
+    EdgeNotifier& notifier(Edge) const {
+      return edge_notifier;
+    }
+
+
+
+    class NodeIt : public Node {
+      const Graph* _graph;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const Graph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Graph& graph, const Node& node)
+        : Node(node), _graph(&graph) {}
+
+      NodeIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Graph* _graph;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const Graph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Graph& graph, const Arc& arc) :
+        Arc(arc), _graph(&graph) { }
+
+      ArcIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Graph* _graph;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const Graph& graph, const Node& node)
+        : _graph(&graph) {
+        _graph->firstOut(*this, node);
+      }
+
+      OutArcIt(const Graph& graph, const Arc& arc)
+        : Arc(arc), _graph(&graph) {}
+
+      OutArcIt& operator++() {
+        _graph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Graph* _graph;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const Graph& graph, const Node& node)
+        : _graph(&graph) {
+        _graph->firstIn(*this, node);
+      }
+
+      InArcIt(const Graph& graph, const Arc& arc) :
+        Arc(arc), _graph(&graph) {}
+
+      InArcIt& operator++() {
+        _graph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+
+    class EdgeIt : public Parent::Edge {
+      const Graph* _graph;
+    public:
+
+      EdgeIt() { }
+
+      EdgeIt(Invalid i) : Edge(i) { }
+
+      explicit EdgeIt(const Graph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const Graph& graph, const Edge& edge) :
+        Edge(edge), _graph(&graph) { }
+
+      EdgeIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+    class IncEdgeIt : public Parent::Edge {
+      friend class GraphExtender;
+      const Graph* _graph;
+      bool _direction;
+    public:
+
+      IncEdgeIt() { }
+
+      IncEdgeIt(Invalid i) : Edge(i), _direction(false) { }
+
+      IncEdgeIt(const Graph& graph, const Node &node) : _graph(&graph) {
+        _graph->firstInc(*this, _direction, node);
+      }
+
+      IncEdgeIt(const Graph& graph, const Edge &edge, const Node &node)
+        : _graph(&graph), Edge(edge) {
+        _direction = (_graph->source(edge) == node);
+      }
+
+      IncEdgeIt& operator++() {
+        _graph->nextInc(*this, _direction);
+        return *this;
+      }
+    };
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the source in this case) of the iterator
+    Node baseNode(const OutArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the target in this case) of the
+    // iterator
+    Node runningNode(const OutArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the target in this case) of the iterator
+    Node baseNode(const InArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the source in this case) of the
+    // iterator
+    Node runningNode(const InArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+    // Base node of the iterator
+    //
+    // Returns the base node of the iterator
+    Node baseNode(const IncEdgeIt &edge) const {
+      return edge._direction ? this->u(edge) : this->v(edge);
+    }
+    // Running node of the iterator
+    //
+    // Returns the running node of the iterator
+    Node runningNode(const IncEdgeIt &edge) const {
+      return edge._direction ? this->v(edge) : this->u(edge);
+    }
+
+    // Mappable extension
+
+    template <typename _Value>
+    class NodeMap
+      : public MapExtender<DefaultMap<Graph, Node, _Value> > {
+      typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
+
+    public:
+      explicit NodeMap(const Graph& graph)
+        : Parent(graph) {}
+      NodeMap(const Graph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap
+      : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
+      typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
+
+    public:
+      explicit ArcMap(const Graph& graph)
+        : Parent(graph) {}
+      ArcMap(const Graph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+
+    template <typename _Value>
+    class EdgeMap
+      : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
+      typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
+
+    public:
+      explicit EdgeMap(const Graph& graph)
+        : Parent(graph) {}
+
+      EdgeMap(const Graph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    // Alteration extension
+
+    Node addNode() {
+      Node node = Parent::addNode();
+      notifier(Node()).add(node);
+      return node;
+    }
+
+    Edge addEdge(const Node& from, const Node& to) {
+      Edge edge = Parent::addEdge(from, to);
+      notifier(Edge()).add(edge);
+      std::vector<Arc> ev;
+      ev.push_back(Parent::direct(edge, true));
+      ev.push_back(Parent::direct(edge, false));
+      notifier(Arc()).add(ev);
+      return edge;
+    }
+
+    void clear() {
+      notifier(Arc()).clear();
+      notifier(Edge()).clear();
+      notifier(Node()).clear();
+      Parent::clear();
+    }
+
+    template <typename Graph, typename NodeRefMap, typename EdgeRefMap>
+    void build(const Graph& graph, NodeRefMap& nodeRef,
+               EdgeRefMap& edgeRef) {
+      Parent::build(graph, nodeRef, edgeRef);
+      notifier(Node()).build();
+      notifier(Edge()).build();
+      notifier(Arc()).build();
+    }
+
+    void erase(const Node& node) {
+      Arc arc;
+      Parent::firstOut(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstOut(arc, node);
+      }
+
+      Parent::firstIn(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstIn(arc, node);
+      }
+
+      notifier(Node()).erase(node);
+      Parent::erase(node);
+    }
+
+    void erase(const Edge& edge) {
+      std::vector<Arc> av;
+      av.push_back(Parent::direct(edge, true));
+      av.push_back(Parent::direct(edge, false));
+      notifier(Arc()).erase(av);
+      notifier(Edge()).erase(edge);
+      Parent::erase(edge);
+    }
+
+    GraphExtender() {
+      node_notifier.setContainer(*this);
+      arc_notifier.setContainer(*this);
+      edge_notifier.setContainer(*this);
+    }
+
+    ~GraphExtender() {
+      edge_notifier.clear();
+      arc_notifier.clear();
+      node_notifier.clear();
+    }
+
+  };
+
+  // \ingroup _graphbits
+  //
+  // \brief Extender for the BpGraphs
+  template <typename Base>
+  class BpGraphExtender : public Base {
+    typedef Base Parent;
+
+  public:
+
+    typedef BpGraphExtender BpGraph;
+
+    typedef True UndirectedTag;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::RedNode RedNode;
+    typedef typename Parent::BlueNode BlueNode;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    // BpGraph extension
+
+    using Parent::first;
+    using Parent::next;
+    using Parent::id;
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(RedNode) const {
+      return Parent::maxRedId();
+    }
+
+    int maxId(BlueNode) const {
+      return Parent::maxBlueId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    int maxId(Edge) const {
+      return Parent::maxEdgeId();
+    }
+
+    static Node fromId(int id, Node) {
+      return Parent::nodeFromId(id);
+    }
+
+    static Arc fromId(int id, Arc) {
+      return Parent::arcFromId(id);
+    }
+
+    static Edge fromId(int id, Edge) {
+      return Parent::edgeFromId(id);
+    }
+
+    Node u(Edge e) const { return this->redNode(e); }
+    Node v(Edge e) const { return this->blueNode(e); }
+
+    Node oppositeNode(const Node &n, const Edge &e) const {
+      if( n == u(e))
+        return v(e);
+      else if( n == v(e))
+        return u(e);
+      else
+        return INVALID;
+    }
+
+    Arc oppositeArc(const Arc &arc) const {
+      return Parent::direct(arc, !Parent::direction(arc));
+    }
+
+    using Parent::direct;
+    Arc direct(const Edge &edge, const Node &node) const {
+      return Parent::direct(edge, Parent::redNode(edge) == node);
+    }
+
+    RedNode asRedNode(const Node& node) const {
+      if (node == INVALID || Parent::blue(node)) {
+        return INVALID;
+      } else {
+        return Parent::asRedNodeUnsafe(node);
+      }
+    }
+
+    BlueNode asBlueNode(const Node& node) const {
+      if (node == INVALID || Parent::red(node)) {
+        return INVALID;
+      } else {
+        return Parent::asBlueNodeUnsafe(node);
+      }
+    }
+
+    // Alterable extension
+
+    typedef AlterationNotifier<BpGraphExtender, Node> NodeNotifier;
+    typedef AlterationNotifier<BpGraphExtender, RedNode> RedNodeNotifier;
+    typedef AlterationNotifier<BpGraphExtender, BlueNode> BlueNodeNotifier;
+    typedef AlterationNotifier<BpGraphExtender, Arc> ArcNotifier;
+    typedef AlterationNotifier<BpGraphExtender, Edge> EdgeNotifier;
+
+
+  protected:
+
+    mutable NodeNotifier node_notifier;
+    mutable RedNodeNotifier red_node_notifier;
+    mutable BlueNodeNotifier blue_node_notifier;
+    mutable ArcNotifier arc_notifier;
+    mutable EdgeNotifier edge_notifier;
+
+  public:
+
+    NodeNotifier& notifier(Node) const {
+      return node_notifier;
+    }
+
+    RedNodeNotifier& notifier(RedNode) const {
+      return red_node_notifier;
+    }
+
+    BlueNodeNotifier& notifier(BlueNode) const {
+      return blue_node_notifier;
+    }
+
+    ArcNotifier& notifier(Arc) const {
+      return arc_notifier;
+    }
+
+    EdgeNotifier& notifier(Edge) const {
+      return edge_notifier;
+    }
+
+
+
+    class NodeIt : public Node {
+      const BpGraph* _graph;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const BpGraph& graph, const Node& node)
+        : Node(node), _graph(&graph) {}
+
+      NodeIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+    class RedNodeIt : public RedNode {
+      const BpGraph* _graph;
+    public:
+
+      RedNodeIt() {}
+
+      RedNodeIt(Invalid i) : RedNode(i) { }
+
+      explicit RedNodeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<RedNode&>(*this));
+      }
+
+      RedNodeIt(const BpGraph& graph, const RedNode& node)
+        : RedNode(node), _graph(&graph) {}
+
+      RedNodeIt& operator++() {
+        _graph->next(static_cast<RedNode&>(*this));
+        return *this;
+      }
+
+    };
+
+    class BlueNodeIt : public BlueNode {
+      const BpGraph* _graph;
+    public:
+
+      BlueNodeIt() {}
+
+      BlueNodeIt(Invalid i) : BlueNode(i) { }
+
+      explicit BlueNodeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<BlueNode&>(*this));
+      }
+
+      BlueNodeIt(const BpGraph& graph, const BlueNode& node)
+        : BlueNode(node), _graph(&graph) {}
+
+      BlueNodeIt& operator++() {
+        _graph->next(static_cast<BlueNode&>(*this));
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const BpGraph& graph, const Arc& arc) :
+        Arc(arc), _graph(&graph) { }
+
+      ArcIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const BpGraph& graph, const Node& node)
+        : _graph(&graph) {
+        _graph->firstOut(*this, node);
+      }
+
+      OutArcIt(const BpGraph& graph, const Arc& arc)
+        : Arc(arc), _graph(&graph) {}
+
+      OutArcIt& operator++() {
+        _graph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const BpGraph& graph, const Node& node)
+        : _graph(&graph) {
+        _graph->firstIn(*this, node);
+      }
+
+      InArcIt(const BpGraph& graph, const Arc& arc) :
+        Arc(arc), _graph(&graph) {}
+
+      InArcIt& operator++() {
+        _graph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+
+    class EdgeIt : public Parent::Edge {
+      const BpGraph* _graph;
+    public:
+
+      EdgeIt() { }
+
+      EdgeIt(Invalid i) : Edge(i) { }
+
+      explicit EdgeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const BpGraph& graph, const Edge& edge) :
+        Edge(edge), _graph(&graph) { }
+
+      EdgeIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+    class IncEdgeIt : public Parent::Edge {
+      friend class BpGraphExtender;
+      const BpGraph* _graph;
+      bool _direction;
+    public:
+
+      IncEdgeIt() { }
+
+      IncEdgeIt(Invalid i) : Edge(i), _direction(false) { }
+
+      IncEdgeIt(const BpGraph& graph, const Node &node) : _graph(&graph) {
+        _graph->firstInc(*this, _direction, node);
+      }
+
+      IncEdgeIt(const BpGraph& graph, const Edge &edge, const Node &node)
+        : _graph(&graph), Edge(edge) {
+        _direction = (_graph->source(edge) == node);
+      }
+
+      IncEdgeIt& operator++() {
+        _graph->nextInc(*this, _direction);
+        return *this;
+      }
+    };
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the source in this case) of the iterator
+    Node baseNode(const OutArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the target in this case) of the
+    // iterator
+    Node runningNode(const OutArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the target in this case) of the iterator
+    Node baseNode(const InArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the source in this case) of the
+    // iterator
+    Node runningNode(const InArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+    // Base node of the iterator
+    //
+    // Returns the base node of the iterator
+    Node baseNode(const IncEdgeIt &edge) const {
+      return edge._direction ? this->u(edge) : this->v(edge);
+    }
+    // Running node of the iterator
+    //
+    // Returns the running node of the iterator
+    Node runningNode(const IncEdgeIt &edge) const {
+      return edge._direction ? this->v(edge) : this->u(edge);
+    }
+
+    // Mappable extension
+
+    template <typename _Value>
+    class NodeMap
+      : public MapExtender<DefaultMap<BpGraph, Node, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Node, _Value> > Parent;
+
+    public:
+      explicit NodeMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      NodeMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class RedNodeMap
+      : public MapExtender<DefaultMap<BpGraph, RedNode, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, RedNode, _Value> > Parent;
+
+    public:
+      explicit RedNodeMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      RedNodeMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      RedNodeMap& operator=(const RedNodeMap& cmap) {
+        return operator=<RedNodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      RedNodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class BlueNodeMap
+      : public MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > Parent;
+
+    public:
+      explicit BlueNodeMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      BlueNodeMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      BlueNodeMap& operator=(const BlueNodeMap& cmap) {
+        return operator=<BlueNodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      BlueNodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap
+      : public MapExtender<DefaultMap<BpGraph, Arc, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Arc, _Value> > Parent;
+
+    public:
+      explicit ArcMap(const BpGraph& graph)
+        : Parent(graph) {}
+      ArcMap(const BpGraph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+
+    template <typename _Value>
+    class EdgeMap
+      : public MapExtender<DefaultMap<BpGraph, Edge, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Edge, _Value> > Parent;
+
+    public:
+      explicit EdgeMap(const BpGraph& graph)
+        : Parent(graph) {}
+
+      EdgeMap(const BpGraph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    // Alteration extension
+
+    RedNode addRedNode() {
+      RedNode node = Parent::addRedNode();
+      notifier(RedNode()).add(node);
+      notifier(Node()).add(node);
+      return node;
+    }
+
+    BlueNode addBlueNode() {
+      BlueNode node = Parent::addBlueNode();
+      notifier(BlueNode()).add(node);
+      notifier(Node()).add(node);
+      return node;
+    }
+
+    Edge addEdge(const RedNode& from, const BlueNode& to) {
+      Edge edge = Parent::addEdge(from, to);
+      notifier(Edge()).add(edge);
+      std::vector<Arc> av;
+      av.push_back(Parent::direct(edge, true));
+      av.push_back(Parent::direct(edge, false));
+      notifier(Arc()).add(av);
+      return edge;
+    }
+
+    void clear() {
+      notifier(Arc()).clear();
+      notifier(Edge()).clear();
+      notifier(Node()).clear();
+      notifier(BlueNode()).clear();
+      notifier(RedNode()).clear();
+      Parent::clear();
+    }
+
+    template <typename BpGraph, typename NodeRefMap, typename EdgeRefMap>
+    void build(const BpGraph& graph, NodeRefMap& nodeRef,
+               EdgeRefMap& edgeRef) {
+      Parent::build(graph, nodeRef, edgeRef);
+      notifier(RedNode()).build();
+      notifier(BlueNode()).build();
+      notifier(Node()).build();
+      notifier(Edge()).build();
+      notifier(Arc()).build();
+    }
+
+    void erase(const Node& node) {
+      Arc arc;
+      Parent::firstOut(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstOut(arc, node);
+      }
+
+      Parent::firstIn(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstIn(arc, node);
+      }
+
+      if (Parent::red(node)) {
+        notifier(RedNode()).erase(this->asRedNodeUnsafe(node));
+      } else {
+        notifier(BlueNode()).erase(this->asBlueNodeUnsafe(node));
+      }
+
+      notifier(Node()).erase(node);
+      Parent::erase(node);
+    }
+
+    void erase(const Edge& edge) {
+      std::vector<Arc> av;
+      av.push_back(Parent::direct(edge, true));
+      av.push_back(Parent::direct(edge, false));
+      notifier(Arc()).erase(av);
+      notifier(Edge()).erase(edge);
+      Parent::erase(edge);
+    }
+
+    BpGraphExtender() {
+      red_node_notifier.setContainer(*this);
+      blue_node_notifier.setContainer(*this);
+      node_notifier.setContainer(*this);
+      arc_notifier.setContainer(*this);
+      edge_notifier.setContainer(*this);
+    }
+
+    ~BpGraphExtender() {
+      edge_notifier.clear();
+      arc_notifier.clear();
+      node_notifier.clear();
+      blue_node_notifier.clear();
+      red_node_notifier.clear();
+    }
+
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/lock.h b/lemon/bits/lock.h
new file mode 100644
index 0000000..0906999
--- /dev/null
+++ b/lemon/bits/lock.h
@@ -0,0 +1,65 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_LOCK_H
+#define LEMON_BITS_LOCK_H
+
+#include <lemon/config.h>
+#if defined(LEMON_USE_PTHREAD)
+#include <pthread.h>
+#elif defined(LEMON_USE_WIN32_THREADS)
+#include <lemon/bits/windows.h>
+#endif
+
+namespace lemon {
+  namespace bits {
+
+#if defined(LEMON_USE_PTHREAD)
+    class Lock {
+    public:
+      Lock() {
+        pthread_mutex_init(&_lock, 0);
+      }
+      ~Lock() {
+        pthread_mutex_destroy(&_lock);
+      }
+      void lock() {
+        pthread_mutex_lock(&_lock);
+      }
+      void unlock() {
+        pthread_mutex_unlock(&_lock);
+      }
+
+    private:
+      pthread_mutex_t _lock;
+    };
+#elif defined(LEMON_USE_WIN32_THREADS)
+    class Lock : public WinLock {};
+#else
+    class Lock {
+    public:
+      Lock() {}
+      ~Lock() {}
+      void lock() {}
+      void unlock() {}
+    };
+#endif
+  }
+}
+
+#endif
diff --git a/lemon/bits/map_extender.h b/lemon/bits/map_extender.h
new file mode 100644
index 0000000..f32403e
--- /dev/null
+++ b/lemon/bits/map_extender.h
@@ -0,0 +1,332 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_MAP_EXTENDER_H
+#define LEMON_BITS_MAP_EXTENDER_H
+
+#include <iterator>
+
+#include <lemon/bits/traits.h>
+
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
+
+//\file
+//\brief Extenders for iterable maps.
+
+namespace lemon {
+
+  // \ingroup graphbits
+  //
+  // \brief Extender for maps
+  template <typename _Map>
+  class MapExtender : public _Map {
+    typedef _Map Parent;
+    typedef typename Parent::GraphType GraphType;
+
+  public:
+
+    typedef MapExtender Map;
+    typedef typename Parent::Key Item;
+
+    typedef typename Parent::Key Key;
+    typedef typename Parent::Value Value;
+    typedef typename Parent::Reference Reference;
+    typedef typename Parent::ConstReference ConstReference;
+
+    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
+
+    class MapIt;
+    class ConstMapIt;
+
+    friend class MapIt;
+    friend class ConstMapIt;
+
+  public:
+
+    MapExtender(const GraphType& graph)
+      : Parent(graph) {}
+
+    MapExtender(const GraphType& graph, const Value& value)
+      : Parent(graph, value) {}
+
+  private:
+    MapExtender& operator=(const MapExtender& cmap) {
+      return operator=<MapExtender>(cmap);
+    }
+
+    template <typename CMap>
+    MapExtender& operator=(const CMap& cmap) {
+      Parent::operator=(cmap);
+      return *this;
+    }
+
+  public:
+    class MapIt : public Item {
+      typedef Item Parent;
+
+    public:
+
+      typedef typename Map::Value Value;
+
+      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) {}
+
+      ConstMapIt& operator++() {
+        map->notifier()->next(*this);
+        return *this;
+      }
+
+      typename MapTraits<Map>::ConstReturnValue operator*() const {
+        return map[*this];
+      }
+
+    protected:
+      const Map* map;
+    };
+
+    class ItemIt : public Item {
+      typedef Item Parent;
+
+    public:
+      ItemIt() : map(NULL) {}
+
+
+      ItemIt(Invalid i) : Parent(i), map(NULL) {}
+
+      explicit ItemIt(Map& _map) : map(&_map) {
+        map->notifier()->first(*this);
+      }
+
+      ItemIt(const Map& _map, const Item& item)
+        : Parent(item), map(&_map) {}
+
+      ItemIt& operator++() {
+        map->notifier()->next(*this);
+        return *this;
+      }
+
+    protected:
+      const Map* map;
+
+    };
+  };
+
+  // \ingroup graphbits
+  //
+  // \brief Extender for maps which use a subset of the items.
+  template <typename _Graph, typename _Map>
+  class SubMapExtender : public _Map {
+    typedef _Map Parent;
+    typedef _Graph GraphType;
+
+  public:
+
+    typedef SubMapExtender Map;
+    typedef typename Parent::Key Item;
+
+    typedef typename Parent::Key Key;
+    typedef typename Parent::Value Value;
+    typedef typename Parent::Reference Reference;
+    typedef typename Parent::ConstReference ConstReference;
+
+    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
+
+    class MapIt;
+    class ConstMapIt;
+
+    friend class MapIt;
+    friend class ConstMapIt;
+
+  public:
+
+    SubMapExtender(const GraphType& _graph)
+      : Parent(_graph), graph(_graph) {}
+
+    SubMapExtender(const GraphType& _graph, const Value& _value)
+      : Parent(_graph, _value), graph(_graph) {}
+
+  private:
+    SubMapExtender& operator=(const SubMapExtender& cmap) {
+      return operator=<MapExtender>(cmap);
+    }
+
+    template <typename CMap>
+    SubMapExtender& operator=(const CMap& cmap) {
+      checkConcept<concepts::ReadMap<Key, Value>, CMap>();
+      Item it;
+      for (graph.first(it); it != INVALID; graph.next(it)) {
+        Parent::set(it, cmap[it]);
+      }
+      return *this;
+    }
+
+  public:
+    class MapIt : public Item {
+      typedef Item Parent;
+
+    public:
+      typedef typename Map::Value Value;
+
+      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) {}
+
+      MapIt& operator++() {
+        map->graph.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->graph.first(*this);
+      }
+
+      ConstMapIt(const Map& _map, const Item& item)
+        : Parent(item), map(&_map) {}
+
+      ConstMapIt& operator++() {
+        map->graph.next(*this);
+        return *this;
+      }
+
+      typename MapTraits<Map>::ConstReturnValue operator*() const {
+        return (*map)[*this];
+      }
+
+    protected:
+      const Map* map;
+    };
+
+    class ItemIt : public Item {
+      typedef Item Parent;
+
+    public:
+      ItemIt() : map(NULL) {}
+
+
+      ItemIt(Invalid i) : Parent(i), map(NULL) { }
+
+      explicit ItemIt(Map& _map) : map(&_map) {
+        map->graph.first(*this);
+      }
+
+      ItemIt(const Map& _map, const Item& item)
+        : Parent(item), map(&_map) {}
+
+      ItemIt& operator++() {
+        map->graph.next(*this);
+        return *this;
+      }
+
+    protected:
+      const Map* map;
+
+    };
+
+  private:
+
+    const GraphType& graph;
+
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/path_dump.h b/lemon/bits/path_dump.h
new file mode 100644
index 0000000..3e8cb8d
--- /dev/null
+++ b/lemon/bits/path_dump.h
@@ -0,0 +1,177 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_PATH_DUMP_H
+#define LEMON_BITS_PATH_DUMP_H
+
+#include <lemon/core.h>
+#include <lemon/concept_check.h>
+
+namespace lemon {
+
+  template <typename _Digraph, typename _PredMap>
+  class PredMapPath {
+  public:
+    typedef True RevPathTag;
+
+    typedef _Digraph Digraph;
+    typedef typename Digraph::Arc Arc;
+    typedef _PredMap PredMap;
+
+    PredMapPath(const Digraph& _digraph, const PredMap& _predMap,
+                typename Digraph::Node _target)
+      : digraph(_digraph), predMap(_predMap), target(_target) {}
+
+    int length() const {
+      int len = 0;
+      typename Digraph::Node node = target;
+      typename Digraph::Arc arc;
+      while ((arc = predMap[node]) != INVALID) {
+        node = digraph.source(arc);
+        ++len;
+      }
+      return len;
+    }
+
+    bool empty() const {
+      return predMap[target] == INVALID;
+    }
+
+    class RevArcIt {
+    public:
+      RevArcIt() {}
+      RevArcIt(Invalid) : path(0), current(INVALID) {}
+      RevArcIt(const PredMapPath& _path)
+        : path(&_path), current(_path.target) {
+        if (path->predMap[current] == INVALID) current = INVALID;
+      }
+
+      operator const typename Digraph::Arc() const {
+        return path->predMap[current];
+      }
+
+      RevArcIt& operator++() {
+        current = path->digraph.source(path->predMap[current]);
+        if (path->predMap[current] == INVALID) current = INVALID;
+        return *this;
+      }
+
+      bool operator==(const RevArcIt& e) const {
+        return current == e.current;
+      }
+
+      bool operator!=(const RevArcIt& e) const {
+        return current != e.current;
+      }
+
+      bool operator<(const RevArcIt& e) const {
+        return current < e.current;
+      }
+
+    private:
+      const PredMapPath* path;
+      typename Digraph::Node current;
+    };
+
+  private:
+    const Digraph& digraph;
+    const PredMap& predMap;
+    typename Digraph::Node target;
+  };
+
+
+  template <typename _Digraph, typename _PredMatrixMap>
+  class PredMatrixMapPath {
+  public:
+    typedef True RevPathTag;
+
+    typedef _Digraph Digraph;
+    typedef typename Digraph::Arc Arc;
+    typedef _PredMatrixMap PredMatrixMap;
+
+    PredMatrixMapPath(const Digraph& _digraph,
+                      const PredMatrixMap& _predMatrixMap,
+                      typename Digraph::Node _source,
+                      typename Digraph::Node _target)
+      : digraph(_digraph), predMatrixMap(_predMatrixMap),
+        source(_source), target(_target) {}
+
+    int length() const {
+      int len = 0;
+      typename Digraph::Node node = target;
+      typename Digraph::Arc arc;
+      while ((arc = predMatrixMap(source, node)) != INVALID) {
+        node = digraph.source(arc);
+        ++len;
+      }
+      return len;
+    }
+
+    bool empty() const {
+      return predMatrixMap(source, target) == INVALID;
+    }
+
+    class RevArcIt {
+    public:
+      RevArcIt() {}
+      RevArcIt(Invalid) : path(0), current(INVALID) {}
+      RevArcIt(const PredMatrixMapPath& _path)
+        : path(&_path), current(_path.target) {
+        if (path->predMatrixMap(path->source, current) == INVALID)
+          current = INVALID;
+      }
+
+      operator const typename Digraph::Arc() const {
+        return path->predMatrixMap(path->source, current);
+      }
+
+      RevArcIt& operator++() {
+        current =
+          path->digraph.source(path->predMatrixMap(path->source, current));
+        if (path->predMatrixMap(path->source, current) == INVALID)
+          current = INVALID;
+        return *this;
+      }
+
+      bool operator==(const RevArcIt& e) const {
+        return current == e.current;
+      }
+
+      bool operator!=(const RevArcIt& e) const {
+        return current != e.current;
+      }
+
+      bool operator<(const RevArcIt& e) const {
+        return current < e.current;
+      }
+
+    private:
+      const PredMatrixMapPath* path;
+      typename Digraph::Node current;
+    };
+
+  private:
+    const Digraph& digraph;
+    const PredMatrixMap& predMatrixMap;
+    typename Digraph::Node source;
+    typename Digraph::Node target;
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/solver_bits.h b/lemon/bits/solver_bits.h
new file mode 100644
index 0000000..c34212b
--- /dev/null
+++ b/lemon/bits/solver_bits.h
@@ -0,0 +1,194 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_SOLVER_BITS_H
+#define LEMON_BITS_SOLVER_BITS_H
+
+#include <vector>
+
+namespace lemon {
+
+  namespace _solver_bits {
+
+    class VarIndex {
+    private:
+      struct ItemT {
+        int prev, next;
+        int index;
+      };
+      std::vector<ItemT> items;
+      int first_item, last_item, first_free_item;
+
+      std::vector<int> cross;
+
+    public:
+
+      VarIndex()
+        : first_item(-1), last_item(-1), first_free_item(-1) {
+      }
+
+      void clear() {
+        first_item = -1;
+        last_item = -1;
+        first_free_item = -1;
+        items.clear();
+        cross.clear();
+      }
+
+      int addIndex(int idx) {
+        int n;
+        if (first_free_item == -1) {
+          n = items.size();
+          items.push_back(ItemT());
+        } else {
+          n = first_free_item;
+          first_free_item = items[n].next;
+          if (first_free_item != -1) {
+            items[first_free_item].prev = -1;
+          }
+        }
+        items[n].index = idx;
+        if (static_cast<int>(cross.size()) <= idx) {
+          cross.resize(idx + 1, -1);
+        }
+        cross[idx] = n;
+
+        items[n].prev = last_item;
+        items[n].next = -1;
+        if (last_item != -1) {
+          items[last_item].next = n;
+        } else {
+          first_item = n;
+        }
+        last_item = n;
+
+        return n;
+      }
+
+      int addIndex(int idx, int n) {
+        while (n >= static_cast<int>(items.size())) {
+          items.push_back(ItemT());
+          items.back().prev = -1;
+          items.back().next = first_free_item;
+          if (first_free_item != -1) {
+            items[first_free_item].prev = items.size() - 1;
+          }
+          first_free_item = items.size() - 1;
+        }
+        if (items[n].next != -1) {
+          items[items[n].next].prev = items[n].prev;
+        }
+        if (items[n].prev != -1) {
+          items[items[n].prev].next = items[n].next;
+        } else {
+          first_free_item = items[n].next;
+        }
+
+        items[n].index = idx;
+        if (static_cast<int>(cross.size()) <= idx) {
+          cross.resize(idx + 1, -1);
+        }
+        cross[idx] = n;
+
+        items[n].prev = last_item;
+        items[n].next = -1;
+        if (last_item != -1) {
+          items[last_item].next = n;
+        } else {
+          first_item = n;
+        }
+        last_item = n;
+
+        return n;
+      }
+
+      void eraseIndex(int idx) {
+        int n = cross[idx];
+
+        if (items[n].prev != -1) {
+          items[items[n].prev].next = items[n].next;
+        } else {
+          first_item = items[n].next;
+        }
+        if (items[n].next != -1) {
+          items[items[n].next].prev = items[n].prev;
+        } else {
+          last_item = items[n].prev;
+        }
+
+        if (first_free_item != -1) {
+          items[first_free_item].prev = n;
+        }
+        items[n].next = first_free_item;
+        items[n].prev = -1;
+        first_free_item = n;
+
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      int maxIndex() const {
+        return cross.size() - 1;
+      }
+
+      void shiftIndices(int idx) {
+        for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
+          cross[i - 1] = cross[i];
+          if (cross[i] != -1) {
+            --items[cross[i]].index;
+          }
+        }
+        cross.back() = -1;
+        cross.pop_back();
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      void relocateIndex(int idx, int jdx) {
+        cross[idx] = cross[jdx];
+        items[cross[jdx]].index = idx;
+        cross[jdx] = -1;
+
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      int operator[](int idx) const {
+        return cross[idx];
+      }
+
+      int operator()(int fdx) const {
+        return items[fdx].index;
+      }
+
+      void firstItem(int& fdx) const {
+        fdx = first_item;
+      }
+
+      void nextItem(int& fdx) const {
+        fdx = items[fdx].next;
+      }
+
+    };
+  }
+}
+
+#endif
diff --git a/lemon/bits/traits.h b/lemon/bits/traits.h
new file mode 100644
index 0000000..53fbd45
--- /dev/null
+++ b/lemon/bits/traits.h
@@ -0,0 +1,388 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_TRAITS_H
+#define LEMON_BITS_TRAITS_H
+
+//\file
+//\brief Traits for graphs and maps
+//
+
+#include <lemon/bits/enable_if.h>
+
+namespace lemon {
+
+  struct InvalidType {};
+
+  template <typename GR, typename _Item>
+  class ItemSetTraits {};
+
+
+  template <typename GR, typename Enable = void>
+  struct NodeNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct NodeNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::NodeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::NodeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::Node> {
+  public:
+
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::Node Item;
+    typedef typename GR::NodeIt ItemIt;
+
+    typedef typename NodeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
+    public:
+      typedef typename GR::template NodeMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _digraph) : Parent(_digraph) {}
+      Map(const GR& _digraph, const Value& _value)
+        : Parent(_digraph, _value) {}
+
+     };
+
+  };
+
+  template <typename GR, typename Enable = void>
+  struct ArcNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct ArcNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::ArcNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::ArcNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::Arc> {
+  public:
+
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::Arc Item;
+    typedef typename GR::ArcIt ItemIt;
+
+    typedef typename ArcNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template ArcMap<V> {
+      typedef typename GR::template ArcMap<V> Parent;
+
+    public:
+      typedef typename GR::template ArcMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _digraph) : Parent(_digraph) {}
+      Map(const GR& _digraph, const Value& _value)
+        : Parent(_digraph, _value) {}
+    };
+
+  };
+
+  template <typename GR, typename Enable = void>
+  struct EdgeNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct EdgeNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::EdgeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::EdgeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::Edge> {
+  public:
+
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::Edge Item;
+    typedef typename GR::EdgeIt ItemIt;
+
+    typedef typename EdgeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template EdgeMap<V> {
+      typedef typename GR::template EdgeMap<V> Parent;
+
+    public:
+      typedef typename GR::template EdgeMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _digraph) : Parent(_digraph) {}
+      Map(const GR& _digraph, const Value& _value)
+        : Parent(_digraph, _value) {}
+    };
+
+  };
+
+  template <typename GR, typename Enable = void>
+  struct RedNodeNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct RedNodeNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::RedNodeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::RedNodeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::RedNode> {
+  public:
+
+    typedef GR BpGraph;
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::RedNode Item;
+    typedef typename GR::RedNodeIt ItemIt;
+
+    typedef typename RedNodeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template RedNodeMap<V> {
+      typedef typename GR::template RedNodeMap<V> Parent;
+
+    public:
+      typedef typename GR::template RedNodeMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _bpgraph) : Parent(_bpgraph) {}
+      Map(const GR& _bpgraph, const Value& _value)
+        : Parent(_bpgraph, _value) {}
+
+     };
+
+  };
+
+  template <typename GR, typename Enable = void>
+  struct BlueNodeNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct BlueNodeNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::BlueNodeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::BlueNodeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::BlueNode> {
+  public:
+
+    typedef GR BpGraph;
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::BlueNode Item;
+    typedef typename GR::BlueNodeIt ItemIt;
+
+    typedef typename BlueNodeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template BlueNodeMap<V> {
+      typedef typename GR::template BlueNodeMap<V> Parent;
+
+    public:
+      typedef typename GR::template BlueNodeMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _bpgraph) : Parent(_bpgraph) {}
+      Map(const GR& _bpgraph, const Value& _value)
+        : Parent(_bpgraph, _value) {}
+
+     };
+
+  };
+
+  template <typename Map, typename Enable = void>
+  struct MapTraits {
+    typedef False ReferenceMapTag;
+
+    typedef typename Map::Key Key;
+    typedef typename Map::Value Value;
+
+    typedef Value ConstReturnValue;
+    typedef Value ReturnValue;
+  };
+
+  template <typename Map>
+  struct MapTraits<
+    Map, typename enable_if<typename Map::ReferenceMapTag, void>::type >
+  {
+    typedef True ReferenceMapTag;
+
+    typedef typename Map::Key Key;
+    typedef typename Map::Value Value;
+
+    typedef typename Map::ConstReference ConstReturnValue;
+    typedef typename Map::Reference ReturnValue;
+
+    typedef typename Map::ConstReference ConstReference;
+    typedef typename Map::Reference Reference;
+ };
+
+  template <typename MatrixMap, typename Enable = void>
+  struct MatrixMapTraits {
+    typedef False ReferenceMapTag;
+
+    typedef typename MatrixMap::FirstKey FirstKey;
+    typedef typename MatrixMap::SecondKey SecondKey;
+    typedef typename MatrixMap::Value Value;
+
+    typedef Value ConstReturnValue;
+    typedef Value ReturnValue;
+  };
+
+  template <typename MatrixMap>
+  struct MatrixMapTraits<
+    MatrixMap, typename enable_if<typename MatrixMap::ReferenceMapTag,
+                                  void>::type >
+  {
+    typedef True ReferenceMapTag;
+
+    typedef typename MatrixMap::FirstKey FirstKey;
+    typedef typename MatrixMap::SecondKey SecondKey;
+    typedef typename MatrixMap::Value Value;
+
+    typedef typename MatrixMap::ConstReference ConstReturnValue;
+    typedef typename MatrixMap::Reference ReturnValue;
+
+    typedef typename MatrixMap::ConstReference ConstReference;
+    typedef typename MatrixMap::Reference Reference;
+ };
+
+  // Indicators for the tags
+
+  template <typename GR, typename Enable = void>
+  struct NodeNumTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename GR>
+  struct NodeNumTagIndicator<
+    GR,
+    typename enable_if<typename GR::NodeNumTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
+  struct ArcNumTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename GR>
+  struct ArcNumTagIndicator<
+    GR,
+    typename enable_if<typename GR::ArcNumTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
+  struct EdgeNumTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename GR>
+  struct EdgeNumTagIndicator<
+    GR,
+    typename enable_if<typename GR::EdgeNumTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
+  struct FindArcTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename GR>
+  struct FindArcTagIndicator<
+    GR,
+    typename enable_if<typename GR::FindArcTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
+  struct FindEdgeTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename GR>
+  struct FindEdgeTagIndicator<
+    GR,
+    typename enable_if<typename GR::FindEdgeTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
+  struct UndirectedTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename GR>
+  struct UndirectedTagIndicator<
+    GR,
+    typename enable_if<typename GR::UndirectedTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
+  struct BuildTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename GR>
+  struct BuildTagIndicator<
+    GR,
+    typename enable_if<typename GR::BuildTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/variant.h b/lemon/bits/variant.h
new file mode 100644
index 0000000..b830189
--- /dev/null
+++ b/lemon/bits/variant.h
@@ -0,0 +1,494 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_VARIANT_H
+#define LEMON_BITS_VARIANT_H
+
+#include <lemon/assert.h>
+
+// \file
+// \brief Variant types
+
+namespace lemon {
+
+  namespace _variant_bits {
+
+    template <int left, int right>
+    struct CTMax {
+      static const int value = left < right ? right : left;
+    };
+
+  }
+
+
+  // \brief Simple Variant type for two types
+  //
+  // Simple Variant type for two types. The Variant type is a type-safe
+  // union. C++ has strong limitations for using unions, for
+  // example you cannot store a type with non-default constructor or
+  // destructor in a union. This class always knowns the current
+  // state of the variant and it cares for the proper construction
+  // and destruction.
+  template <typename _First, typename _Second>
+  class BiVariant {
+  public:
+
+    // \brief The \c First type.
+    typedef _First First;
+    // \brief The \c Second type.
+    typedef _Second Second;
+
+    // \brief Constructor
+    //
+    // This constructor initalizes to the default value of the \c First
+    // type.
+    BiVariant() {
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First();
+    }
+
+    // \brief Constructor
+    //
+    // This constructor initalizes to the given value of the \c First
+    // type.
+    BiVariant(const First& f) {
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First(f);
+    }
+
+    // \brief Constructor
+    //
+    // This constructor initalizes to the given value of the \c
+    // Second type.
+    BiVariant(const Second& s) {
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second(s);
+    }
+
+    // \brief Copy constructor
+    //
+    // Copy constructor
+    BiVariant(const BiVariant& bivariant) {
+      flag = bivariant.flag;
+      if (flag) {
+        new(reinterpret_cast<First*>(data)) First(bivariant.first());
+      } else {
+        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
+      }
+    }
+
+    // \brief Destrcutor
+    //
+    // Destructor
+    ~BiVariant() {
+      destroy();
+    }
+
+    // \brief Set to the default value of the \c First type.
+    //
+    // This function sets the variant to the default value of the \c
+    // First type.
+    BiVariant& setFirst() {
+      destroy();
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First();
+      return *this;
+    }
+
+    // \brief Set to the given value of the \c First type.
+    //
+    // This function sets the variant to the given value of the \c
+    // First type.
+    BiVariant& setFirst(const First& f) {
+      destroy();
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First(f);
+      return *this;
+    }
+
+    // \brief Set to the default value of the \c Second type.
+    //
+    // This function sets the variant to the default value of the \c
+    // Second type.
+    BiVariant& setSecond() {
+      destroy();
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second();
+      return *this;
+    }
+
+    // \brief Set to the given value of the \c Second type.
+    //
+    // This function sets the variant to the given value of the \c
+    // Second type.
+    BiVariant& setSecond(const Second& s) {
+      destroy();
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second(s);
+      return *this;
+    }
+
+    // \brief Operator form of the \c setFirst()
+    BiVariant& operator=(const First& f) {
+      return setFirst(f);
+    }
+
+    // \brief Operator form of the \c setSecond()
+    BiVariant& operator=(const Second& s) {
+      return setSecond(s);
+    }
+
+    // \brief Assign operator
+    BiVariant& operator=(const BiVariant& bivariant) {
+      if (this == &bivariant) return *this;
+      destroy();
+      flag = bivariant.flag;
+      if (flag) {
+        new(reinterpret_cast<First*>(data)) First(bivariant.first());
+      } else {
+        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
+      }
+      return *this;
+    }
+
+    // \brief Reference to the value
+    //
+    // Reference to the value of the \c First type.
+    // \pre The BiVariant should store value of \c First type.
+    First& first() {
+      LEMON_DEBUG(flag, "Variant wrong state");
+      return *reinterpret_cast<First*>(data);
+    }
+
+    // \brief Const reference to the value
+    //
+    // Const reference to the value of the \c First type.
+    // \pre The BiVariant should store value of \c First type.
+    const First& first() const {
+      LEMON_DEBUG(flag, "Variant wrong state");
+      return *reinterpret_cast<const First*>(data);
+    }
+
+    // \brief Operator form of the \c first()
+    operator First&() { return first(); }
+    // \brief Operator form of the const \c first()
+    operator const First&() const { return first(); }
+
+    // \brief Reference to the value
+    //
+    // Reference to the value of the \c Second type.
+    // \pre The BiVariant should store value of \c Second type.
+    Second& second() {
+      LEMON_DEBUG(!flag, "Variant wrong state");
+      return *reinterpret_cast<Second*>(data);
+    }
+
+    // \brief Const reference to the value
+    //
+    // Const reference to the value of the \c Second type.
+    // \pre The BiVariant should store value of \c Second type.
+    const Second& second() const {
+      LEMON_DEBUG(!flag, "Variant wrong state");
+      return *reinterpret_cast<const Second*>(data);
+    }
+
+    // \brief Operator form of the \c second()
+    operator Second&() { return second(); }
+    // \brief Operator form of the const \c second()
+    operator const Second&() const { return second(); }
+
+    // \brief %True when the variant is in the first state
+    //
+    // %True when the variant stores value of the \c First type.
+    bool firstState() const { return flag; }
+
+    // \brief %True when the variant is in the second state
+    //
+    // %True when the variant stores value of the \c Second type.
+    bool secondState() const { return !flag; }
+
+  private:
+
+    void destroy() {
+      if (flag) {
+        reinterpret_cast<First*>(data)->~First();
+      } else {
+        reinterpret_cast<Second*>(data)->~Second();
+      }
+    }
+
+    char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value];
+    bool flag;
+  };
+
+  namespace _variant_bits {
+
+    template <int _idx, typename _TypeMap>
+    struct Memory {
+
+      typedef typename _TypeMap::template Map<_idx>::Type Current;
+
+      static void destroy(int index, char* place) {
+        if (index == _idx) {
+          reinterpret_cast<Current*>(place)->~Current();
+        } else {
+          Memory<_idx - 1, _TypeMap>::destroy(index, place);
+        }
+      }
+
+      static void copy(int index, char* to, const char* from) {
+        if (index == _idx) {
+          new (reinterpret_cast<Current*>(to))
+            Current(reinterpret_cast<const Current*>(from));
+        } else {
+          Memory<_idx - 1, _TypeMap>::copy(index, to, from);
+        }
+      }
+
+    };
+
+    template <typename _TypeMap>
+    struct Memory<-1, _TypeMap> {
+
+      static void destroy(int, char*) {
+        LEMON_DEBUG(false, "Variant wrong index.");
+      }
+
+      static void copy(int, char*, const char*) {
+        LEMON_DEBUG(false, "Variant wrong index.");
+      }
+    };
+
+    template <int _idx, typename _TypeMap>
+    struct Size {
+      static const int value =
+      CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type),
+            Size<_idx - 1, _TypeMap>::value>::value;
+    };
+
+    template <typename _TypeMap>
+    struct Size<0, _TypeMap> {
+      static const int value =
+      sizeof(typename _TypeMap::template Map<0>::Type);
+    };
+
+  }
+
+  // \brief Variant type
+  //
+  // Simple Variant type. The Variant type is a type-safe union.
+  // C++ has strong limitations for using unions, for example you
+  // cannot store type with non-default constructor or destructor in
+  // a union. This class always knowns the current state of the
+  // variant and it cares for the proper construction and
+  // destruction.
+  //
+  // \param _num The number of the types which can be stored in the
+  // variant type.
+  // \param _TypeMap This class describes the types of the Variant. The
+  // _TypeMap::Map<index>::Type should be a valid type for each index
+  // in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
+  // class to define such type mappings up to 10 types.
+  //
+  // And the usage of the class:
+  //\code
+  // typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
+  // MyVariant var;
+  // var.set<0>(12);
+  // std::cout << var.get<0>() << std::endl;
+  // var.set<1>("alpha");
+  // std::cout << var.get<1>() << std::endl;
+  // var.set<2>(0.75);
+  // std::cout << var.get<2>() << std::endl;
+  //\endcode
+  //
+  // The result of course:
+  //\code
+  // 12
+  // alpha
+  // 0.75
+  //\endcode
+  template <int _num, typename _TypeMap>
+  class Variant {
+  public:
+
+    static const int num = _num;
+
+    typedef _TypeMap TypeMap;
+
+    // \brief Constructor
+    //
+    // This constructor initalizes to the default value of the \c type
+    // with 0 index.
+    Variant() {
+      flag = 0;
+      new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data))
+        typename TypeMap::template Map<0>::Type();
+    }
+
+
+    // \brief Copy constructor
+    //
+    // Copy constructor
+    Variant(const Variant& variant) {
+      flag = variant.flag;
+      _variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data);
+    }
+
+    // \brief Assign operator
+    //
+    // Assign operator
+    Variant& operator=(const Variant& variant) {
+      if (this == &variant) return *this;
+      _variant_bits::Memory<num - 1, TypeMap>::
+        destroy(flag, data);
+      flag = variant.flag;
+      _variant_bits::Memory<num - 1, TypeMap>::
+        copy(flag, data, variant.data);
+      return *this;
+    }
+
+    // \brief Destrcutor
+    //
+    // Destructor
+    ~Variant() {
+      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
+    }
+
+    // \brief Set to the default value of the type with \c _idx index.
+    //
+    // This function sets the variant to the default value of the
+    // type with \c _idx index.
+    template <int _idx>
+    Variant& set() {
+      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
+      flag = _idx;
+      new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
+        typename TypeMap::template Map<_idx>::Type();
+      return *this;
+    }
+
+    // \brief Set to the given value of the type with \c _idx index.
+    //
+    // This function sets the variant to the given value of the type
+    // with \c _idx index.
+    template <int _idx>
+    Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
+      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
+      flag = _idx;
+      new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
+        typename TypeMap::template Map<_idx>::Type(init);
+      return *this;
+    }
+
+    // \brief Gets the current value of the type with \c _idx index.
+    //
+    // Gets the current value of the type with \c _idx index.
+    template <int _idx>
+    const typename TypeMap::template Map<_idx>::Type& get() const {
+      LEMON_DEBUG(_idx == flag, "Variant wrong index");
+      return *reinterpret_cast<const typename TypeMap::
+        template Map<_idx>::Type*>(data);
+    }
+
+    // \brief Gets the current value of the type with \c _idx index.
+    //
+    // Gets the current value of the type with \c _idx index.
+    template <int _idx>
+    typename _TypeMap::template Map<_idx>::Type& get() {
+      LEMON_DEBUG(_idx == flag, "Variant wrong index");
+      return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>
+        (data);
+    }
+
+    // \brief Returns the current state of the variant.
+    //
+    // Returns the current state of the variant.
+    int state() const {
+      return flag;
+    }
+
+  private:
+
+    char data[_variant_bits::Size<num - 1, TypeMap>::value];
+    int flag;
+  };
+
+  namespace _variant_bits {
+
+    template <int _index, typename _List>
+    struct Get {
+      typedef typename Get<_index - 1, typename _List::Next>::Type Type;
+    };
+
+    template <typename _List>
+    struct Get<0, _List> {
+      typedef typename _List::Type Type;
+    };
+
+    struct List {};
+
+    template <typename _Type, typename _List>
+    struct Insert {
+      typedef _List Next;
+      typedef _Type Type;
+    };
+
+    template <int _idx, typename _T0, typename _T1, typename _T2,
+              typename _T3, typename _T4, typename _T5, typename _T6,
+              typename _T7, typename _T8, typename _T9>
+    struct Mapper {
+      typedef List L10;
+      typedef Insert<_T9, L10> L9;
+      typedef Insert<_T8, L9> L8;
+      typedef Insert<_T7, L8> L7;
+      typedef Insert<_T6, L7> L6;
+      typedef Insert<_T5, L6> L5;
+      typedef Insert<_T4, L5> L4;
+      typedef Insert<_T3, L4> L3;
+      typedef Insert<_T2, L3> L2;
+      typedef Insert<_T1, L2> L1;
+      typedef Insert<_T0, L1> L0;
+      typedef typename Get<_idx, L0>::Type Type;
+    };
+
+  }
+
+  // \brief Helper class for Variant
+  //
+  // Helper class to define type mappings for Variant. This class
+  // converts the template parameters to be mappable by integer.
+  // \see Variant
+  template <
+    typename _T0,
+    typename _T1 = void, typename _T2 = void, typename _T3 = void,
+    typename _T4 = void, typename _T5 = void, typename _T6 = void,
+    typename _T7 = void, typename _T8 = void, typename _T9 = void>
+  struct VariantTypeMap {
+    template <int _idx>
+    struct Map {
+      typedef typename _variant_bits::
+      Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type
+      Type;
+    };
+  };
+
+}
+
+
+#endif
diff --git a/lemon/bits/vector_map.h b/lemon/bits/vector_map.h
new file mode 100644
index 0000000..d60841d
--- /dev/null
+++ b/lemon/bits/vector_map.h
@@ -0,0 +1,244 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_VECTOR_MAP_H
+#define LEMON_BITS_VECTOR_MAP_H
+
+#include <vector>
+#include <algorithm>
+
+#include <lemon/core.h>
+#include <lemon/bits/alteration_notifier.h>
+
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
+
+//\ingroup graphbits
+//
+//\file
+//\brief Vector based graph maps.
+namespace lemon {
+
+  // \ingroup graphbits
+  //
+  // \brief Graph map based on the std::vector storage.
+  //
+  // The VectorMap template class is graph map structure that automatically
+  // updates the map when a key is added to or erased from the graph.
+  // This map type uses std::vector to store the values.
+  //
+  // \tparam _Graph The graph this map is attached to.
+  // \tparam _Item The item type of the graph items.
+  // \tparam _Value The value type of the map.
+  template <typename _Graph, typename _Item, typename _Value>
+  class VectorMap
+    : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
+  private:
+
+    // The container type of the map.
+    typedef std::vector<_Value> Container;
+
+  public:
+
+    // The graph type of the map.
+    typedef _Graph GraphType;
+    // The item type of the map.
+    typedef _Item Item;
+    // The reference map tag.
+    typedef True ReferenceMapTag;
+
+    // The key type of the map.
+    typedef _Item Key;
+    // The value type of the map.
+    typedef _Value Value;
+
+    // The notifier type.
+    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
+
+    // The map type.
+    typedef VectorMap Map;
+
+    // The reference type of the map;
+    typedef typename Container::reference Reference;
+    // The const reference type of the map;
+    typedef typename Container::const_reference ConstReference;
+
+  private:
+
+    // The base class of the map.
+    typedef typename Notifier::ObserverBase Parent;
+
+  public:
+
+    // \brief Constructor to attach the new map into the notifier.
+    //
+    // It constructs a map and attachs it into the notifier.
+    // It adds all the items of the graph to the map.
+    VectorMap(const GraphType& graph) {
+      Parent::attach(graph.notifier(Item()));
+      container.resize(Parent::notifier()->maxId() + 1);
+    }
+
+    // \brief Constructor uses given value to initialize the map.
+    //
+    // It constructs a map uses a given value to initialize the map.
+    // It adds all the items of the graph to the map.
+    VectorMap(const GraphType& graph, const Value& value) {
+      Parent::attach(graph.notifier(Item()));
+      container.resize(Parent::notifier()->maxId() + 1, value);
+    }
+
+  private:
+    // \brief Copy constructor
+    //
+    // Copy constructor.
+    VectorMap(const VectorMap& _copy) : Parent() {
+      if (_copy.attached()) {
+        Parent::attach(*_copy.notifier());
+        container = _copy.container;
+      }
+    }
+
+    // \brief Assign operator.
+    //
+    // This operator assigns for each item in the map the
+    // value mapped to the same item in the copied map.
+    // The parameter map should be indiced with the same
+    // itemset because this assign operator does not change
+    // the container of the map.
+    VectorMap& operator=(const VectorMap& cmap) {
+      return operator=<VectorMap>(cmap);
+    }
+
+
+    // \brief Template assign operator.
+    //
+    // The given parameter should conform to the ReadMap
+    // concecpt and could be indiced by the current item set of
+    // the NodeMap. In this case the value for each item
+    // is assigned by the value of the given ReadMap.
+    template <typename CMap>
+    VectorMap& operator=(const CMap& cmap) {
+      checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
+      const typename Parent::Notifier* nf = Parent::notifier();
+      Item it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        set(it, cmap[it]);
+      }
+      return *this;
+    }
+
+  public:
+
+    // \brief The subcript operator.
+    //
+    // The subscript operator. The map can be subscripted by the
+    // actual items of the graph.
+    Reference operator[](const Key& key) {
+      return container[Parent::notifier()->id(key)];
+    }
+
+    // \brief The const subcript operator.
+    //
+    // The const subscript operator. The map can be subscripted by the
+    // actual items of the graph.
+    ConstReference operator[](const Key& key) const {
+      return container[Parent::notifier()->id(key)];
+    }
+
+
+    // \brief The setter function of the map.
+    //
+    // It the same as operator[](key) = value expression.
+    void set(const Key& key, const Value& value) {
+      (*this)[key] = value;
+    }
+
+  protected:
+
+    // \brief Adds a new key to the map.
+    //
+    // It adds a new key to the map. It is called by the observer notifier
+    // and it overrides the add() member function of the observer base.
+    virtual void add(const Key& key) {
+      int id = Parent::notifier()->id(key);
+      if (id >= int(container.size())) {
+        container.resize(id + 1);
+      }
+    }
+
+    // \brief Adds more new keys to the map.
+    //
+    // It adds more new keys to the map. It is called by the observer notifier
+    // and it overrides the add() member function of the observer base.
+    virtual void add(const std::vector<Key>& keys) {
+      int max = container.size() - 1;
+      for (int i = 0; i < int(keys.size()); ++i) {
+        int id = Parent::notifier()->id(keys[i]);
+        if (id >= max) {
+          max = id;
+        }
+      }
+      container.resize(max + 1);
+    }
+
+    // \brief Erase a key from the map.
+    //
+    // Erase a key from the map. It is called by the observer notifier
+    // and it overrides the erase() member function of the observer base.
+    virtual void erase(const Key& key) {
+      container[Parent::notifier()->id(key)] = Value();
+    }
+
+    // \brief Erase more keys from the map.
+    //
+    // It erases more keys from the map. It is called by the observer notifier
+    // and it overrides the erase() member function of the observer base.
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        container[Parent::notifier()->id(keys[i])] = Value();
+      }
+    }
+
+    // \brief Build the map.
+    //
+    // It builds the map. It is called by the observer notifier
+    // and it overrides the build() member function of the observer base.
+    virtual void build() {
+      int size = Parent::notifier()->maxId() + 1;
+      container.reserve(size);
+      container.resize(size);
+    }
+
+    // \brief Clear the map.
+    //
+    // It erases all items from the map. It is called by the observer notifier
+    // and it overrides the clear() member function of the observer base.
+    virtual void clear() {
+      container.clear();
+    }
+
+  private:
+
+    Container container;
+
+  };
+
+}
+
+#endif
diff --git a/lemon/bits/windows.cc b/lemon/bits/windows.cc
new file mode 100644
index 0000000..7ad901c
--- /dev/null
+++ b/lemon/bits/windows.cc
@@ -0,0 +1,166 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Some basic non-inline functions and static global data.
+
+#include<lemon/bits/windows.h>
+
+#ifdef WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#ifdef UNICODE
+#undef UNICODE
+#endif
+#include <windows.h>
+#ifdef LOCALE_INVARIANT
+#define MY_LOCALE LOCALE_INVARIANT
+#else
+#define MY_LOCALE LOCALE_NEUTRAL
+#endif
+#else
+#include <unistd.h>
+#include <ctime>
+#ifndef WIN32
+#include <sys/times.h>
+#endif
+#include <sys/time.h>
+#endif
+
+#include <cmath>
+#include <sstream>
+
+namespace lemon {
+  namespace bits {
+    void getWinProcTimes(double &rtime,
+                         double &utime, double &stime,
+                         double &cutime, double &cstime)
+    {
+#ifdef WIN32
+      static const double ch = 4294967296.0e-7;
+      static const double cl = 1.0e-7;
+
+      FILETIME system;
+      GetSystemTimeAsFileTime(&system);
+      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
+
+      FILETIME create, exit, kernel, user;
+      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
+        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
+        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
+        cutime = 0;
+        cstime = 0;
+      } else {
+        rtime = 0;
+        utime = 0;
+        stime = 0;
+        cutime = 0;
+        cstime = 0;
+      }
+#else
+      timeval tv;
+      gettimeofday(&tv, 0);
+      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
+
+      tms ts;
+      double tck=sysconf(_SC_CLK_TCK);
+      times(&ts);
+      utime=ts.tms_utime/tck;
+      stime=ts.tms_stime/tck;
+      cutime=ts.tms_cutime/tck;
+      cstime=ts.tms_cstime/tck;
+#endif
+    }
+
+    std::string getWinFormattedDate()
+    {
+      std::ostringstream os;
+#ifdef WIN32
+      SYSTEMTIME time;
+      GetSystemTime(&time);
+      char buf1[11], buf2[9], buf3[5];
+          if (GetDateFormat(MY_LOCALE, 0, &time,
+                        ("ddd MMM dd"), buf1, 11) &&
+          GetTimeFormat(MY_LOCALE, 0, &time,
+                        ("HH':'mm':'ss"), buf2, 9) &&
+          GetDateFormat(MY_LOCALE, 0, &time,
+                        ("yyyy"), buf3, 5)) {
+        os << buf1 << ' ' << buf2 << ' ' << buf3;
+      }
+      else os << "unknown";
+#else
+      timeval tv;
+      gettimeofday(&tv, 0);
+
+      char cbuf[26];
+      ctime_r(&tv.tv_sec,cbuf);
+      os << cbuf;
+#endif
+      return os.str();
+    }
+
+    int getWinRndSeed()
+    {
+#ifdef WIN32
+      FILETIME time;
+      GetSystemTimeAsFileTime(&time);
+      return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
+#else
+      timeval tv;
+      gettimeofday(&tv, 0);
+      return getpid() + tv.tv_sec + tv.tv_usec;
+#endif
+    }
+
+    WinLock::WinLock() {
+#ifdef WIN32
+      CRITICAL_SECTION *lock = new CRITICAL_SECTION;
+      InitializeCriticalSection(lock);
+      _repr = lock;
+#else
+      _repr = 0; //Just to avoid 'unused variable' warning with clang
+#endif
+    }
+
+    WinLock::~WinLock() {
+#ifdef WIN32
+      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
+      DeleteCriticalSection(lock);
+      delete lock;
+#endif
+    }
+
+    void WinLock::lock() {
+#ifdef WIN32
+      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
+      EnterCriticalSection(lock);
+#endif
+    }
+
+    void WinLock::unlock() {
+#ifdef WIN32
+      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
+      LeaveCriticalSection(lock);
+#endif
+    }
+  }
+}
diff --git a/lemon/bits/windows.h b/lemon/bits/windows.h
new file mode 100644
index 0000000..c09bb12
--- /dev/null
+++ b/lemon/bits/windows.h
@@ -0,0 +1,44 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_WINDOWS_H
+#define LEMON_BITS_WINDOWS_H
+
+#include <string>
+
+namespace lemon {
+  namespace bits {
+    void getWinProcTimes(double &rtime,
+                         double &utime, double &stime,
+                         double &cutime, double &cstime);
+    std::string getWinFormattedDate();
+    int getWinRndSeed();
+
+    class WinLock {
+    public:
+      WinLock();
+      ~WinLock();
+      void lock();
+      void unlock();
+    private:
+      void *_repr;
+    };
+  }
+}
+
+#endif
diff --git a/lemon/bucket_heap.h b/lemon/bucket_heap.h
new file mode 100644
index 0000000..92dbc08
--- /dev/null
+++ b/lemon/bucket_heap.h
@@ -0,0 +1,594 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BUCKET_HEAP_H
+#define LEMON_BUCKET_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Bucket heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  namespace _bucket_heap_bits {
+
+    template <bool MIN>
+    struct DirectionTraits {
+      static bool less(int left, int right) {
+        return left < right;
+      }
+      static void increase(int& value) {
+        ++value;
+      }
+    };
+
+    template <>
+    struct DirectionTraits<false> {
+      static bool less(int left, int right) {
+        return left > right;
+      }
+      static void increase(int& value) {
+        --value;
+      }
+    };
+
+  }
+
+  /// \ingroup heaps
+  ///
+  /// \brief Bucket heap data structure.
+  ///
+  /// This class implements the \e bucket \e heap data structure.
+  /// It practically conforms to the \ref concepts::Heap "heap concept",
+  /// but it has some limitations.
+  ///
+  /// The bucket heap is a very simple structure. It can store only
+  /// \c int priorities and it maintains a list of items for each priority
+  /// in the range <tt>[0..C)</tt>. So it should only be used when the
+  /// priorities are small. It is not intended to use as a Dijkstra heap.
+  ///
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
+  /// The default is \e min-heap. If this parameter is set to \c false,
+  /// then the comparison is reversed, so the top(), prio() and pop()
+  /// functions deal with the item having maximum priority instead of the
+  /// minimum.
+  ///
+  /// \sa SimpleBucketHeap
+  template <typename IM, bool MIN = true>
+  class BucketHeap {
+
+  public:
+
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef int Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+
+  private:
+
+    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
+
+  public:
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _first.clear(); _minimum = 0;
+    }
+
+  private:
+
+    void relocateLast(int idx) {
+      if (idx + 1 < int(_data.size())) {
+        _data[idx] = _data.back();
+        if (_data[idx].prev != -1) {
+          _data[_data[idx].prev].next = idx;
+        } else {
+          _first[_data[idx].value] = idx;
+        }
+        if (_data[idx].next != -1) {
+          _data[_data[idx].next].prev = idx;
+        }
+        _iim[_data[idx].item] = idx;
+      }
+      _data.pop_back();
+    }
+
+    void unlace(int idx) {
+      if (_data[idx].prev != -1) {
+        _data[_data[idx].prev].next = _data[idx].next;
+      } else {
+        _first[_data[idx].value] = _data[idx].next;
+      }
+      if (_data[idx].next != -1) {
+        _data[_data[idx].next].prev = _data[idx].prev;
+      }
+    }
+
+    void lace(int idx) {
+      if (int(_first.size()) <= _data[idx].value) {
+        _first.resize(_data[idx].value + 1, -1);
+      }
+      _data[idx].next = _first[_data[idx].value];
+      if (_data[idx].next != -1) {
+        _data[_data[idx].next].prev = idx;
+      }
+      _first[_data[idx].value] = idx;
+      _data[idx].prev = -1;
+    }
+
+  public:
+
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair& p) {
+      push(p.first, p.second);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) {
+      int idx = _data.size();
+      _iim[i] = idx;
+      _data.push_back(BucketItem(i, p));
+      lace(idx);
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _data[_first[_minimum]].item;
+    }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _minimum;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      int idx = _first[_minimum];
+      _iim[_data[idx].item] = -2;
+      unlace(idx);
+      relocateLast(idx);
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int idx = _iim[i];
+      _iim[_data[idx].item] = -2;
+      unlace(idx);
+      relocateLast(idx);
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].value;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if (idx < 0) {
+        push(i, p);
+      } else if (Direction::less(p, _data[idx].value)) {
+        decrease(i, p);
+      } else {
+        increase(i, p);
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      unlace(idx);
+      _data[idx].value = p;
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+      lace(idx);
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      unlace(idx);
+      _data[idx].value = p;
+      lace(idx);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int idx = _iim[i];
+      if (idx >= 0) idx = 0;
+      return State(idx);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    struct BucketItem {
+      BucketItem(const Item& _item, int _value)
+        : item(_item), value(_value) {}
+
+      Item item;
+      int value;
+
+      int prev, next;
+    };
+
+    ItemIntMap& _iim;
+    std::vector<int> _first;
+    std::vector<BucketItem> _data;
+    mutable int _minimum;
+
+  }; // class BucketHeap
+
+  /// \ingroup heaps
+  ///
+  /// \brief Simplified bucket heap data structure.
+  ///
+  /// This class implements a simplified \e bucket \e heap data
+  /// structure. It does not provide some functionality, but it is
+  /// faster and simpler than BucketHeap. The main difference is
+  /// that BucketHeap stores a doubly-linked list for each key while
+  /// this class stores only simply-linked lists. It supports erasing
+  /// only for the item having minimum priority and it does not support
+  /// key increasing and decreasing.
+  ///
+  /// Note that this implementation does not conform to the
+  /// \ref concepts::Heap "heap concept" due to the lack of some
+  /// functionality.
+  ///
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
+  /// The default is \e min-heap. If this parameter is set to \c false,
+  /// then the comparison is reversed, so the top(), prio() and pop()
+  /// functions deal with the item having maximum priority instead of the
+  /// minimum.
+  ///
+  /// \sa BucketHeap
+  template <typename IM, bool MIN = true >
+  class SimpleBucketHeap {
+
+  public:
+
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef int Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+
+  private:
+
+    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
+
+  public:
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit SimpleBucketHeap(ItemIntMap &map)
+      : _iim(map), _free(-1), _num(0), _minimum(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num == 0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
+    }
+
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair& p) {
+      push(p.first, p.second);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) {
+      int idx;
+      if (_free == -1) {
+        idx = _data.size();
+        _data.push_back(BucketItem(i));
+      } else {
+        idx = _free;
+        _free = _data[idx].next;
+        _data[idx].item = i;
+      }
+      _iim[i] = idx;
+      if (p >= int(_first.size())) _first.resize(p + 1, -1);
+      _data[idx].next = _first[p];
+      _first[p] = idx;
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+      ++_num;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _data[_first[_minimum]].item;
+    }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _minimum;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      int idx = _first[_minimum];
+      _iim[_data[idx].item] = -2;
+      _first[_minimum] = _data[idx].next;
+      _data[idx].next = _free;
+      _free = idx;
+      --_num;
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    /// \warning This operator is not a constant time function because
+    /// it scans the whole data structure to find the proper value.
+    Prio operator[](const Item &i) const {
+      for (int k = 0; k < int(_first.size()); ++k) {
+        int idx = _first[k];
+        while (idx != -1) {
+          if (_data[idx].item == i) {
+            return k;
+          }
+          idx = _data[idx].next;
+        }
+      }
+      return -1;
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int idx = _iim[i];
+      if (idx >= 0) idx = 0;
+      return State(idx);
+    }
+
+  private:
+
+    struct BucketItem {
+      BucketItem(const Item& _item)
+        : item(_item) {}
+
+      Item item;
+      int next;
+    };
+
+    ItemIntMap& _iim;
+    std::vector<int> _first;
+    std::vector<BucketItem> _data;
+    int _free, _num;
+    mutable int _minimum;
+
+  }; // class SimpleBucketHeap
+
+}
+
+#endif
diff --git a/lemon/capacity_scaling.h b/lemon/capacity_scaling.h
new file mode 100644
index 0000000..ca64b56
--- /dev/null
+++ b/lemon/capacity_scaling.h
@@ -0,0 +1,1014 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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" \cite amo93networkflows,
+  /// \cite edmondskarp72theoretical. It is an efficient dual
+  /// solution method, which runs in polynomial time
+  /// \f$O(m\log U (n+m)\log n)\f$, where <i>U</i> denotes the maximum
+  /// of node supply and arc capacity values.
+  ///
+  /// This algorithm is typically slower than \ref CostScaling and
+  /// \ref NetworkSimplex, but in special cases, it can be more
+  /// efficient than them.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
+  ///
+  /// 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 \c V and \c C must be signed number types.
+  /// \warning Capacity bounds and supply values must be integer, but
+  /// arc costs can be arbitrary real numbers.
+  /// \warning This algorithm does not support negative costs for
+  /// arcs having 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;
+
+    /// \brief The \ref lemon::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 _has_lower;
+    Value _sum_supply;
+
+    // Data structures for storing the digraph
+    IntNodeMap _node_id;
+    IntArcMap _arc_idf;
+    IntArcMap _arc_idb;
+    IntVector _first_out;
+    BoolVector _forward;
+    IntVector _source;
+    IntVector _target;
+    IntVector _reverse;
+
+    // Node and arc data
+    ValueVector _lower;
+    ValueVector _upper;
+    CostVector _cost;
+    ValueVector _supply;
+
+    ValueVector _res_cap;
+    CostVector _pi;
+    ValueVector _excess;
+    IntVector _excess_nodes;
+    IntVector _deficit_nodes;
+
+    Value _delta;
+    int _factor;
+    IntVector _pred;
+
+  public:
+
+    /// \brief Constant for infinite upper bounds (capacities).
+    ///
+    /// Constant for infinite upper bounds (capacities).
+    /// It is \c std::numeric_limits<Value>::infinity() if available,
+    /// \c std::numeric_limits<Value>::max() otherwise.
+    const Value INF;
+
+  private:
+
+    // Special implementation of the Dijkstra algorithm for finding
+    // shortest paths in the residual network of the digraph with
+    // respect to the reduced arc costs and modifying the node
+    // potentials according to the found distance labels.
+    class ResidualDijkstra
+    {
+    private:
+
+      int _node_num;
+      bool _geq;
+      const IntVector &_first_out;
+      const IntVector &_target;
+      const CostVector &_cost;
+      const ValueVector &_res_cap;
+      const ValueVector &_excess;
+      CostVector &_pi;
+      IntVector &_pred;
+
+      IntVector _proc_nodes;
+      CostVector _dist;
+
+    public:
+
+      ResidualDijkstra(CapacityScaling& cs) :
+        _node_num(cs._node_num), _geq(cs._sum_supply < 0),
+        _first_out(cs._first_out), _target(cs._target), _cost(cs._cost),
+        _res_cap(cs._res_cap), _excess(cs._excess), _pi(cs._pi),
+        _pred(cs._pred), _dist(cs._node_num)
+      {}
+
+      int run(int s, Value delta = 1) {
+        RangeMap<int> heap_cross_ref(_node_num, Heap::PRE_HEAP);
+        Heap heap(heap_cross_ref);
+        heap.push(s, 0);
+        _pred[s] = -1;
+        _proc_nodes.clear();
+
+        // Process nodes
+        while (!heap.empty() && _excess[heap.top()] > -delta) {
+          int u = heap.top(), v;
+          Cost d = heap.prio() + _pi[u], dn;
+          _dist[u] = heap.prio();
+          _proc_nodes.push_back(u);
+          heap.pop();
+
+          // Traverse outgoing residual arcs
+          int last_out = _geq ? _first_out[u+1] : _first_out[u+1] - 1;
+          for (int a = _first_out[u]; a != last_out; ++a) {
+            if (_res_cap[a] < delta) continue;
+            v = _target[a];
+            switch (heap.state(v)) {
+              case Heap::PRE_HEAP:
+                heap.push(v, d + _cost[a] - _pi[v]);
+                _pred[v] = a;
+                break;
+              case Heap::IN_HEAP:
+                dn = d + _cost[a] - _pi[v];
+                if (dn < heap[v]) {
+                  heap.decrease(v, dn);
+                  _pred[v] = a;
+                }
+                break;
+              case Heap::POST_HEAP:
+                break;
+            }
+          }
+        }
+        if (heap.empty()) return -1;
+
+        // Update potentials of processed nodes
+        int t = heap.top();
+        Cost dt = heap.prio();
+        for (int i = 0; i < int(_proc_nodes.size()); ++i) {
+          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - dt;
+        }
+
+        return t;
+      }
+
+    }; //class ResidualDijkstra
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetHeapTraits : public Traits {
+      typedef T Heap;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c Heap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c Heap
+    /// type, which is used for internal Dijkstra computations.
+    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
+    /// its priority type must be \c Cost and its cross reference type
+    /// must be \ref RangeMap "RangeMap<int>".
+    template <typename T>
+    struct SetHeap
+      : public CapacityScaling<GR, V, C, SetHeapTraits<T> > {
+      typedef  CapacityScaling<GR, V, C, SetHeapTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    CapacityScaling() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    CapacityScaling(const GR& graph) :
+      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
+      INF(std::numeric_limits<Value>::has_infinity ?
+          std::numeric_limits<Value>::infinity() :
+          std::numeric_limits<Value>::max())
+    {
+      // Check the number types
+      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
+        "The flow type of CapacityScaling must be signed");
+      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
+        "The cost type of CapacityScaling must be signed");
+
+      // Reset data structures
+      reset();
+    }
+
+    /// \name Parameters
+    /// The parameters of the algorithm can be specified using these
+    /// functions.
+
+    /// @{
+
+    /// \brief Set the lower bounds on the arcs.
+    ///
+    /// This function sets the lower bounds on the arcs.
+    /// If it is not used before calling \ref run(), the lower bounds
+    /// will be set to zero on all arcs.
+    ///
+    /// \param map An arc map storing the lower bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template <typename LowerMap>
+    CapacityScaling& lowerMap(const LowerMap& map) {
+      _has_lower = true;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _lower[_arc_idf[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 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;
+      }
+      _has_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(m).
+    ///
+    /// \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 Copy the flow values (the primal solution) into the
+    /// given map.
+    ///
+    /// 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 Copy the potential values (the dual solution) into the
+    /// given map.
+    ///
+    /// 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;
+
+      // Check lower and upper bounds
+      LEMON_DEBUG(checkBoundMaps(),
+          "Upper bounds must be greater or equal to the lower bounds");
+
+
+      // 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 (_has_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;
+    }
+
+    // Check if the upper bound is greater than or equal to the lower bound
+    // on each forward arc.
+    bool checkBoundMaps() {
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_forward[j] && _upper[j] < _lower[j]) return false;
+      }
+      return true;
+    }
+
+    ProblemType start() {
+      // Execute the algorithm
+      ProblemType pt;
+      if (_delta > 1)
+        pt = startWithScaling();
+      else
+        pt = startWithoutScaling();
+
+      // Handle non-zero lower bounds
+      if (_has_lower) {
+        int limit = _first_out[_root];
+        for (int j = 0; j != limit; ++j) {
+          if (_forward[j]) _res_cap[_reverse[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
diff --git a/lemon/cbc.cc b/lemon/cbc.cc
new file mode 100644
index 0000000..62331b1
--- /dev/null
+++ b/lemon/cbc.cc
@@ -0,0 +1,460 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Implementation of the CBC MIP solver interface.
+
+#include "cbc.h"
+
+#include <coin/CoinModel.hpp>
+#include <coin/CbcModel.hpp>
+#include <coin/OsiSolverInterface.hpp>
+
+#include "coin/OsiClpSolverInterface.hpp"
+
+#include "coin/CbcCutGenerator.hpp"
+#include "coin/CbcHeuristicLocal.hpp"
+#include "coin/CbcHeuristicGreedy.hpp"
+#include "coin/CbcHeuristicFPump.hpp"
+#include "coin/CbcHeuristicRINS.hpp"
+
+#include "coin/CglGomory.hpp"
+#include "coin/CglProbing.hpp"
+#include "coin/CglKnapsackCover.hpp"
+#include "coin/CglOddHole.hpp"
+#include "coin/CglClique.hpp"
+#include "coin/CglFlowCover.hpp"
+#include "coin/CglMixedIntegerRounding.hpp"
+
+#include "coin/CbcHeuristic.hpp"
+
+namespace lemon {
+
+  CbcMip::CbcMip() {
+    _prob = new CoinModel();
+    _prob->setProblemName("LEMON");
+    _osi_solver = 0;
+    _cbc_model = 0;
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  CbcMip::CbcMip(const CbcMip& other) {
+    _prob = new CoinModel(*other._prob);
+    _prob->setProblemName("LEMON");
+    _osi_solver = 0;
+    _cbc_model = 0;
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  CbcMip::~CbcMip() {
+    delete _prob;
+    if (_osi_solver) delete _osi_solver;
+    if (_cbc_model) delete _cbc_model;
+  }
+
+  const char* CbcMip::_solverName() const { return "CbcMip"; }
+
+  int CbcMip::_addCol() {
+    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
+    return _prob->numberColumns() - 1;
+  }
+
+  CbcMip* CbcMip::newSolver() const {
+    CbcMip* newlp = new CbcMip;
+    return newlp;
+  }
+
+  CbcMip* CbcMip::cloneSolver() const {
+    CbcMip* copylp = new CbcMip(*this);
+    return copylp;
+  }
+
+  int CbcMip::_addRow() {
+    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
+    return _prob->numberRows() - 1;
+  }
+
+  int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
+    return _prob->numberRows() - 1;
+  }
+
+  void CbcMip::_eraseCol(int i) {
+    _prob->deleteColumn(i);
+  }
+
+  void CbcMip::_eraseRow(int i) {
+    _prob->deleteRow(i);
+  }
+
+  void CbcMip::_eraseColId(int i) {
+    cols.eraseIndex(i);
+  }
+
+  void CbcMip::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+  }
+
+  void CbcMip::_getColName(int c, std::string& name) const {
+    name = _prob->getColumnName(c);
+  }
+
+  void CbcMip::_setColName(int c, const std::string& name) {
+    _prob->setColumnName(c, name.c_str());
+  }
+
+  int CbcMip::_colByName(const std::string& name) const {
+    return _prob->column(name.c_str());
+  }
+
+  void CbcMip::_getRowName(int r, std::string& name) const {
+    name = _prob->getRowName(r);
+  }
+
+  void CbcMip::_setRowName(int r, const std::string& name) {
+    _prob->setRowName(r, name.c_str());
+  }
+
+  int CbcMip::_rowByName(const std::string& name) const {
+    return _prob->row(name.c_str());
+  }
+
+  void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setElement(i, it->first, it->second);
+    }
+  }
+
+  void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
+    int length = _prob->numberRows();
+
+    std::vector<int> indices(length);
+    std::vector<Value> values(length);
+
+    length = _prob->getRow(ix, &indices[0], &values[0]);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+  }
+
+  void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setElement(it->first, ix, it->second);
+    }
+  }
+
+  void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
+    int length = _prob->numberColumns();
+
+    std::vector<int> indices(length);
+    std::vector<Value> values(length);
+
+    length = _prob->getColumn(ix, &indices[0], &values[0]);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+  }
+
+  void CbcMip::_setCoeff(int ix, int jx, Value value) {
+    _prob->setElement(ix, jx, value);
+  }
+
+  CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
+    return _prob->getElement(ix, jx);
+  }
+
+
+  void CbcMip::_setColLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  CbcMip::Value CbcMip::_getColLowerBound(int i) const {
+    double val = _prob->getColumnLower(i);
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void CbcMip::_setColUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  CbcMip::Value CbcMip::_getColUpperBound(int i) const {
+    double val = _prob->getColumnUpper(i);
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void CbcMip::_setRowLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
+    double val = _prob->getRowLower(i);
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void CbcMip::_setRowUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
+    double val = _prob->getRowUpper(i);
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    int num = _prob->numberColumns();
+    for (int i = 0; i < num; ++i) {
+      _prob->setColumnObjective(i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setColumnObjective(it->first, it->second);
+    }
+  }
+
+  void CbcMip::_getObjCoeffs(InsertIterator b) const {
+    int num = _prob->numberColumns();
+    for (int i = 0; i < num; ++i) {
+      Value coef = _prob->getColumnObjective(i);
+      if (coef != 0.0) {
+        *b = std::make_pair(i, coef);
+        ++b;
+      }
+    }
+  }
+
+  void CbcMip::_setObjCoeff(int i, Value obj_coef) {
+    _prob->setColumnObjective(i, obj_coef);
+  }
+
+  CbcMip::Value CbcMip::_getObjCoeff(int i) const {
+    return _prob->getColumnObjective(i);
+  }
+
+  CbcMip::SolveExitStatus CbcMip::_solve() {
+
+    if (_osi_solver) {
+      delete _osi_solver;
+    }
+    _osi_solver = new OsiClpSolverInterface();
+
+    _osi_solver->loadFromCoinModel(*_prob);
+
+    if (_cbc_model) {
+      delete _cbc_model;
+    }
+    _cbc_model= new CbcModel(*_osi_solver);
+
+    _osi_solver->messageHandler()->setLogLevel(_message_level);
+    _cbc_model->setLogLevel(_message_level);
+
+    _cbc_model->initialSolve();
+    _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
+
+    if (!_cbc_model->isInitialSolveAbandoned() &&
+        _cbc_model->isInitialSolveProvenOptimal() &&
+        !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
+        !_cbc_model->isInitialSolveProvenDualInfeasible()) {
+
+      CglProbing generator1;
+      generator1.setUsingObjective(true);
+      generator1.setMaxPass(3);
+      generator1.setMaxProbe(100);
+      generator1.setMaxLook(50);
+      generator1.setRowCuts(3);
+      _cbc_model->addCutGenerator(&generator1, -1, "Probing");
+
+      CglGomory generator2;
+      generator2.setLimit(300);
+      _cbc_model->addCutGenerator(&generator2, -1, "Gomory");
+
+      CglKnapsackCover generator3;
+      _cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
+
+      CglOddHole generator4;
+      generator4.setMinimumViolation(0.005);
+      generator4.setMinimumViolationPer(0.00002);
+      generator4.setMaximumEntries(200);
+      _cbc_model->addCutGenerator(&generator4, -1, "OddHole");
+
+      CglClique generator5;
+      generator5.setStarCliqueReport(false);
+      generator5.setRowCliqueReport(false);
+      _cbc_model->addCutGenerator(&generator5, -1, "Clique");
+
+      CglMixedIntegerRounding mixedGen;
+      _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
+
+      CglFlowCover flowGen;
+      _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
+
+      OsiClpSolverInterface* osiclp =
+        dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
+      if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
+        osiclp->setupForRepeatedUse(2, 0);
+      }
+
+      CbcRounding heuristic1(*_cbc_model);
+      heuristic1.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic1);
+
+      CbcHeuristicLocal heuristic2(*_cbc_model);
+      heuristic2.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic2);
+
+      CbcHeuristicGreedyCover heuristic3(*_cbc_model);
+      heuristic3.setAlgorithm(11);
+      heuristic3.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic3);
+
+      CbcHeuristicFPump heuristic4(*_cbc_model);
+      heuristic4.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic4);
+
+      CbcHeuristicRINS heuristic5(*_cbc_model);
+      heuristic5.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic5);
+
+      if (_cbc_model->getNumCols() < 500) {
+        _cbc_model->setMaximumCutPassesAtRoot(-100);
+      } else if (_cbc_model->getNumCols() < 5000) {
+        _cbc_model->setMaximumCutPassesAtRoot(100);
+      } else {
+        _cbc_model->setMaximumCutPassesAtRoot(20);
+      }
+
+      if (_cbc_model->getNumCols() < 5000) {
+        _cbc_model->setNumberStrong(10);
+      }
+
+      _cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
+      _cbc_model->branchAndBound();
+    }
+
+    if (_cbc_model->isAbandoned()) {
+      return UNSOLVED;
+    } else {
+      return SOLVED;
+    }
+  }
+
+  CbcMip::Value CbcMip::_getSol(int i) const {
+    return _cbc_model->getColSolution()[i];
+  }
+
+  CbcMip::Value CbcMip::_getSolValue() const {
+    return _cbc_model->getObjValue();
+  }
+
+  CbcMip::ProblemType CbcMip::_getType() const {
+    if (_cbc_model->isProvenOptimal()) {
+      return OPTIMAL;
+    } else if (_cbc_model->isContinuousUnbounded()) {
+      return UNBOUNDED;
+    }
+    return FEASIBLE;
+  }
+
+  void CbcMip::_setSense(Sense sense) {
+    switch (sense) {
+    case MIN:
+      _prob->setOptimizationDirection(1.0);
+      break;
+    case MAX:
+      _prob->setOptimizationDirection(- 1.0);
+      break;
+    }
+  }
+
+  CbcMip::Sense CbcMip::_getSense() const {
+    if (_prob->optimizationDirection() > 0.0) {
+      return MIN;
+    } else if (_prob->optimizationDirection() < 0.0) {
+      return MAX;
+    } else {
+      LEMON_ASSERT(false, "Wrong sense");
+      return CbcMip::Sense();
+    }
+  }
+
+  void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
+    switch (col_type){
+    case INTEGER:
+      _prob->setInteger(i);
+      break;
+    case REAL:
+      _prob->setContinuous(i);
+      break;
+    default:;
+      LEMON_ASSERT(false, "Wrong sense");
+    }
+  }
+
+  CbcMip::ColTypes CbcMip::_getColType(int i) const {
+    return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
+  }
+
+  void CbcMip::_clear() {
+    delete _prob;
+    if (_osi_solver) {
+      delete _osi_solver;
+      _osi_solver = 0;
+    }
+    if (_cbc_model) {
+      delete _cbc_model;
+      _cbc_model = 0;
+    }
+
+    _prob = new CoinModel();
+  }
+
+  void CbcMip::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _message_level = 0;
+      break;
+    case MESSAGE_ERROR:
+      _message_level = 1;
+      break;
+    case MESSAGE_WARNING:
+      _message_level = 1;
+      break;
+    case MESSAGE_NORMAL:
+      _message_level = 2;
+      break;
+    case MESSAGE_VERBOSE:
+      _message_level = 3;
+      break;
+    }
+  }
+
+} //END OF NAMESPACE LEMON
diff --git a/lemon/cbc.h b/lemon/cbc.h
new file mode 100644
index 0000000..968e504
--- /dev/null
+++ b/lemon/cbc.h
@@ -0,0 +1,129 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_CBC_H
+#define LEMON_CBC_H
+
+///\file
+///\brief Header of the LEMON-CBC mip solver interface.
+///\ingroup lp_group
+
+#include <lemon/lp_base.h>
+
+class CoinModel;
+class OsiSolverInterface;
+class CbcModel;
+
+namespace lemon {
+
+  /// \brief Interface for the CBC MIP solver
+  ///
+  /// This class implements an interface for the CBC MIP solver.
+  ///\ingroup lp_group
+  class CbcMip : public MipSolver {
+  protected:
+
+    CoinModel *_prob;
+    OsiSolverInterface *_osi_solver;
+    CbcModel *_cbc_model;
+
+  public:
+
+    /// \e
+    CbcMip();
+    /// \e
+    CbcMip(const CbcMip&);
+    /// \e
+    ~CbcMip();
+    /// \e
+    virtual CbcMip* newSolver() const;
+    /// \e
+    virtual CbcMip* cloneSolver() const;
+
+  protected:
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+    virtual void _clear();
+
+    virtual void _messageLevel(MessageLevel level);
+    void _applyMessageLevel();
+
+    int _message_level;
+
+
+
+  };
+
+}
+
+#endif
diff --git a/lemon/christofides_tsp.h b/lemon/christofides_tsp.h
new file mode 100644
index 0000000..2997567
--- /dev/null
+++ b/lemon/christofides_tsp.h
@@ -0,0 +1,254 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_CHRISTOFIDES_TSP_H
+#define LEMON_CHRISTOFIDES_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief Christofides algorithm for symmetric TSP
+
+#include <lemon/full_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/kruskal.h>
+#include <lemon/matching.h>
+#include <lemon/euler.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief Christofides algorithm for symmetric TSP.
+  ///
+  /// ChristofidesTsp implements Christofides' heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This a well-known approximation method for the TSP problem with
+  /// metric cost function.
+  /// It has a guaranteed approximation factor of 3/2 (i.e. it finds a tour
+  /// whose total cost is at most 3/2 of the optimum), but it usually
+  /// provides better solutions in practice.
+  /// This implementation runs in O(n<sup>3</sup>log(n)) time.
+  ///
+  /// The algorithm starts with a \ref spantree "minimum cost spanning tree" and
+  /// finds a \ref MaxWeightedPerfectMatching "minimum cost perfect matching"
+  /// in the subgraph induced by the nodes that have odd degree in the
+  /// spanning tree.
+  /// Finally, it constructs the tour from the \ref EulerIt "Euler traversal"
+  /// of the union of the spanning tree and the matching.
+  /// During this last step, the algorithm simply skips the visited nodes
+  /// (i.e. creates shortcuts) assuming that the triangle inequality holds
+  /// for the cost function.
+  ///
+  /// \tparam CM Type of the cost map.
+  ///
+  /// \warning CM::Value must be a signed number type.
+  template <typename CM>
+  class ChristofidesTsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      std::vector<Node> _path;
+      Cost _sum;
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      ChristofidesTsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm.
+      ///
+      /// This function runs the algorithm.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run() {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 2) {
+          _path.push_back(_gr(0));
+          _path.push_back(_gr(1));
+          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
+        }
+
+        // Compute min. cost spanning tree
+        std::vector<Edge> tree;
+        kruskal(_gr, _cost, std::back_inserter(tree));
+
+        FullGraph::NodeMap<int> deg(_gr, 0);
+        for (int i = 0; i != int(tree.size()); ++i) {
+          Edge e = tree[i];
+          ++deg[_gr.u(e)];
+          ++deg[_gr.v(e)];
+        }
+
+        // Copy the induced subgraph of odd nodes
+        std::vector<Node> odd_nodes;
+        for (NodeIt u(_gr); u != INVALID; ++u) {
+          if (deg[u] % 2 == 1) odd_nodes.push_back(u);
+        }
+
+        SmartGraph sgr;
+        SmartGraph::EdgeMap<Cost> scost(sgr);
+        for (int i = 0; i != int(odd_nodes.size()); ++i) {
+          sgr.addNode();
+        }
+        for (int i = 0; i != int(odd_nodes.size()); ++i) {
+          for (int j = 0; j != int(odd_nodes.size()); ++j) {
+            if (j == i) continue;
+            SmartGraph::Edge e =
+              sgr.addEdge(sgr.nodeFromId(i), sgr.nodeFromId(j));
+            scost[e] = -_cost[_gr.edge(odd_nodes[i], odd_nodes[j])];
+          }
+        }
+
+        // Compute min. cost perfect matching
+        MaxWeightedPerfectMatching<SmartGraph, SmartGraph::EdgeMap<Cost> >
+          mwpm(sgr, scost);
+        mwpm.run();
+
+        for (SmartGraph::EdgeIt e(sgr); e != INVALID; ++e) {
+          if (mwpm.matching(e)) {
+            tree.push_back( _gr.edge(odd_nodes[sgr.id(sgr.u(e))],
+                                     odd_nodes[sgr.id(sgr.v(e))]) );
+          }
+        }
+
+        // Join the spanning tree and the matching
+        sgr.clear();
+        for (int i = 0; i != _gr.nodeNum(); ++i) {
+          sgr.addNode();
+        }
+        for (int i = 0; i != int(tree.size()); ++i) {
+          int ui = _gr.id(_gr.u(tree[i])),
+              vi = _gr.id(_gr.v(tree[i]));
+          sgr.addEdge(sgr.nodeFromId(ui), sgr.nodeFromId(vi));
+        }
+
+        // Compute the tour from the Euler traversal
+        SmartGraph::NodeMap<bool> visited(sgr, false);
+        for (EulerIt<SmartGraph> e(sgr); e != INVALID; ++e) {
+          SmartGraph::Node n = sgr.target(e);
+          if (!visited[n]) {
+            _path.push_back(_gr(sgr.id(n)));
+            visited[n] = true;
+          }
+        }
+
+        _sum = _cost[_gr.edge(_path.back(), _path.front())];
+        for (int i = 0; i < int(_path.size())-1; ++i) {
+          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
+        }
+
+        return _sum;
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _path;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_path.begin(), _path.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_path.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_path[i], _path[i+1]));
+        }
+        if (int(_path.size()) >= 2) {
+          path.addBack(_gr.arc(_path.back(), _path.front()));
+        }
+      }
+
+      /// @}
+
+  };
+
+}; // namespace lemon
+
+#endif
diff --git a/lemon/circulation.h b/lemon/circulation.h
new file mode 100644
index 0000000..b0f717b
--- /dev/null
+++ b/lemon/circulation.h
@@ -0,0 +1,807 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_CIRCULATION_H
+#define LEMON_CIRCULATION_H
+
+#include <lemon/tolerance.h>
+#include <lemon/elevator.h>
+#include <limits>
+
+///\ingroup max_flow
+///\file
+///\brief Push-relabel algorithm for finding a feasible circulation.
+///
+namespace lemon {
+
+  /// \brief Default traits class of Circulation class.
+  ///
+  /// Default traits class of Circulation class.
+  ///
+  /// \tparam GR Type of the digraph the algorithm runs on.
+  /// \tparam LM The type of the lower bound map.
+  /// \tparam UM The type of the upper bound (capacity) map.
+  /// \tparam SM The type of the supply map.
+  template <typename GR, typename LM,
+            typename UM, typename SM>
+  struct CirculationDefaultTraits {
+
+    /// \brief The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the lower bound map.
+    ///
+    /// The type of the map that stores the lower bounds on the arcs.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LM LowerMap;
+
+    /// \brief The type of the upper bound (capacity) map.
+    ///
+    /// The type of the map that stores the upper bounds (capacities)
+    /// on the arcs.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef UM UpperMap;
+
+    /// \brief The type of supply map.
+    ///
+    /// The type of the map that stores the signed supply values of the
+    /// nodes.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef SM SupplyMap;
+
+    /// \brief The type of the flow and supply values.
+    typedef typename SupplyMap::Value Value;
+
+    /// \brief The type of the map that stores the flow values.
+    ///
+    /// The type of the map that stores the flow values.
+    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
+    /// concept.
+#ifdef DOXYGEN
+    typedef GR::ArcMap<Value> FlowMap;
+#else
+    typedef typename Digraph::template ArcMap<Value> FlowMap;
+#endif
+
+    /// \brief Instantiates a FlowMap.
+    ///
+    /// This function instantiates a \ref FlowMap.
+    /// \param digraph The digraph for which we would like to define
+    /// the flow map.
+    static FlowMap* createFlowMap(const Digraph& digraph) {
+      return new FlowMap(digraph);
+    }
+
+    /// \brief The elevator type used by the algorithm.
+    ///
+    /// The elevator type used by the algorithm.
+    ///
+    /// \sa Elevator, LinkedElevator
+#ifdef DOXYGEN
+    typedef lemon::Elevator<GR, GR::Node> Elevator;
+#else
+    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
+#endif
+
+    /// \brief Instantiates an Elevator.
+    ///
+    /// This function instantiates an \ref Elevator.
+    /// \param digraph The digraph for which we would like to define
+    /// the elevator.
+    /// \param max_level The maximum level of the elevator.
+    static Elevator* createElevator(const Digraph& digraph, int max_level) {
+      return new Elevator(digraph, max_level);
+    }
+
+    /// \brief The tolerance used by the algorithm
+    ///
+    /// The tolerance used by the algorithm to handle inexact computation.
+    typedef lemon::Tolerance<Value> Tolerance;
+
+  };
+
+  /**
+     \brief Push-relabel algorithm for the network circulation problem.
+
+     \ingroup max_flow
+     This class implements a push-relabel algorithm for the \e network
+     \e circulation problem.
+     It is to find a feasible circulation when lower and upper bounds
+     are given for the flow values on the arcs and lower bounds are
+     given for the difference between the outgoing and incoming flow
+     at the nodes.
+
+     The exact formulation of this problem is the following.
+     Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
+     \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
+     upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
+     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
+     denotes the signed supply values of the nodes.
+     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
+     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
+     \f$-sup(u)\f$ demand.
+     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
+     solution of the following problem.
+
+     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
+     \geq sup(u) \quad \forall u\in V, \f]
+     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
+
+     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
+     zero or negative in order to have a feasible solution (since the sum
+     of the expressions on the left-hand side of the inequalities is zero).
+     It means that the total demand must be greater or equal to the total
+     supply and all the supplies have to be carried out from the supply nodes,
+     but there could be demands that are not satisfied.
+     If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
+     constraints have to be satisfied with equality, i.e. all demands
+     have to be satisfied and all supplies have to be used.
+
+     If you need the opposite inequalities in the supply/demand constraints
+     (i.e. the total demand is less than the total supply and all the demands
+     have to be satisfied while there could be supplies that are not used),
+     then you could easily transform the problem to the above form by reversing
+     the direction of the arcs and taking the negative of the supply values
+     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
+
+     This algorithm either calculates a feasible circulation, or provides
+     a \ref barrier() "barrier", which prooves that a feasible soultion
+     cannot exist.
+
+     Note that this algorithm also provides a feasible solution for the
+     \ref min_cost_flow "minimum cost flow problem".
+
+     \tparam GR The type of the digraph the algorithm runs on.
+     \tparam LM The type of the lower bound map. The default
+     map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+     \tparam UM The type of the upper bound (capacity) map.
+     The default map type is \c LM.
+     \tparam 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
+template< typename GR,
+          typename LM,
+          typename UM,
+          typename SM,
+          typename TR >
+#else
+template< typename GR,
+          typename LM = typename GR::template ArcMap<int>,
+          typename UM = LM,
+          typename SM = typename GR::template NodeMap<typename UM::Value>,
+          typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
+#endif
+  class Circulation {
+  public:
+
+    /// \brief The \ref lemon::CirculationDefaultTraits "traits class"
+    /// of the algorithm.
+    typedef TR Traits;
+    ///The type of the digraph the algorithm runs on.
+    typedef typename Traits::Digraph Digraph;
+    ///The type of the flow and supply values.
+    typedef typename Traits::Value Value;
+
+    ///The type of the lower bound map.
+    typedef typename Traits::LowerMap LowerMap;
+    ///The type of the upper bound (capacity) map.
+    typedef typename Traits::UpperMap UpperMap;
+    ///The type of the supply map.
+    typedef typename Traits::SupplyMap SupplyMap;
+    ///The type of the flow map.
+    typedef typename Traits::FlowMap FlowMap;
+
+    ///The type of the elevator.
+    typedef typename Traits::Elevator Elevator;
+    ///The type of the tolerance.
+    typedef typename Traits::Tolerance Tolerance;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    const Digraph &_g;
+    int _node_num;
+
+    const LowerMap *_lo;
+    const UpperMap *_up;
+    const SupplyMap *_supply;
+
+    FlowMap *_flow;
+    bool _local_flow;
+
+    Elevator* _level;
+    bool _local_level;
+
+    typedef typename Digraph::template NodeMap<Value> ExcessMap;
+    ExcessMap* _excess;
+
+    Tolerance _tol;
+    int _el;
+
+  public:
+
+    typedef Circulation Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <typename T>
+    struct SetFlowMapTraits : public Traits {
+      typedef T FlowMap;
+      static FlowMap *createFlowMap(const Digraph&) {
+        LEMON_ASSERT(false, "FlowMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// FlowMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting FlowMap
+    /// type.
+    template <typename T>
+    struct SetFlowMap
+      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
+                           SetFlowMapTraits<T> > {
+      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
+                          SetFlowMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Digraph&, int) {
+        LEMON_ASSERT(false, "Elevator is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type. If this named parameter is used, then an external
+    /// elevator object must be passed to the algorithm using the
+    /// \ref elevator(Elevator&) "elevator()" function before calling
+    /// \ref run() or \ref init().
+    /// \sa SetStandardElevator
+    template <typename T>
+    struct SetElevator
+      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
+                           SetElevatorTraits<T> > {
+      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
+                          SetElevatorTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetStandardElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Digraph& digraph, int max_level) {
+        return new Elevator(digraph, max_level);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type with automatic allocation.
+    /// The Elevator should have standard constructor interface to be
+    /// able to automatically created by the algorithm (i.e. the
+    /// digraph and the maximum level should be passed to it).
+    /// However, an external elevator object could also be passed to the
+    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
+    /// before calling \ref run() or \ref init().
+    /// \sa SetElevator
+    template <typename T>
+    struct SetStandardElevator
+      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
+                       SetStandardElevatorTraits<T> > {
+      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
+                      SetStandardElevatorTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    Circulation() {}
+
+  public:
+
+    /// Constructor.
+
+    /// The constructor of the class.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    /// \param lower The lower bounds for the flow values on the arcs.
+    /// \param upper The upper bounds (capacities) for the flow values
+    /// on the arcs.
+    /// \param supply The signed supply values of the nodes.
+    Circulation(const Digraph &graph, const LowerMap &lower,
+                const UpperMap &upper, const SupplyMap &supply)
+      : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
+        _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
+        _excess(NULL) {}
+
+    /// Destructor.
+    ~Circulation() {
+      destroyStructures();
+    }
+
+
+  private:
+
+    bool checkBoundMaps() {
+      for (ArcIt e(_g);e!=INVALID;++e) {
+        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
+      }
+      return true;
+    }
+
+    void createStructures() {
+      _node_num = _el = countNodes(_g);
+
+      if (!_flow) {
+        _flow = Traits::createFlowMap(_g);
+        _local_flow = true;
+      }
+      if (!_level) {
+        _level = Traits::createElevator(_g, _node_num);
+        _local_level = true;
+      }
+      if (!_excess) {
+        _excess = new ExcessMap(_g);
+      }
+    }
+
+    void destroyStructures() {
+      if (_local_flow) {
+        delete _flow;
+      }
+      if (_local_level) {
+        delete _level;
+      }
+      if (_excess) {
+        delete _excess;
+      }
+    }
+
+  public:
+
+    /// Sets the lower bound map.
+
+    /// Sets the lower bound map.
+    /// \return <tt>(*this)</tt>
+    Circulation& lowerMap(const LowerMap& map) {
+      _lo = ↦
+      return *this;
+    }
+
+    /// Sets the upper bound (capacity) map.
+
+    /// Sets the upper bound (capacity) map.
+    /// \return <tt>(*this)</tt>
+    Circulation& upperMap(const UpperMap& map) {
+      _up = ↦
+      return *this;
+    }
+
+    /// Sets the supply map.
+
+    /// Sets the supply map.
+    /// \return <tt>(*this)</tt>
+    Circulation& supplyMap(const SupplyMap& map) {
+      _supply = ↦
+      return *this;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    Circulation& flowMap(FlowMap& map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = ↦
+      return *this;
+    }
+
+    /// \brief Sets the elevator used by algorithm.
+    ///
+    /// Sets the elevator used by algorithm.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated elevator,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    Circulation& elevator(Elevator& elevator) {
+      if (_local_level) {
+        delete _level;
+        _local_level = false;
+      }
+      _level = &elevator;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the elevator.
+    ///
+    /// Returns a const reference to the elevator.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const Elevator& elevator() const {
+      return *_level;
+    }
+
+    /// \brief Sets the tolerance used by the algorithm.
+    ///
+    /// Sets the tolerance object used by the algorithm.
+    /// \return <tt>(*this)</tt>
+    Circulation& tolerance(const Tolerance& tolerance) {
+      _tol = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// Returns a const reference to the tolerance object used by
+    /// the algorithm.
+    const Tolerance& tolerance() const {
+      return _tol;
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to call \ref run().\n
+    /// If you need better control on the initial solution or the execution,
+    /// you have to call one of the \ref init() functions first, then
+    /// the \ref start() function.
+
+    ///@{
+
+    /// Initializes the internal data structures.
+
+    /// Initializes the internal data structures and sets all flow values
+    /// to the lower bound.
+    void init()
+    {
+      LEMON_DEBUG(checkBoundMaps(),
+        "Upper bounds must be greater or equal to the lower bounds");
+
+      createStructures();
+
+      for(NodeIt n(_g);n!=INVALID;++n) {
+        (*_excess)[n] = (*_supply)[n];
+      }
+
+      for (ArcIt e(_g);e!=INVALID;++e) {
+        _flow->set(e, (*_lo)[e]);
+        (*_excess)[_g.target(e)] += (*_flow)[e];
+        (*_excess)[_g.source(e)] -= (*_flow)[e];
+      }
+
+      // global relabeling tested, but in general case it provides
+      // worse performance for random digraphs
+      _level->initStart();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        _level->initAddItem(n);
+      _level->initFinish();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        if(_tol.positive((*_excess)[n]))
+          _level->activate(n);
+    }
+
+    /// Initializes the internal data structures using a greedy approach.
+
+    /// Initializes the internal data structures using a greedy approach
+    /// to construct the initial solution.
+    void greedyInit()
+    {
+      LEMON_DEBUG(checkBoundMaps(),
+        "Upper bounds must be greater or equal to the lower bounds");
+
+      createStructures();
+
+      for(NodeIt n(_g);n!=INVALID;++n) {
+        (*_excess)[n] = (*_supply)[n];
+      }
+
+      for (ArcIt e(_g);e!=INVALID;++e) {
+        if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
+          _flow->set(e, (*_up)[e]);
+          (*_excess)[_g.target(e)] += (*_up)[e];
+          (*_excess)[_g.source(e)] -= (*_up)[e];
+        } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
+          _flow->set(e, (*_lo)[e]);
+          (*_excess)[_g.target(e)] += (*_lo)[e];
+          (*_excess)[_g.source(e)] -= (*_lo)[e];
+        } else {
+          Value fc = -(*_excess)[_g.target(e)];
+          _flow->set(e, fc);
+          (*_excess)[_g.target(e)] = 0;
+          (*_excess)[_g.source(e)] -= fc;
+        }
+      }
+
+      _level->initStart();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        _level->initAddItem(n);
+      _level->initFinish();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        if(_tol.positive((*_excess)[n]))
+          _level->activate(n);
+    }
+
+    ///Executes the algorithm
+
+    ///This function executes the algorithm.
+    ///
+    ///\return \c true if a feasible circulation is found.
+    ///
+    ///\sa barrier()
+    ///\sa barrierMap()
+    bool start()
+    {
+
+      Node act;
+      while((act=_level->highestActive())!=INVALID) {
+        int actlevel=(*_level)[act];
+        int mlevel=_node_num;
+        Value exc=(*_excess)[act];
+
+        for(OutArcIt e(_g,act);e!=INVALID; ++e) {
+          Node v = _g.target(e);
+          Value fc=(*_up)[e]-(*_flow)[e];
+          if(!_tol.positive(fc)) continue;
+          if((*_level)[v]<actlevel) {
+            if(!_tol.less(fc, exc)) {
+              _flow->set(e, (*_flow)[e] + exc);
+              (*_excess)[v] += exc;
+              if(!_level->active(v) && _tol.positive((*_excess)[v]))
+                _level->activate(v);
+              (*_excess)[act] = 0;
+              _level->deactivate(act);
+              goto next_l;
+            }
+            else {
+              _flow->set(e, (*_up)[e]);
+              (*_excess)[v] += fc;
+              if(!_level->active(v) && _tol.positive((*_excess)[v]))
+                _level->activate(v);
+              exc-=fc;
+            }
+          }
+          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
+        }
+        for(InArcIt e(_g,act);e!=INVALID; ++e) {
+          Node v = _g.source(e);
+          Value fc=(*_flow)[e]-(*_lo)[e];
+          if(!_tol.positive(fc)) continue;
+          if((*_level)[v]<actlevel) {
+            if(!_tol.less(fc, exc)) {
+              _flow->set(e, (*_flow)[e] - exc);
+              (*_excess)[v] += exc;
+              if(!_level->active(v) && _tol.positive((*_excess)[v]))
+                _level->activate(v);
+              (*_excess)[act] = 0;
+              _level->deactivate(act);
+              goto next_l;
+            }
+            else {
+              _flow->set(e, (*_lo)[e]);
+              (*_excess)[v] += fc;
+              if(!_level->active(v) && _tol.positive((*_excess)[v]))
+                _level->activate(v);
+              exc-=fc;
+            }
+          }
+          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
+        }
+
+        (*_excess)[act] = exc;
+        if(!_tol.positive(exc)) _level->deactivate(act);
+        else if(mlevel==_node_num) {
+          _level->liftHighestActiveToTop();
+          _el = _node_num;
+          return false;
+        }
+        else {
+          _level->liftHighestActive(mlevel+1);
+          if(_level->onLevel(actlevel)==0) {
+            _el = actlevel;
+            return false;
+          }
+        }
+      next_l:
+        ;
+      }
+      return true;
+    }
+
+    /// Runs the algorithm.
+
+    /// This function runs the algorithm.
+    ///
+    /// \return \c true if a feasible circulation is found.
+    ///
+    /// \note Apart from the return value, c.run() is just a shortcut of
+    /// the following code.
+    /// \code
+    ///   c.greedyInit();
+    ///   c.start();
+    /// \endcode
+    bool run() {
+      greedyInit();
+      return start();
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the circulation algorithm can be obtained using
+    /// these functions.\n
+    /// Either \ref run() or \ref start() should be called before
+    /// using them.
+
+    ///@{
+
+    /// \brief Returns the flow value on the given arc.
+    ///
+    /// Returns the flow value on the given arc.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flow(const Arc& arc) const {
+      return (*_flow)[arc];
+    }
+
+    /// \brief Returns a const reference to the flow map.
+    ///
+    /// Returns a const reference to the arc map storing the found flow.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const FlowMap& flowMap() const {
+      return *_flow;
+    }
+
+    /**
+       \brief Returns \c true if the given node is in a barrier.
+
+       Barrier is a set \e B of nodes for which
+
+       \f[ \sum_{uv\in A: u\in B} upper(uv) -
+           \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
+
+       holds. The existence of a set with this property prooves that a
+       feasible circualtion cannot exist.
+
+       This function returns \c true if the given node is in the found
+       barrier. If a feasible circulation is found, the function
+       gives back \c false for every node.
+
+       \pre Either \ref run() or \ref init() must be called before
+       using this function.
+
+       \sa barrierMap()
+       \sa checkBarrier()
+    */
+    bool barrier(const Node& node) const
+    {
+      return (*_level)[node] >= _el;
+    }
+
+    /// \brief Gives back a barrier.
+    ///
+    /// This function sets \c bar to the characteristic vector of the
+    /// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
+    /// node map with \c bool (or convertible) value type.
+    ///
+    /// If a feasible circulation is found, the function gives back an
+    /// empty set, so \c bar[v] will be \c false for all nodes \c v.
+    ///
+    /// \note This function calls \ref barrier() for each node,
+    /// so it runs in O(n) time.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    ///
+    /// \sa barrier()
+    /// \sa checkBarrier()
+    template<class BarrierMap>
+    void barrierMap(BarrierMap &bar) const
+    {
+      for(NodeIt n(_g);n!=INVALID;++n)
+        bar.set(n, (*_level)[n] >= _el);
+    }
+
+    /// @}
+
+    /// \name Checker Functions
+    /// The feasibility of the results can be checked using
+    /// these functions.\n
+    /// Either \ref run() or \ref start() should be called before
+    /// using them.
+
+    ///@{
+
+    ///Check if the found flow is a feasible circulation
+
+    ///Check if the found flow is a feasible circulation,
+    ///
+    bool checkFlow() const {
+      for(ArcIt e(_g);e!=INVALID;++e)
+        if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
+      for(NodeIt n(_g);n!=INVALID;++n)
+        {
+          Value dif=-(*_supply)[n];
+          for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
+          for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
+          if(_tol.negative(dif)) return false;
+        }
+      return true;
+    }
+
+    ///Check whether or not the last execution provides a barrier
+
+    ///Check whether or not the last execution provides a barrier.
+    ///\sa barrier()
+    ///\sa barrierMap()
+    bool checkBarrier() const
+    {
+      Value delta=0;
+      Value inf_cap = std::numeric_limits<Value>::has_infinity ?
+        std::numeric_limits<Value>::infinity() :
+        std::numeric_limits<Value>::max();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        if(barrier(n))
+          delta-=(*_supply)[n];
+      for(ArcIt e(_g);e!=INVALID;++e)
+        {
+          Node s=_g.source(e);
+          Node t=_g.target(e);
+          if(barrier(s)&&!barrier(t)) {
+            if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
+            delta+=(*_up)[e];
+          }
+          else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
+        }
+      return _tol.negative(delta);
+    }
+
+    /// @}
+
+  };
+
+}
+
+#endif
diff --git a/lemon/clp.cc b/lemon/clp.cc
new file mode 100644
index 0000000..7c0ea74
--- /dev/null
+++ b/lemon/clp.cc
@@ -0,0 +1,464 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/clp.h>
+#include <coin/ClpSimplex.hpp>
+
+namespace lemon {
+
+  ClpLp::ClpLp() {
+    _prob = new ClpSimplex();
+    _init_temporals();
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  ClpLp::ClpLp(const ClpLp& other) {
+    _prob = new ClpSimplex(*other._prob);
+    rows = other.rows;
+    cols = other.cols;
+    _init_temporals();
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  ClpLp::~ClpLp() {
+    delete _prob;
+    _clear_temporals();
+  }
+
+  void ClpLp::_init_temporals() {
+    _primal_ray = 0;
+    _dual_ray = 0;
+  }
+
+  void ClpLp::_clear_temporals() {
+    if (_primal_ray) {
+      delete[] _primal_ray;
+      _primal_ray = 0;
+    }
+    if (_dual_ray) {
+      delete[] _dual_ray;
+      _dual_ray = 0;
+    }
+  }
+
+  ClpLp* ClpLp::newSolver() const {
+    ClpLp* newlp = new ClpLp;
+    return newlp;
+  }
+
+  ClpLp* ClpLp::cloneSolver() const {
+    ClpLp* copylp = new ClpLp(*this);
+    return copylp;
+  }
+
+  const char* ClpLp::_solverName() const { return "ClpLp"; }
+
+  int ClpLp::_addCol() {
+    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
+    return _prob->numberColumns() - 1;
+  }
+
+  int ClpLp::_addRow() {
+    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
+    return _prob->numberRows() - 1;
+  }
+
+  int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
+    return _prob->numberRows() - 1;
+  }
+
+
+  void ClpLp::_eraseCol(int c) {
+    _col_names_ref.erase(_prob->getColumnName(c));
+    _prob->deleteColumns(1, &c);
+  }
+
+  void ClpLp::_eraseRow(int r) {
+    _row_names_ref.erase(_prob->getRowName(r));
+    _prob->deleteRows(1, &r);
+  }
+
+  void ClpLp::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+
+  void ClpLp::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void ClpLp::_getColName(int c, std::string& name) const {
+    name = _prob->getColumnName(c);
+  }
+
+  void ClpLp::_setColName(int c, const std::string& name) {
+    _prob->setColumnName(c, const_cast<std::string&>(name));
+    _col_names_ref[name] = c;
+  }
+
+  int ClpLp::_colByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
+    return it != _col_names_ref.end() ? it->second : -1;
+  }
+
+  void ClpLp::_getRowName(int r, std::string& name) const {
+    name = _prob->getRowName(r);
+  }
+
+  void ClpLp::_setRowName(int r, const std::string& name) {
+    _prob->setRowName(r, const_cast<std::string&>(name));
+    _row_names_ref[name] = r;
+  }
+
+  int ClpLp::_rowByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
+    return it != _row_names_ref.end() ? it->second : -1;
+  }
+
+
+  void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
+    std::map<int, Value> coeffs;
+
+    int n = _prob->clpMatrix()->getNumCols();
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (int i = 0; i < n; ++i) {
+      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
+      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
+
+      const int* it = std::lower_bound(indices + begin, indices + end, ix);
+      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
+        coeffs[i] = 0.0;
+      }
+    }
+
+    for (ExprIterator it = b; it != e; ++it) {
+      coeffs[it->first] = it->second;
+    }
+
+    for (std::map<int, Value>::iterator it = coeffs.begin();
+         it != coeffs.end(); ++it) {
+      _prob->modifyCoefficient(ix, it->first, it->second);
+    }
+  }
+
+  void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
+    int n = _prob->clpMatrix()->getNumCols();
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (int i = 0; i < n; ++i) {
+      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
+      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
+
+      const int* it = std::lower_bound(indices + begin, indices + end, ix);
+      if (it != indices + end && *it == ix) {
+        *b = std::make_pair(i, elements[it - indices]);
+      }
+    }
+  }
+
+  void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
+    std::map<int, Value> coeffs;
+
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (CoinBigIndex i = begin; i != end; ++i) {
+      if (elements[i] != 0.0) {
+        coeffs[indices[i]] = 0.0;
+      }
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      coeffs[it->first] = it->second;
+    }
+    for (std::map<int, Value>::iterator it = coeffs.begin();
+         it != coeffs.end(); ++it) {
+      _prob->modifyCoefficient(it->first, ix, it->second);
+    }
+  }
+
+  void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (CoinBigIndex i = begin; i != end; ++i) {
+      *b = std::make_pair(indices[i], elements[i]);
+      ++b;
+    }
+  }
+
+  void ClpLp::_setCoeff(int ix, int jx, Value value) {
+    _prob->modifyCoefficient(ix, jx, value);
+  }
+
+  ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    const int* it = std::lower_bound(indices + begin, indices + end, jx);
+    if (it != indices + end && *it == jx) {
+      return elements[it - indices];
+    } else {
+      return 0.0;
+    }
+  }
+
+  void ClpLp::_setColLowerBound(int i, Value lo) {
+    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  ClpLp::Value ClpLp::_getColLowerBound(int i) const {
+    double val = _prob->getColLower()[i];
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void ClpLp::_setColUpperBound(int i, Value up) {
+    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  ClpLp::Value ClpLp::_getColUpperBound(int i) const {
+    double val = _prob->getColUpper()[i];
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void ClpLp::_setRowLowerBound(int i, Value lo) {
+    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
+    double val = _prob->getRowLower()[i];
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void ClpLp::_setRowUpperBound(int i, Value up) {
+    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
+    double val = _prob->getRowUpper()[i];
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    int num = _prob->clpMatrix()->getNumCols();
+    for (int i = 0; i < num; ++i) {
+      _prob->setObjectiveCoefficient(i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setObjectiveCoefficient(it->first, it->second);
+    }
+  }
+
+  void ClpLp::_getObjCoeffs(InsertIterator b) const {
+    int num = _prob->clpMatrix()->getNumCols();
+    for (int i = 0; i < num; ++i) {
+      Value coef = _prob->getObjCoefficients()[i];
+      if (coef != 0.0) {
+        *b = std::make_pair(i, coef);
+        ++b;
+      }
+    }
+  }
+
+  void ClpLp::_setObjCoeff(int i, Value obj_coef) {
+    _prob->setObjectiveCoefficient(i, obj_coef);
+  }
+
+  ClpLp::Value ClpLp::_getObjCoeff(int i) const {
+    return _prob->getObjCoefficients()[i];
+  }
+
+  ClpLp::SolveExitStatus ClpLp::_solve() {
+    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  ClpLp::SolveExitStatus ClpLp::solvePrimal() {
+    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  ClpLp::SolveExitStatus ClpLp::solveDual() {
+    return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  ClpLp::SolveExitStatus ClpLp::solveBarrier() {
+    return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  ClpLp::Value ClpLp::_getPrimal(int i) const {
+    return _prob->primalColumnSolution()[i];
+  }
+  ClpLp::Value ClpLp::_getPrimalValue() const {
+    return _prob->objectiveValue();
+  }
+
+  ClpLp::Value ClpLp::_getDual(int i) const {
+    return _prob->dualRowSolution()[i];
+  }
+
+  ClpLp::Value ClpLp::_getPrimalRay(int i) const {
+    if (!_primal_ray) {
+      _primal_ray = _prob->unboundedRay();
+      LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
+    }
+    return _primal_ray[i];
+  }
+
+  ClpLp::Value ClpLp::_getDualRay(int i) const {
+    if (!_dual_ray) {
+      _dual_ray = _prob->infeasibilityRay();
+      LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
+    }
+    return _dual_ray[i];
+  }
+
+  ClpLp::VarStatus ClpLp::_getColStatus(int i) const {
+    switch (_prob->getColumnStatus(i)) {
+    case ClpSimplex::basic:
+      return BASIC;
+    case ClpSimplex::isFree:
+      return FREE;
+    case ClpSimplex::atUpperBound:
+      return UPPER;
+    case ClpSimplex::atLowerBound:
+      return LOWER;
+    case ClpSimplex::isFixed:
+      return FIXED;
+    case ClpSimplex::superBasic:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return VarStatus();
+    }
+  }
+
+  ClpLp::VarStatus ClpLp::_getRowStatus(int i) const {
+    switch (_prob->getColumnStatus(i)) {
+    case ClpSimplex::basic:
+      return BASIC;
+    case ClpSimplex::isFree:
+      return FREE;
+    case ClpSimplex::atUpperBound:
+      return UPPER;
+    case ClpSimplex::atLowerBound:
+      return LOWER;
+    case ClpSimplex::isFixed:
+      return FIXED;
+    case ClpSimplex::superBasic:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return VarStatus();
+    }
+  }
+
+
+  ClpLp::ProblemType ClpLp::_getPrimalType() const {
+    if (_prob->isProvenOptimal()) {
+      return OPTIMAL;
+    } else if (_prob->isProvenPrimalInfeasible()) {
+      return INFEASIBLE;
+    } else if (_prob->isProvenDualInfeasible()) {
+      return UNBOUNDED;
+    } else {
+      return UNDEFINED;
+    }
+  }
+
+  ClpLp::ProblemType ClpLp::_getDualType() const {
+    if (_prob->isProvenOptimal()) {
+      return OPTIMAL;
+    } else if (_prob->isProvenDualInfeasible()) {
+      return INFEASIBLE;
+    } else if (_prob->isProvenPrimalInfeasible()) {
+      return INFEASIBLE;
+    } else {
+      return UNDEFINED;
+    }
+  }
+
+  void ClpLp::_setSense(ClpLp::Sense sense) {
+    switch (sense) {
+    case MIN:
+      _prob->setOptimizationDirection(1);
+      break;
+    case MAX:
+      _prob->setOptimizationDirection(-1);
+      break;
+    }
+  }
+
+  ClpLp::Sense ClpLp::_getSense() const {
+    double dir = _prob->optimizationDirection();
+    if (dir > 0.0) {
+      return MIN;
+    } else {
+      return MAX;
+    }
+  }
+
+  void ClpLp::_clear() {
+    delete _prob;
+    _prob = new ClpSimplex();
+    _col_names_ref.clear();
+    _clear_temporals();
+  }
+
+  void ClpLp::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _prob->setLogLevel(0);
+      break;
+    case MESSAGE_ERROR:
+      _prob->setLogLevel(1);
+      break;
+    case MESSAGE_WARNING:
+      _prob->setLogLevel(2);
+      break;
+    case MESSAGE_NORMAL:
+      _prob->setLogLevel(3);
+      break;
+    case MESSAGE_VERBOSE:
+      _prob->setLogLevel(4);
+      break;
+    }
+  }
+
+} //END OF NAMESPACE LEMON
diff --git a/lemon/clp.h b/lemon/clp.h
new file mode 100644
index 0000000..fd331ac
--- /dev/null
+++ b/lemon/clp.h
@@ -0,0 +1,164 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_CLP_H
+#define LEMON_CLP_H
+
+///\file
+///\brief Header of the LEMON-CLP lp solver interface.
+
+#include <vector>
+#include <string>
+
+#include <lemon/lp_base.h>
+
+class ClpSimplex;
+
+namespace lemon {
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Interface for the CLP solver
+  ///
+  /// This class implements an interface for the Clp LP solver.  The
+  /// Clp library is an object oriented lp solver library developed at
+  /// the IBM. The CLP is part of the COIN-OR package and it can be
+  /// used with Common Public License.
+  class ClpLp : public LpSolver {
+  protected:
+
+    ClpSimplex* _prob;
+
+    std::map<std::string, int> _col_names_ref;
+    std::map<std::string, int> _row_names_ref;
+
+  public:
+
+    /// \e
+    ClpLp();
+    /// \e
+    ClpLp(const ClpLp&);
+    /// \e
+    ~ClpLp();
+
+    /// \e
+    virtual ClpLp* newSolver() const;
+    /// \e
+    virtual ClpLp* cloneSolver() const;
+
+  protected:
+
+    mutable double* _primal_ray;
+    mutable double* _dual_ray;
+
+    void _init_temporals();
+    void _clear_temporals();
+
+  protected:
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
+    virtual void _getObjCoeffs(InsertIterator) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual SolveExitStatus _solve();
+
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+    virtual void _clear();
+
+    virtual void _messageLevel(MessageLevel);
+
+  public:
+
+    ///Solves LP with primal simplex method.
+    SolveExitStatus solvePrimal();
+
+    ///Solves LP with dual simplex method.
+    SolveExitStatus solveDual();
+
+    ///Solves LP with barrier method.
+    SolveExitStatus solveBarrier();
+
+    ///Returns the constraint identifier understood by CLP.
+    int clpRow(Row r) const { return rows(id(r)); }
+
+    ///Returns the variable identifier understood by CLP.
+    int clpCol(Col c) const { return cols(id(c)); }
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_CLP_H
+
diff --git a/lemon/color.cc b/lemon/color.cc
new file mode 100644
index 0000000..a49167b
--- /dev/null
+++ b/lemon/color.cc
@@ -0,0 +1,44 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Color constants
+
+#include<lemon/color.h>
+
+namespace lemon {
+
+  const Color WHITE(1,1,1);
+
+  const Color BLACK(0,0,0);
+  const Color RED(1,0,0);
+  const Color GREEN(0,1,0);
+  const Color BLUE(0,0,1);
+  const Color YELLOW(1,1,0);
+  const Color MAGENTA(1,0,1);
+  const Color CYAN(0,1,1);
+
+  const Color GREY(0,0,0);
+  const Color DARK_RED(.5,0,0);
+  const Color DARK_GREEN(0,.5,0);
+  const Color DARK_BLUE(0,0,.5);
+  const Color DARK_YELLOW(.5,.5,0);
+  const Color DARK_MAGENTA(.5,0,.5);
+  const Color DARK_CYAN(0,.5,.5);
+
+} //namespace lemon
diff --git a/lemon/color.h b/lemon/color.h
new file mode 100644
index 0000000..0235791
--- /dev/null
+++ b/lemon/color.h
@@ -0,0 +1,204 @@
+/* -*- 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_COLOR_H
+#define LEMON_COLOR_H
+
+#include<vector>
+#include<lemon/math.h>
+#include<lemon/maps.h>
+
+
+///\ingroup misc
+///\file
+///\brief Tools to manage RGB colors.
+
+namespace lemon {
+
+
+  /// \addtogroup misc
+  /// @{
+
+  ///Data structure representing RGB colors.
+
+  ///Data structure representing RGB colors.
+  class Color
+  {
+    double _r,_g,_b;
+  public:
+    ///Default constructor
+    Color() {}
+    ///Constructor
+    Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
+    ///Set the red component
+    double & red() {return _r;}
+    ///Return the red component
+    const double & red() const {return _r;}
+    ///Set the green component
+    double & green() {return _g;}
+    ///Return the green component
+    const double & green() const {return _g;}
+    ///Set the blue component
+    double & blue() {return _b;}
+    ///Return the blue component
+    const double & blue() const {return _b;}
+    ///Set the color components
+    void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
+  };
+
+  /// White color constant
+  extern const Color WHITE;
+  /// Black color constant
+  extern const Color BLACK;
+  /// Red color constant
+  extern const Color RED;
+  /// Green color constant
+  extern const Color GREEN;
+  /// Blue color constant
+  extern const Color BLUE;
+  /// Yellow color constant
+  extern const Color YELLOW;
+  /// Magenta color constant
+  extern const Color MAGENTA;
+  /// Cyan color constant
+  extern const Color CYAN;
+  /// Grey color constant
+  extern const Color GREY;
+  /// Dark red color constant
+  extern const Color DARK_RED;
+  /// Dark green color constant
+  extern const Color DARK_GREEN;
+  /// Drak blue color constant
+  extern const Color DARK_BLUE;
+  /// Dark yellow color constant
+  extern const Color DARK_YELLOW;
+  /// Dark magenta color constant
+  extern const Color DARK_MAGENTA;
+  /// Dark cyan color constant
+  extern const Color DARK_CYAN;
+
+  ///Map <tt>int</tt>s to different <tt>Color</tt>s
+
+  ///This map assigns one of the predefined \ref Color "Color"s to
+  ///each <tt>int</tt>. It is possible to change the colors as well as
+  ///their number. The integer range is cyclically mapped to the
+  ///provided set of colors.
+  ///
+  ///This is a true \ref concepts::ReferenceMap "reference map", so
+  ///you can also change the actual colors.
+
+  class Palette : public MapBase<int,Color>
+  {
+    std::vector<Color> colors;
+  public:
+    ///Constructor
+
+    ///Constructor.
+    ///\param have_white Indicates whether white is among the
+    ///provided initial colors (\c true) or not (\c false). If it is true,
+    ///white will be assigned to \c 0.
+    ///\param num The number of the allocated colors. If it is \c -1,
+    ///the default color configuration is set up (26 color plus optionaly the
+    ///white).  If \c num is less then 26/27 then the default color
+    ///list is cut. Otherwise the color list is filled repeatedly with
+    ///the default color list.  (The colors can be changed later on.)
+    Palette(bool have_white=false,int num=-1)
+    {
+      if (num==0) return;
+      do {
+        if(have_white) colors.push_back(Color(1,1,1));
+
+        colors.push_back(Color(0,0,0));
+        colors.push_back(Color(1,0,0));
+        colors.push_back(Color(0,1,0));
+        colors.push_back(Color(0,0,1));
+        colors.push_back(Color(1,1,0));
+        colors.push_back(Color(1,0,1));
+        colors.push_back(Color(0,1,1));
+
+        colors.push_back(Color(.5,0,0));
+        colors.push_back(Color(0,.5,0));
+        colors.push_back(Color(0,0,.5));
+        colors.push_back(Color(.5,.5,0));
+        colors.push_back(Color(.5,0,.5));
+        colors.push_back(Color(0,.5,.5));
+
+        colors.push_back(Color(.5,.5,.5));
+        colors.push_back(Color(1,.5,.5));
+        colors.push_back(Color(.5,1,.5));
+        colors.push_back(Color(.5,.5,1));
+        colors.push_back(Color(1,1,.5));
+        colors.push_back(Color(1,.5,1));
+        colors.push_back(Color(.5,1,1));
+
+        colors.push_back(Color(1,.5,0));
+        colors.push_back(Color(.5,1,0));
+        colors.push_back(Color(1,0,.5));
+        colors.push_back(Color(0,1,.5));
+        colors.push_back(Color(0,.5,1));
+        colors.push_back(Color(.5,0,1));
+      } while(int(colors.size())<num);
+      if(num>=0) colors.resize(num);
+    }
+    ///\e
+    Color &operator[](int i)
+    {
+      return colors[i%colors.size()];
+    }
+    ///\e
+    const Color &operator[](int i) const
+    {
+      return colors[i%colors.size()];
+    }
+    ///\e
+    void set(int i,const Color &c)
+    {
+      colors[i%colors.size()]=c;
+    }
+    ///Adds a new color to the end of the color list.
+    void add(const Color &c)
+    {
+      colors.push_back(c);
+    }
+
+    ///Sets the number of the existing colors.
+    void resize(int s) { colors.resize(s);}
+    ///Returns the number of the existing colors.
+    int size() const { return int(colors.size());}
+  };
+
+  ///Returns a visibly distinct \ref Color
+
+  ///Returns a \ref Color which is as different from the given parameter
+  ///as it is possible.
+  inline Color distantColor(const Color &c)
+  {
+    return Color(c.red()<.5?1:0,c.green()<.5?1:0,c.blue()<.5?1:0);
+  }
+  ///Returns black for light colors and white for the dark ones.
+
+  ///Returns black for light colors and white for the dark ones.
+  inline Color distantBW(const Color &c){
+    return (.2125*c.red()+.7154*c.green()+.0721*c.blue())<.5 ? WHITE : BLACK;
+  }
+
+  /// @}
+
+} //END OF NAMESPACE LEMON
+
+#endif // LEMON_COLOR_H
diff --git a/lemon/concept_check.h b/lemon/concept_check.h
new file mode 100644
index 0000000..38355b0
--- /dev/null
+++ b/lemon/concept_check.h
@@ -0,0 +1,77 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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.
+ *
+ */
+
+// The contents of this file was inspired by the concept checking
+// utility of the BOOST library (http://www.boost.org).
+
+///\file
+///\brief Basic utilities for concept checking.
+///
+
+#ifndef LEMON_CONCEPT_CHECK_H
+#define LEMON_CONCEPT_CHECK_H
+
+namespace lemon {
+
+  /*
+    "inline" is used for ignore_unused_variable_warning()
+    and function_requires() to make sure there is no
+    overtarget with g++.
+  */
+
+  template <class T> inline void ignore_unused_variable_warning(const T&) { }
+  template <class T1, class T2>
+  inline void ignore_unused_variable_warning(const T1&, const T2&) { }
+  template <class T1, class T2, class T3>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&) { }
+  template <class T1, class T2, class T3, class T4>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&) { }
+  template <class T1, class T2, class T3, class T4, class T5>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&,
+                                             const T5&) { }
+  template <class T1, class T2, class T3, class T4, class T5, class T6>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&,
+                                             const T5&, const T6&) { }
+
+  ///\e
+  template <class Concept>
+  inline void function_requires()
+  {
+#if !defined(NDEBUG)
+    void (Concept::*x)() = & Concept::constraints;
+    ::lemon::ignore_unused_variable_warning(x);
+#endif
+  }
+
+  ///\e
+  template <typename Concept, typename Type>
+  inline void checkConcept() {
+#if !defined(NDEBUG)
+    typedef typename Concept::template Constraints<Type> ConceptCheck;
+    void (ConceptCheck::*x)() = & ConceptCheck::constraints;
+    ::lemon::ignore_unused_variable_warning(x);
+#endif
+  }
+
+} // namespace lemon
+
+#endif // LEMON_CONCEPT_CHECK_H
diff --git a/lemon/concepts/bpgraph.h b/lemon/concepts/bpgraph.h
new file mode 100644
index 0000000..2ebdeaf
--- /dev/null
+++ b/lemon/concepts/bpgraph.h
@@ -0,0 +1,1029 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup graph_concepts
+///\file
+///\brief The concept of undirected graphs.
+
+#ifndef LEMON_CONCEPTS_BPGRAPH_H
+#define LEMON_CONCEPTS_BPGRAPH_H
+
+#include <lemon/concepts/graph_components.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concept_check.h>
+#include <lemon/core.h>
+
+namespace lemon {
+  namespace concepts {
+
+    /// \ingroup graph_concepts
+    ///
+    /// \brief Class describing the concept of undirected bipartite graphs.
+    ///
+    /// This class describes the common interface of all undirected
+    /// bipartite graphs.
+    ///
+    /// Like all concept classes, it only provides an interface
+    /// without any sensible implementation. So any general algorithm for
+    /// undirected bipartite graphs should compile with this class,
+    /// but it will not run properly, of course.
+    /// An actual graph implementation like \ref ListBpGraph or
+    /// \ref SmartBpGraph may have additional functionality.
+    ///
+    /// The bipartite graphs also fulfill the concept of \ref Graph
+    /// "undirected graphs". Bipartite graphs provide a bipartition of
+    /// the node set, namely a red and blue set of the nodes. The
+    /// nodes can be iterated with the RedNodeIt and BlueNodeIt in the
+    /// two node sets. With RedNodeMap and BlueNodeMap values can be
+    /// assigned to the nodes in the two sets.
+    ///
+    /// The edges of the graph cannot connect two nodes of the same
+    /// set. The edges inherent orientation is from the red nodes to
+    /// the blue nodes.
+    ///
+    /// \sa Graph
+    class BpGraph {
+    private:
+      /// BpGraphs are \e not copy constructible. Use bpGraphCopy instead.
+      BpGraph(const BpGraph&) {}
+      /// \brief Assignment of a graph to another one is \e not allowed.
+      /// Use bpGraphCopy instead.
+      void operator=(const BpGraph&) {}
+
+    public:
+      /// Default constructor.
+      BpGraph() {}
+
+      /// \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;
+
+      /// 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
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Node() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Node(const Node&) { }
+
+        /// %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 \c INVALID.
+        bool operator==(Node) const { return true; }
+
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Node) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// 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.
+        bool operator<(Node) const { return false; }
+
+      };
+
+      /// Class to represent red nodes.
+
+      /// This class represents the red nodes of the graph. It does
+      /// not supposed to be used directly, because the nodes can be
+      /// represented as Node instances. This class can be used as
+      /// template parameter for special map classes.
+      class RedNode : public Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        RedNode() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        RedNode(const RedNode&) : Node() { }
+
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        RedNode(Invalid) { }
+
+      };
+
+      /// Class to represent blue nodes.
+
+      /// This class represents the blue nodes of the graph. It does
+      /// not supposed to be used directly, because the nodes can be
+      /// represented as Node instances. This class can be used as
+      /// template parameter for special map classes.
+      class BlueNode : public Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        BlueNode() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        BlueNode(const BlueNode&) : Node() { }
+
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        BlueNode(Invalid) { }
+
+      };
+
+      /// Iterator class for the red nodes.
+
+      /// This iterator goes through each red node of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of red nodes in a graph \c g of type \c %BpGraph like this:
+      ///\code
+      /// int count=0;
+      /// for (BpGraph::RedNodeIt n(g); n!=INVALID; ++n) ++count;
+      ///\endcode
+      class RedNodeIt : public RedNode {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        RedNodeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        RedNodeIt(const RedNodeIt& n) : RedNode(n) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        RedNodeIt(Invalid) { }
+        /// Sets the iterator to the first red node.
+
+        /// Sets the iterator to the first red node of the given
+        /// digraph.
+        explicit RedNodeIt(const BpGraph&) { }
+        /// Sets the iterator to the given red node.
+
+        /// Sets the iterator to the given red node of the given
+        /// digraph.
+        RedNodeIt(const BpGraph&, const RedNode&) { }
+        /// Next node.
+
+        /// Assign the iterator to the next red node.
+        ///
+        RedNodeIt& operator++() { return *this; }
+      };
+
+      /// Iterator class for the blue nodes.
+
+      /// This iterator goes through each blue node of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of blue nodes in a graph \c g of type \c %BpGraph like this:
+      ///\code
+      /// int count=0;
+      /// for (BpGraph::BlueNodeIt n(g); n!=INVALID; ++n) ++count;
+      ///\endcode
+      class BlueNodeIt : public BlueNode {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        BlueNodeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        BlueNodeIt(const BlueNodeIt& n) : BlueNode(n) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        BlueNodeIt(Invalid) { }
+        /// Sets the iterator to the first blue node.
+
+        /// Sets the iterator to the first blue node of the given
+        /// digraph.
+        explicit BlueNodeIt(const BpGraph&) { }
+        /// Sets the iterator to the given blue node.
+
+        /// Sets the iterator to the given blue node of the given
+        /// digraph.
+        BlueNodeIt(const BpGraph&, const BlueNode&) { }
+        /// Next node.
+
+        /// Assign the iterator to the next blue node.
+        ///
+        BlueNodeIt& operator++() { return *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 %BpGraph like this:
+      ///\code
+      /// int count=0;
+      /// for (BpGraph::NodeIt n(g); n!=INVALID; ++n) ++count;
+      ///\endcode
+      class NodeIt : public Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        NodeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        NodeIt(const NodeIt& n) : Node(n) { }
+        /// %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 the given digraph.
+        ///
+        explicit NodeIt(const BpGraph&) { }
+        /// Sets the iterator to the given node.
+
+        /// Sets the iterator to the given node of the given digraph.
+        ///
+        NodeIt(const BpGraph&, const Node&) { }
+        /// Next node.
+
+        /// Assign the iterator to the next node.
+        ///
+        NodeIt& operator++() { return *this; }
+      };
+
+
+      /// 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
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Edge() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Edge(const Edge&) { }
+        /// %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 \c INVALID.
+        bool operator==(Edge) const { return true; }
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Edge) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// 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; }
+      };
+
+      /// 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 %BpGraph as follows:
+      ///\code
+      /// int count=0;
+      /// for(BpGraph::EdgeIt e(g); e!=INVALID; ++e) ++count;
+      ///\endcode
+      class EdgeIt : public Edge {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        EdgeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        EdgeIt(const EdgeIt& e) : Edge(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        EdgeIt(Invalid) { }
+        /// Sets the iterator to the first edge.
+
+        /// Sets the iterator to the first edge of the given graph.
+        ///
+        explicit EdgeIt(const BpGraph&) { }
+        /// Sets the iterator to the given edge.
+
+        /// Sets the iterator to the given edge of the given graph.
+        ///
+        EdgeIt(const BpGraph&, const Edge&) { }
+        /// Next edge
+
+        /// Assign the iterator to the next edge.
+        ///
+        EdgeIt& operator++() { return *this; }
+      };
+
+      /// 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 %BpGraph as follows.
+      ///
+      ///\code
+      /// int count=0;
+      /// for(BpGraph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
+      ///\endcode
+      ///
+      /// \warning Loop edges will be iterated twice.
+      class IncEdgeIt : public Edge {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        IncEdgeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        IncEdgeIt(Invalid) { }
+        /// Sets the iterator to the first incident edge.
+
+        /// Sets the iterator to the first incident edge of the given node.
+        ///
+        IncEdgeIt(const BpGraph&, const Node&) { }
+        /// Sets the iterator to the given edge.
+
+        /// Sets the iterator to the given edge of the given graph.
+        ///
+        IncEdgeIt(const BpGraph&, const Edge&) { }
+        /// Next incident edge
+
+        /// Assign the iterator to the next incident edge
+        /// of the corresponding node.
+        IncEdgeIt& operator++() { return *this; }
+      };
+
+      /// The arc type of the graph
+
+      /// This class identifies a directed arc of the graph. It also serves
+      /// as a base class of the arc iterators,
+      /// thus they will convert to this type.
+      class Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Arc() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Arc(const Arc&) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        Arc(Invalid) { }
+        /// Equality operator
+
+        /// Equality operator.
+        ///
+        /// Two iterators are equal if and only if they point to the
+        /// same object or both are \c INVALID.
+        bool operator==(Arc) const { return true; }
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Arc) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// 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 \c Edge
+
+        /// Converison to \c Edge.
+        ///
+        operator Edge() const { return Edge(); }
+      };
+
+      /// Iterator class for the arcs.
+
+      /// This iterator goes through each directed arc of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of arcs in a graph \c g of type \c %BpGraph as follows:
+      ///\code
+      /// int count=0;
+      /// for(BpGraph::ArcIt a(g); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class ArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        ArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        ArcIt(const ArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        ArcIt(Invalid) { }
+        /// Sets the iterator to the first arc.
+
+        /// Sets the iterator to the first arc of the given graph.
+        ///
+        explicit ArcIt(const BpGraph &g)
+        {
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
+        ArcIt(const BpGraph&, const Arc&) { }
+        /// Next arc
+
+        /// Assign the iterator to the next arc.
+        ///
+        ArcIt& operator++() { return *this; }
+      };
+
+      /// 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 a graph \c g of type \c %BpGraph as follows.
+      ///\code
+      /// int count=0;
+      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class OutArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        OutArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        OutArcIt(const OutArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        OutArcIt(Invalid) { }
+        /// Sets the iterator to the first outgoing arc.
+
+        /// Sets the iterator to the first outgoing arc of the given node.
+        ///
+        OutArcIt(const BpGraph& n, const Node& g) {
+          ::lemon::ignore_unused_variable_warning(n);
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
+        OutArcIt(const BpGraph&, const Arc&) { }
+        /// Next outgoing arc
+
+        /// Assign the iterator to the next
+        /// outgoing arc of the corresponding node.
+        OutArcIt& operator++() { return *this; }
+      };
+
+      /// 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 %BpGraph as follows.
+      ///\code
+      /// int count=0;
+      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class InArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        InArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        InArcIt(const InArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        InArcIt(Invalid) { }
+        /// Sets the iterator to the first incoming arc.
+
+        /// Sets the iterator to the first incoming arc of the given node.
+        ///
+        InArcIt(const BpGraph& g, const Node& n) {
+          ::lemon::ignore_unused_variable_warning(n);
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
+        InArcIt(const BpGraph&, const Arc&) { }
+        /// Next incoming arc
+
+        /// Assign the iterator to the next
+        /// incoming arc of the corresponding node.
+        InArcIt& operator++() { return *this; }
+      };
+
+      /// \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:
+
+        /// Constructor
+        explicit NodeMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        NodeMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        NodeMap(const NodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
+        ///Assignment operator
+        template <typename CMap>
+        NodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \brief Standard graph map type for the red nodes.
+      ///
+      /// Standard graph map type for the red nodes.
+      /// It conforms to the ReferenceMap concept.
+      template<class T>
+      class RedNodeMap : public ReferenceMap<Node, T, T&, const T&>
+      {
+      public:
+
+        /// Constructor
+        explicit RedNodeMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        RedNodeMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        RedNodeMap(const RedNodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
+        ///Assignment operator
+        template <typename CMap>
+        RedNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \brief Standard graph map type for the blue nodes.
+      ///
+      /// Standard graph map type for the blue nodes.
+      /// It conforms to the ReferenceMap concept.
+      template<class T>
+      class BlueNodeMap : public ReferenceMap<Node, T, T&, const T&>
+      {
+      public:
+
+        /// Constructor
+        explicit BlueNodeMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        BlueNodeMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        BlueNodeMap(const BlueNodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
+        ///Assignment operator
+        template <typename CMap>
+        BlueNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \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:
+
+        /// Constructor
+        explicit ArcMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        ArcMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        ArcMap(const ArcMap& em) :
+          ReferenceMap<Arc, T, T&, const T&>(em) { }
+        ///Assignment operator
+        template <typename CMap>
+        ArcMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Arc, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \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&>
+      {
+      public:
+
+        /// Constructor
+        explicit EdgeMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        EdgeMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        EdgeMap(const EdgeMap& em) :
+          ReferenceMap<Edge, T, T&, const T&>(em) {}
+        ///Assignment operator
+        template <typename CMap>
+        EdgeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Edge, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \brief Gives back %true for red nodes.
+      ///
+      /// Gives back %true for red nodes.
+      bool red(const Node&) const { return true; }
+
+      /// \brief Gives back %true for blue nodes.
+      ///
+      /// Gives back %true for blue nodes.
+      bool blue(const Node&) const { return true; }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts unsafely the node to red node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts safely the node to red node
+      /// object. If the node is not from the red partition, then it
+      /// returns INVALID.
+      RedNode asRedNode(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. If the node is not from the blue partition, then it
+      /// returns INVALID.
+      BlueNode asBlueNode(const Node&) const { return BlueNode(); }
+
+      /// \brief Gives back the red end node of the edge.
+      ///
+      /// Gives back the red end node of the edge.
+      RedNode redNode(const Edge&) const { return RedNode(); }
+
+      /// \brief Gives back the blue end node of the edge.
+      ///
+      /// Gives back the blue end node of the edge.
+      BlueNode blueNode(const Edge&) const { return BlueNode(); }
+
+      /// \brief The first node of the edge.
+      ///
+      /// It is a synonim for the \c redNode().
+      Node u(Edge) const { return INVALID; }
+
+      /// \brief The second node of the edge.
+      ///
+      /// It is a synonim for the \c blueNode().
+      Node v(Edge) const { return INVALID; }
+
+      /// \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; }
+
+      /// \brief The ID of the node.
+      ///
+      /// Returns the ID of the given node.
+      int id(Node) const { return -1; }
+
+      /// \brief The red ID of the node.
+      ///
+      /// Returns the red ID of the given node.
+      int id(RedNode) const { return -1; }
+
+      /// \brief The blue ID of the node.
+      ///
+      /// Returns the blue ID of the given node.
+      int id(BlueNode) const { return -1; }
+
+      /// \brief The ID of the edge.
+      ///
+      /// Returns the ID of the given edge.
+      int id(Edge) const { return -1; }
+
+      /// \brief The ID of the arc.
+      ///
+      /// Returns the ID of the given arc.
+      int id(Arc) const { return -1; }
+
+      /// \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 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 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 An upper bound on the node IDs.
+      ///
+      /// Returns an upper bound on the node IDs.
+      int maxNodeId() const { return -1; }
+
+      /// \brief An upper bound on the red IDs.
+      ///
+      /// Returns an upper bound on the red IDs.
+      int maxRedId() const { return -1; }
+
+      /// \brief An upper bound on the blue IDs.
+      ///
+      /// Returns an upper bound on the blue IDs.
+      int maxBlueId() const { return -1; }
+
+      /// \brief An upper bound on the edge IDs.
+      ///
+      /// Returns an upper bound on the edge IDs.
+      int maxEdgeId() const { return -1; }
+
+      /// \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 given arc goes from a red node to a blue node.
+      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 source of the node
+      /// will be a red node.
+      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 {}
+      void next(Node&) const {}
+
+      void firstRed(RedNode&) const {}
+      void nextRed(RedNode&) const {}
+
+      void firstBlue(BlueNode&) const {}
+      void nextBlue(BlueNode&) const {}
+
+      void first(Edge&) const {}
+      void next(Edge&) const {}
+
+      void first(Arc&) const {}
+      void next(Arc&) const {}
+
+      void firstOut(Arc&, Node) const {}
+      void nextOut(Arc&) const {}
+
+      void firstIn(Arc&, Node) const {}
+      void nextIn(Arc&) const {}
+
+      void firstInc(Edge &, bool &, const Node &) const {}
+      void nextInc(Edge &, bool &) const {}
+
+      // The second parameter is dummy.
+      Node fromId(int, Node) const { return INVALID; }
+      // The second parameter is dummy.
+      Edge fromId(int, Edge) const { return INVALID; }
+      // The second parameter is dummy.
+      Arc fromId(int, Arc) const { return INVALID; }
+
+      // Dummy parameter.
+      int maxId(Node) const { return -1; }
+      // Dummy parameter.
+      int maxId(RedNode) const { return -1; }
+      // Dummy parameter.
+      int maxId(BlueNode) const { return -1; }
+      // Dummy parameter.
+      int maxId(Edge) const { return -1; }
+      // Dummy parameter.
+      int maxId(Arc) const { return -1; }
+
+      /// \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 incoming 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 incoming arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node runningNode(InArcIt) const { return INVALID; }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<BaseBpGraphComponent, _BpGraph>();
+          checkConcept<IterableBpGraphComponent<>, _BpGraph>();
+          checkConcept<IDableBpGraphComponent<>, _BpGraph>();
+          checkConcept<MappableBpGraphComponent<>, _BpGraph>();
+        }
+      };
+
+    };
+
+  }
+
+}
+
+#endif
diff --git a/lemon/concepts/digraph.h b/lemon/concepts/digraph.h
new file mode 100644
index 0000000..dc3c36b
--- /dev/null
+++ b/lemon/concepts/digraph.h
@@ -0,0 +1,491 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_CONCEPTS_DIGRAPH_H
+#define LEMON_CONCEPTS_DIGRAPH_H
+
+///\ingroup graph_concepts
+///\file
+///\brief The concept of directed graphs.
+
+#include <lemon/core.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concept_check.h>
+#include <lemon/concepts/graph_components.h>
+
+namespace lemon {
+  namespace concepts {
+
+    /// \ingroup graph_concepts
+    ///
+    /// \brief Class describing the concept of directed graphs.
+    ///
+    /// This class describes the common interface of all directed
+    /// graphs (digraphs).
+    ///
+    /// 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 Graph
+    class Digraph {
+    private:
+      /// 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:
+      /// Default constructor.
+      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 convert to this type.
+      class Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Node() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Node(const Node&) { }
+
+        /// %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 \c INVALID.
+        bool operator==(Node) const { return true; }
+
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Node) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// 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; }
+      };
+
+      /// 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;
+      /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
+      ///\endcode
+      class NodeIt : public Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        NodeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        NodeIt(const NodeIt& n) : Node(n) { }
+        /// %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 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.
+
+        /// Assign the iterator to the next node.
+        ///
+        NodeIt& operator++() { return *this; }
+      };
+
+
+      /// The arc type of the digraph
+
+      /// This class identifies an arc of the digraph. It also serves
+      /// as a base class of the arc iterators,
+      /// thus they will convert to this type.
+      class Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Arc() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Arc(const Arc&) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        Arc(Invalid) { }
+        /// Equality operator
+
+        /// Equality operator.
+        ///
+        /// Two iterators are equal if and only if they point to the
+        /// same object or both are \c INVALID.
+        bool operator==(Arc) const { return true; }
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Arc) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// 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; }
+      };
+
+      /// 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
+      /// of outgoing arcs of a node \c n
+      /// in a digraph \c g of type \c %Digraph as follows.
+      ///\code
+      /// int count=0;
+      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class OutArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        OutArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        OutArcIt(const OutArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        OutArcIt(Invalid) { }
+        /// 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&) { }
+        /// 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
+
+        /// Assign the iterator to the next
+        /// outgoing arc of the corresponding node.
+        OutArcIt& operator++() { return *this; }
+      };
+
+      /// 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 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 a(g, n); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class InArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        InArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        InArcIt(const InArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        InArcIt(Invalid) { }
+        /// 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&) { }
+        /// 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
+        /// incoming arc of the corresponding node.
+        InArcIt& operator++() { return *this; }
+      };
+
+      /// 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 a(g); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class ArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        ArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        ArcIt(const ArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        ArcIt(Invalid) { }
+        /// Sets the iterator to the first arc.
+
+        /// Sets the iterator to the first arc of the given digraph.
+        ///
+        explicit ArcIt(const Digraph& g) {
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given digraph.
+        ///
+        ArcIt(const Digraph&, const Arc&) { }
+        /// Next arc
+
+        /// Assign the iterator to the next arc.
+        ///
+        ArcIt& operator++() { return *this; }
+      };
+
+      /// \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; }
+
+      /// \brief The ID of the node.
+      ///
+      /// Returns the ID of the given node.
+      int id(Node) const { return -1; }
+
+      /// \brief The ID of the arc.
+      ///
+      /// Returns the ID of the given arc.
+      int id(Arc) const { return -1; }
+
+      /// \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 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 An upper bound on the node IDs.
+      ///
+      /// Returns an upper bound on the node IDs.
+      int maxNodeId() const { return -1; }
+
+      /// \brief An upper bound on the arc IDs.
+      ///
+      /// Returns an upper bound on the arc IDs.
+      int maxArcId() const { return -1; }
+
+      void first(Node&) const {}
+      void next(Node&) const {}
+
+      void first(Arc&) const {}
+      void next(Arc&) const {}
+
+
+      void firstIn(Arc&, const Node&) const {}
+      void nextIn(Arc&) const {}
+
+      void firstOut(Arc&, const Node&) const {}
+      void nextOut(Arc&) const {}
+
+      // The second parameter is dummy.
+      Node fromId(int, Node) const { return INVALID; }
+      // The second parameter is dummy.
+      Arc fromId(int, Arc) const { return INVALID; }
+
+      // Dummy parameter.
+      int maxId(Node) const { return -1; }
+      // Dummy parameter.
+      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.
+      ///
+      /// 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 incoming 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 incoming 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:
+
+        /// Constructor
+        explicit NodeMap(const Digraph&) { }
+        /// Constructor with given initial value
+        NodeMap(const Digraph&, T) { }
+
+      private:
+        ///Copy constructor
+        NodeMap(const NodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
+        ///Assignment operator
+        template <typename CMap>
+        NodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \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:
+
+        /// Constructor
+        explicit ArcMap(const Digraph&) { }
+        /// Constructor with given initial value
+        ArcMap(const Digraph&, T) { }
+
+      private:
+        ///Copy constructor
+        ArcMap(const ArcMap& em) :
+          ReferenceMap<Arc, T, T&, const T&>(em) { }
+        ///Assignment operator
+        template <typename CMap>
+        ArcMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Arc, T>, CMap>();
+          return *this;
+        }
+      };
+
+      template <typename _Digraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<BaseDigraphComponent, _Digraph>();
+          checkConcept<IterableDigraphComponent<>, _Digraph>();
+          checkConcept<IDableDigraphComponent<>, _Digraph>();
+          checkConcept<MappableDigraphComponent<>, _Digraph>();
+        }
+      };
+
+    };
+
+  } //namespace concepts
+} //namespace lemon
+
+
+
+#endif
diff --git a/lemon/concepts/graph.h b/lemon/concepts/graph.h
new file mode 100644
index 0000000..76e43da
--- /dev/null
+++ b/lemon/concepts/graph.h
@@ -0,0 +1,788 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup graph_concepts
+///\file
+///\brief The concept of undirected graphs.
+
+#ifndef LEMON_CONCEPTS_GRAPH_H
+#define LEMON_CONCEPTS_GRAPH_H
+
+#include <lemon/concepts/graph_components.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concept_check.h>
+#include <lemon/core.h>
+
+namespace lemon {
+  namespace concepts {
+
+    /// \ingroup graph_concepts
+    ///
+    /// \brief Class describing the concept of undirected graphs.
+    ///
+    /// This class describes the common interface of all undirected
+    /// graphs.
+    ///
+    /// 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 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 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.
+    ///
+    /// 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 GraphCopy instead.
+      Graph(const Graph&) {}
+      /// \brief Assignment of a graph to another one is \e not allowed.
+      /// Use GraphCopy instead.
+      void operator=(const Graph&) {}
+
+    public:
+      /// 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;
+
+      /// 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
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Node() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Node(const Node&) { }
+
+        /// %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 \c INVALID.
+        bool operator==(Node) const { return true; }
+
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Node) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// 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.
+        bool operator<(Node) const { return false; }
+
+      };
+
+      /// 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;
+      /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
+      ///\endcode
+      class NodeIt : public Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        NodeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        NodeIt(const NodeIt& n) : Node(n) { }
+        /// %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 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.
+
+        /// Assign the iterator to the next node.
+        ///
+        NodeIt& operator++() { return *this; }
+      };
+
+
+      /// 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
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Edge() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Edge(const Edge&) { }
+        /// %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 \c INVALID.
+        bool operator==(Edge) const { return true; }
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Edge) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// 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; }
+      };
+
+      /// 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;
+      /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
+      ///\endcode
+      class EdgeIt : public Edge {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        EdgeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        EdgeIt(const EdgeIt& e) : Edge(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        EdgeIt(Invalid) { }
+        /// 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; }
+      };
+
+      /// 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
+      /// int count=0;
+      /// 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
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        IncEdgeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        IncEdgeIt(Invalid) { }
+        /// 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&) { }
+        /// 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 edge
+
+        /// Assign the iterator to the next incident edge
+        /// of the corresponding node.
+        IncEdgeIt& operator++() { return *this; }
+      };
+
+      /// The arc type of the graph
+
+      /// This class identifies a directed arc of the graph. It also serves
+      /// as a base class of the arc iterators,
+      /// thus they will convert to this type.
+      class Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Arc() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Arc(const Arc&) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        Arc(Invalid) { }
+        /// Equality operator
+
+        /// Equality operator.
+        ///
+        /// Two iterators are equal if and only if they point to the
+        /// same object or both are \c INVALID.
+        bool operator==(Arc) const { return true; }
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Arc) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// 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 \c Edge
+
+        /// Converison to \c Edge.
+        ///
+        operator Edge() const { return Edge(); }
+      };
+
+      /// Iterator class for the arcs.
+
+      /// This iterator goes through each directed arc of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of arcs in a graph \c g of type \c %Graph as follows:
+      ///\code
+      /// int count=0;
+      /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class ArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        ArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        ArcIt(const ArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        ArcIt(Invalid) { }
+        /// Sets the iterator to the first arc.
+
+        /// Sets the iterator to the first arc of the given graph.
+        ///
+        explicit ArcIt(const Graph &g) {
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
+        ArcIt(const Graph&, const Arc&) { }
+        /// Next arc
+
+        /// Assign the iterator to the next arc.
+        ///
+        ArcIt& operator++() { return *this; }
+      };
+
+      /// 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 a graph \c g of type \c %Graph as follows.
+      ///\code
+      /// int count=0;
+      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class OutArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        OutArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        OutArcIt(const OutArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        OutArcIt(Invalid) { }
+        /// 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) {
+          ::lemon::ignore_unused_variable_warning(n);
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// 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
+
+        /// Assign the iterator to the next
+        /// outgoing arc of the corresponding node.
+        OutArcIt& operator++() { return *this; }
+      };
+
+      /// 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 (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class InArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        InArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        InArcIt(const InArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        InArcIt(Invalid) { }
+        /// 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) {
+          ::lemon::ignore_unused_variable_warning(n);
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// 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
+        /// incoming arc of the corresponding node.
+        InArcIt& operator++() { return *this; }
+      };
+
+      /// \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:
+
+        /// Constructor
+        explicit NodeMap(const Graph&) { }
+        /// Constructor with given initial value
+        NodeMap(const Graph&, T) { }
+
+      private:
+        ///Copy constructor
+        NodeMap(const NodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
+        ///Assignment operator
+        template <typename CMap>
+        NodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \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:
+
+        /// Constructor
+        explicit ArcMap(const Graph&) { }
+        /// Constructor with given initial value
+        ArcMap(const Graph&, T) { }
+
+      private:
+        ///Copy constructor
+        ArcMap(const ArcMap& em) :
+          ReferenceMap<Arc, T, T&, const T&>(em) { }
+        ///Assignment operator
+        template <typename CMap>
+        ArcMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Arc, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \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&>
+      {
+      public:
+
+        /// Constructor
+        explicit EdgeMap(const Graph&) { }
+        /// Constructor with given initial value
+        EdgeMap(const Graph&, T) { }
+
+      private:
+        ///Copy constructor
+        EdgeMap(const EdgeMap& em) :
+          ReferenceMap<Edge, T, T&, const T&>(em) {}
+        ///Assignment operator
+        template <typename CMap>
+        EdgeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Edge, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \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 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 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; }
+
+      /// \brief The ID of the node.
+      ///
+      /// Returns the ID of the given node.
+      int id(Node) const { return -1; }
+
+      /// \brief The ID of the edge.
+      ///
+      /// Returns the ID of the given edge.
+      int id(Edge) const { return -1; }
+
+      /// \brief The ID of the arc.
+      ///
+      /// Returns the ID of the given arc.
+      int id(Arc) const { return -1; }
+
+      /// \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 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 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 An upper bound on the node IDs.
+      ///
+      /// Returns an upper bound on the node IDs.
+      int maxNodeId() const { return -1; }
+
+      /// \brief An upper bound on the edge IDs.
+      ///
+      /// Returns an upper bound on the edge IDs.
+      int maxEdgeId() const { return -1; }
+
+      /// \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 {}
+      void next(Node&) const {}
+
+      void first(Edge&) const {}
+      void next(Edge&) const {}
+
+      void first(Arc&) const {}
+      void next(Arc&) const {}
+
+      void firstOut(Arc&, Node) const {}
+      void nextOut(Arc&) const {}
+
+      void firstIn(Arc&, Node) const {}
+      void nextIn(Arc&) const {}
+
+      void firstInc(Edge &, bool &, const Node &) const {}
+      void nextInc(Edge &, bool &) const {}
+
+      // The second parameter is dummy.
+      Node fromId(int, Node) const { return INVALID; }
+      // The second parameter is dummy.
+      Edge fromId(int, Edge) const { return INVALID; }
+      // The second parameter is dummy.
+      Arc fromId(int, Arc) const { return INVALID; }
+
+      // Dummy parameter.
+      int maxId(Node) const { return -1; }
+      // Dummy parameter.
+      int maxId(Edge) const { return -1; }
+      // Dummy parameter.
+      int maxId(Arc) const { return -1; }
+
+      /// \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 incoming 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 incoming arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node runningNode(InArcIt) const { return INVALID; }
+
+      template <typename _Graph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<BaseGraphComponent, _Graph>();
+          checkConcept<IterableGraphComponent<>, _Graph>();
+          checkConcept<IDableGraphComponent<>, _Graph>();
+          checkConcept<MappableGraphComponent<>, _Graph>();
+        }
+      };
+
+    };
+
+  }
+
+}
+
+#endif
diff --git a/lemon/concepts/graph_components.h b/lemon/concepts/graph_components.h
new file mode 100644
index 0000000..9df28f3
--- /dev/null
+++ b/lemon/concepts/graph_components.h
@@ -0,0 +1,2134 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup graph_concepts
+///\file
+///\brief The concepts of graph components.
+
+#ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
+#define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
+
+#include <lemon/core.h>
+#include <lemon/concepts/maps.h>
+
+#include <lemon/bits/alteration_notifier.h>
+
+namespace lemon {
+  namespace concepts {
+
+    /// \brief Concept class for \c Node, \c Arc and \c Edge types.
+    ///
+    /// This class describes the concept of \c Node, \c Arc and \c Edge
+    /// subtypes of digraph and graph types.
+    ///
+    /// \note This class is a template class so that we can use it to
+    /// create graph skeleton classes. The reason for this is that \c Node
+    /// and \c Arc (or \c Edge) types should \e not derive from the same
+    /// base class. For \c Node you should instantiate it with character
+    /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
+#ifndef DOXYGEN
+    template <char sel = '0'>
+#endif
+    class GraphItem {
+    public:
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// \warning The default constructor is not required to set
+      /// the item to some well-defined value. So you should consider it
+      /// as uninitialized.
+      GraphItem() {}
+
+      /// \brief Copy constructor.
+      ///
+      /// Copy constructor.
+      GraphItem(const GraphItem &) {}
+
+      /// \brief Constructor for conversion from \c INVALID.
+      ///
+      /// Constructor for conversion from \c INVALID.
+      /// It initializes the item to be invalid.
+      /// \sa Invalid for more details.
+      GraphItem(Invalid) {}
+
+      /// \brief Assignment operator.
+      ///
+      /// Assignment operator for the item.
+      GraphItem& operator=(const GraphItem&) { return *this; }
+
+      /// \brief Assignment operator for INVALID.
+      ///
+      /// This operator makes the item invalid.
+      GraphItem& operator=(Invalid) { return *this; }
+
+      /// \brief Equality operator.
+      ///
+      /// Equality operator.
+      bool operator==(const GraphItem&) const { return false; }
+
+      /// \brief Inequality operator.
+      ///
+      /// Inequality operator.
+      bool operator!=(const GraphItem&) const { return false; }
+
+      /// \brief Ordering operator.
+      ///
+      /// This operator defines an ordering of the items.
+      /// It makes possible to use graph item types as key types in
+      /// associative containers (e.g. \c std::map).
+      ///
+      /// \note This operator only has to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(const GraphItem&) const { return false; }
+
+      template<typename _GraphItem>
+      struct Constraints {
+        void constraints() {
+          _GraphItem i1;
+          i1=INVALID;
+          _GraphItem i2 = i1;
+          _GraphItem i3 = INVALID;
+
+          i1 = i2 = i3;
+
+          bool b;
+          ::lemon::ignore_unused_variable_warning(b);
+
+          b = (ia == ib) && (ia != ib);
+          b = (ia == INVALID) && (ib != INVALID);
+          b = (ia < ib);
+        }
+
+        const _GraphItem &ia;
+        const _GraphItem &ib;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Base skeleton class for directed graphs.
+    ///
+    /// This class describes the base interface of directed graph types.
+    /// All digraph %concepts have to conform to this class.
+    /// It just provides types for nodes and arcs and functions
+    /// to get the source and the target nodes of arcs.
+    class BaseDigraphComponent {
+    public:
+
+      typedef BaseDigraphComponent Digraph;
+
+      /// \brief Node class of the digraph.
+      ///
+      /// This class represents the nodes of the digraph.
+      typedef GraphItem<'n'> Node;
+
+      /// \brief Arc class of the digraph.
+      ///
+      /// This class represents the arcs of the digraph.
+      typedef GraphItem<'a'> Arc;
+
+      /// \brief Return the source node of an arc.
+      ///
+      /// This function returns the source node of an arc.
+      Node source(const Arc&) const { return INVALID; }
+
+      /// \brief Return the target node of an arc.
+      ///
+      /// This function returns the target node of an arc.
+      Node target(const Arc&) const { return INVALID; }
+
+      /// \brief Return the opposite node on the given arc.
+      ///
+      /// This function returns the opposite node on the given arc.
+      Node oppositeNode(const Node&, const Arc&) const {
+        return INVALID;
+      }
+
+      template <typename _Digraph>
+      struct Constraints {
+        typedef typename _Digraph::Node Node;
+        typedef typename _Digraph::Arc Arc;
+
+        void constraints() {
+          checkConcept<GraphItem<'n'>, Node>();
+          checkConcept<GraphItem<'a'>, Arc>();
+          {
+            Node n;
+            Arc e(INVALID);
+            n = digraph.source(e);
+            n = digraph.target(e);
+            n = digraph.oppositeNode(n, e);
+          }
+        }
+
+        const _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Base skeleton class for undirected graphs.
+    ///
+    /// This class describes the base interface of undirected graph types.
+    /// All graph %concepts have to conform to this class.
+    /// It extends the interface of \ref BaseDigraphComponent with an
+    /// \c Edge type and functions to get the end nodes of edges,
+    /// to convert from arcs to edges and to get both direction of edges.
+    class BaseGraphComponent : public BaseDigraphComponent {
+    public:
+
+      typedef BaseGraphComponent Graph;
+
+      typedef BaseDigraphComponent::Node Node;
+      typedef BaseDigraphComponent::Arc Arc;
+
+      /// \brief Undirected edge class of the graph.
+      ///
+      /// This class represents the undirected edges of the graph.
+      /// Undirected graphs can be used as directed graphs, each edge is
+      /// represented by two opposite directed arcs.
+      class Edge : public GraphItem<'e'> {
+        typedef GraphItem<'e'> Parent;
+
+      public:
+        /// \brief Default constructor.
+        ///
+        /// Default constructor.
+        /// \warning The default constructor is not required to set
+        /// the item to some well-defined value. So you should consider it
+        /// as uninitialized.
+        Edge() {}
+
+        /// \brief Copy constructor.
+        ///
+        /// Copy constructor.
+        Edge(const Edge &) : Parent() {}
+
+        /// \brief Constructor for conversion from \c INVALID.
+        ///
+        /// Constructor for conversion from \c INVALID.
+        /// It initializes the item to be invalid.
+        /// \sa Invalid for more details.
+        Edge(Invalid) {}
+
+        /// \brief Constructor for conversion from an arc.
+        ///
+        /// Constructor for conversion from an arc.
+        /// Besides the core graph item functionality each arc should
+        /// be convertible to the represented edge.
+        Edge(const Arc&) {}
+     };
+
+      /// \brief Return one end node of an edge.
+      ///
+      /// This function returns one end node of an edge.
+      Node u(const Edge&) const { return INVALID; }
+
+      /// \brief Return the other end node of an edge.
+      ///
+      /// This function returns the other end node of an edge.
+      Node v(const Edge&) const { return INVALID; }
+
+      /// \brief Return a directed arc related to an edge.
+      ///
+      /// This function returns a directed arc from its direction and the
+      /// represented edge.
+      Arc direct(const Edge&, bool) const { return INVALID; }
+
+      /// \brief Return a directed arc related to an edge.
+      ///
+      /// This function returns a directed arc from its source node and the
+      /// represented edge.
+      Arc direct(const Edge&, const Node&) const { return INVALID; }
+
+      /// \brief Return the direction of the arc.
+      ///
+      /// Returns the direction of the arc. Each arc represents an
+      /// edge with a direction. It gives back the
+      /// direction.
+      bool direction(const Arc&) const { return true; }
+
+      /// \brief Return the opposite arc.
+      ///
+      /// This function returns the opposite arc, i.e. the arc representing
+      /// the same edge and has opposite direction.
+      Arc oppositeArc(const Arc&) const { return INVALID; }
+
+      template <typename _Graph>
+      struct Constraints {
+        typedef typename _Graph::Node Node;
+        typedef typename _Graph::Arc Arc;
+        typedef typename _Graph::Edge Edge;
+
+        void constraints() {
+          checkConcept<BaseDigraphComponent, _Graph>();
+          checkConcept<GraphItem<'e'>, Edge>();
+          {
+            Node n;
+            Edge ue(INVALID);
+            Arc e;
+            n = graph.u(ue);
+            n = graph.v(ue);
+            e = graph.direct(ue, true);
+            e = graph.direct(ue, false);
+            e = graph.direct(ue, n);
+            e = graph.oppositeArc(e);
+            ue = e;
+            bool d = graph.direction(e);
+            ::lemon::ignore_unused_variable_warning(d);
+          }
+        }
+
+        const _Graph& graph;
+      Constraints() {}
+      };
+
+    };
+
+    /// \brief Base skeleton class for undirected bipartite graphs.
+    ///
+    /// This class describes the base interface of undirected
+    /// bipartite graph types.  All bipartite graph %concepts have to
+    /// conform to this class.  It extends the interface of \ref
+    /// BaseGraphComponent with an \c Edge type and functions to get
+    /// the end nodes of edges, to convert from arcs to edges and to
+    /// get both direction of edges.
+    class BaseBpGraphComponent : public BaseGraphComponent {
+    public:
+
+      typedef BaseBpGraphComponent BpGraph;
+
+      typedef BaseDigraphComponent::Node Node;
+      typedef BaseDigraphComponent::Arc Arc;
+
+      /// \brief Class to represent red nodes.
+      ///
+      /// This class represents the red nodes of the graph. The red
+      /// nodes can also be used as normal nodes.
+      class RedNode : public Node {
+        typedef Node Parent;
+
+      public:
+        /// \brief Default constructor.
+        ///
+        /// Default constructor.
+        /// \warning The default constructor is not required to set
+        /// the item to some well-defined value. So you should consider it
+        /// as uninitialized.
+        RedNode() {}
+
+        /// \brief Copy constructor.
+        ///
+        /// Copy constructor.
+        RedNode(const RedNode &) : Parent() {}
+
+        /// \brief Constructor for conversion from \c INVALID.
+        ///
+        /// Constructor for conversion from \c INVALID.
+        /// It initializes the item to be invalid.
+        /// \sa Invalid for more details.
+        RedNode(Invalid) {}
+      };
+
+      /// \brief Class to represent blue nodes.
+      ///
+      /// This class represents the blue nodes of the graph. The blue
+      /// nodes can also be used as normal nodes.
+      class BlueNode : public Node {
+        typedef Node Parent;
+
+      public:
+        /// \brief Default constructor.
+        ///
+        /// Default constructor.
+        /// \warning The default constructor is not required to set
+        /// the item to some well-defined value. So you should consider it
+        /// as uninitialized.
+        BlueNode() {}
+
+        /// \brief Copy constructor.
+        ///
+        /// Copy constructor.
+        BlueNode(const BlueNode &) : Parent() {}
+
+        /// \brief Constructor for conversion from \c INVALID.
+        ///
+        /// Constructor for conversion from \c INVALID.
+        /// It initializes the item to be invalid.
+        /// \sa Invalid for more details.
+        BlueNode(Invalid) {}
+
+        /// \brief Constructor for conversion from a node.
+        ///
+        /// Constructor for conversion from a node. The conversion can
+        /// be invalid, since the Node can be member of the red
+        /// set.
+        BlueNode(const Node&) {}
+      };
+
+      /// \brief Gives back %true for red nodes.
+      ///
+      /// Gives back %true for red nodes.
+      bool red(const Node&) const { return true; }
+
+      /// \brief Gives back %true for blue nodes.
+      ///
+      /// Gives back %true for blue nodes.
+      bool blue(const Node&) const { return true; }
+
+      /// \brief Gives back the red end node of the edge.
+      ///
+      /// Gives back the red end node of the edge.
+      RedNode redNode(const Edge&) const { return RedNode(); }
+
+      /// \brief Gives back the blue end node of the edge.
+      ///
+      /// Gives back the blue end node of the edge.
+      BlueNode blueNode(const Edge&) const { return BlueNode(); }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts unsafely the node to red node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts safely the node to red node
+      /// object. If the node is not from the red partition, then it
+      /// returns INVALID.
+      RedNode asRedNode(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. If the node is not from the blue partition, then it
+      /// returns INVALID.
+      BlueNode asBlueNode(const Node&) const { return BlueNode(); }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        typedef typename _BpGraph::Node Node;
+        typedef typename _BpGraph::RedNode RedNode;
+        typedef typename _BpGraph::BlueNode BlueNode;
+        typedef typename _BpGraph::Arc Arc;
+        typedef typename _BpGraph::Edge Edge;
+
+        void constraints() {
+          checkConcept<BaseGraphComponent, _BpGraph>();
+          checkConcept<GraphItem<'n'>, RedNode>();
+          checkConcept<GraphItem<'n'>, BlueNode>();
+          {
+            Node n;
+            RedNode rn;
+            BlueNode bn;
+            Node rnan = rn;
+            Node bnan = bn;
+            Edge e;
+            bool b;
+            b = bpgraph.red(rnan);
+            b = bpgraph.blue(bnan);
+            rn = bpgraph.redNode(e);
+            bn = bpgraph.blueNode(e);
+            rn = bpgraph.asRedNodeUnsafe(rnan);
+            bn = bpgraph.asBlueNodeUnsafe(bnan);
+            rn = bpgraph.asRedNode(rnan);
+            bn = bpgraph.asBlueNode(bnan);
+            ::lemon::ignore_unused_variable_warning(b);
+          }
+        }
+
+        const _BpGraph& bpgraph;
+      };
+
+    };
+
+    /// \brief Skeleton class for \e idable directed graphs.
+    ///
+    /// This class describes the interface of \e idable directed graphs.
+    /// It extends \ref BaseDigraphComponent with the core ID functions.
+    /// The ids of the items must be unique and immutable.
+    /// This concept is part of the Digraph concept.
+    template <typename BAS = BaseDigraphComponent>
+    class IDableDigraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::Arc Arc;
+
+      /// \brief Return a unique integer id for the given node.
+      ///
+      /// This function returns a unique integer id for the given node.
+      int id(const Node&) const { return -1; }
+
+      /// \brief Return the node by its unique id.
+      ///
+      /// This function returns the node by its unique id.
+      /// If the digraph does not contain a node with the given id,
+      /// then the result of the function is undefined.
+      Node nodeFromId(int) const { return INVALID; }
+
+      /// \brief Return a unique integer id for the given arc.
+      ///
+      /// This function returns a unique integer id for the given arc.
+      int id(const Arc&) const { return -1; }
+
+      /// \brief Return the arc by its unique id.
+      ///
+      /// This function returns the arc by its unique id.
+      /// If the digraph does not contain an arc with the given id,
+      /// then the result of the function is undefined.
+      Arc arcFromId(int) const { return INVALID; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// node id.
+      ///
+      /// This function returns an integer greater or equal to the
+      /// maximum node id.
+      int maxNodeId() const { return -1; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// arc id.
+      ///
+      /// This function returns an integer greater or equal to the
+      /// maximum arc id.
+      int maxArcId() const { return -1; }
+
+      template <typename _Digraph>
+      struct Constraints {
+
+        void constraints() {
+          checkConcept<Base, _Digraph >();
+          typename _Digraph::Node node;
+          node=INVALID;
+          int nid = digraph.id(node);
+          nid = digraph.id(node);
+          node = digraph.nodeFromId(nid);
+          typename _Digraph::Arc arc;
+          arc=INVALID;
+          int eid = digraph.id(arc);
+          eid = digraph.id(arc);
+          arc = digraph.arcFromId(eid);
+
+          nid = digraph.maxNodeId();
+          ::lemon::ignore_unused_variable_warning(nid);
+          eid = digraph.maxArcId();
+          ::lemon::ignore_unused_variable_warning(eid);
+        }
+
+        const _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for \e idable undirected graphs.
+    ///
+    /// This class describes the interface of \e idable undirected
+    /// graphs. It extends \ref IDableDigraphComponent with the core ID
+    /// functions of undirected graphs.
+    /// The ids of the items must be unique and immutable.
+    /// This concept is part of the Graph concept.
+    template <typename BAS = BaseGraphComponent>
+    class IDableGraphComponent : public IDableDigraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Edge Edge;
+
+      using IDableDigraphComponent<Base>::id;
+
+      /// \brief Return a unique integer id for the given edge.
+      ///
+      /// This function returns a unique integer id for the given edge.
+      int id(const Edge&) const { return -1; }
+
+      /// \brief Return the edge by its unique id.
+      ///
+      /// This function returns the edge by its unique id.
+      /// If the graph does not contain an edge with the given id,
+      /// then the result of the function is undefined.
+      Edge edgeFromId(int) const { return INVALID; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// edge id.
+      ///
+      /// This function returns an integer greater or equal to the
+      /// maximum edge id.
+      int maxEdgeId() const { return -1; }
+
+      template <typename _Graph>
+      struct Constraints {
+
+        void constraints() {
+          checkConcept<IDableDigraphComponent<Base>, _Graph >();
+          typename _Graph::Edge edge;
+          int ueid = graph.id(edge);
+          ueid = graph.id(edge);
+          edge = graph.edgeFromId(ueid);
+          ueid = graph.maxEdgeId();
+          ::lemon::ignore_unused_variable_warning(ueid);
+        }
+
+        const _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for \e idable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of \e idable undirected
+    /// bipartite graphs. It extends \ref IDableGraphComponent with
+    /// the core ID functions of undirected bipartite graphs. Beside
+    /// the regular node ids, this class also provides ids within the
+    /// the red and blue sets of the nodes. This concept is part of
+    /// the BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class IDableBpGraphComponent : public IDableGraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef IDableGraphComponent<BAS> Parent;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+
+      using Parent::id;
+
+      /// \brief Return a unique integer id for the given node in the red set.
+      ///
+      /// Return a unique integer id for the given node in the red set.
+      int id(const RedNode&) const { return -1; }
+
+      /// \brief Return a unique integer id for the given node in the blue set.
+      ///
+      /// Return a unique integer id for the given node in the blue set.
+      int id(const BlueNode&) const { return -1; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// node id in the red set.
+      ///
+      /// Return an integer greater or equal to the maximum
+      /// node id in the red set.
+      int maxRedId() const { return -1; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// node id in the blue set.
+      ///
+      /// Return an integer greater or equal to the maximum
+      /// node id in the blue set.
+      int maxBlueId() const { return -1; }
+
+      template <typename _BpGraph>
+      struct Constraints {
+
+        void constraints() {
+          checkConcept<IDableGraphComponent<Base>, _BpGraph>();
+          typename _BpGraph::Node node;
+          typename _BpGraph::RedNode red;
+          typename _BpGraph::BlueNode blue;
+          int rid = bpgraph.id(red);
+          int bid = bpgraph.id(blue);
+          rid = bpgraph.maxRedId();
+          bid = bpgraph.maxBlueId();
+          ::lemon::ignore_unused_variable_warning(rid);
+          ::lemon::ignore_unused_variable_warning(bid);
+        }
+
+        const _BpGraph& bpgraph;
+      };
+    };
+
+    /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
+    ///
+    /// This class describes the concept of \c NodeIt, \c ArcIt and
+    /// \c EdgeIt subtypes of digraph and graph types.
+    template <typename GR, typename Item>
+    class GraphItemIt : public Item {
+    public:
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// \warning The default constructor is not required to set
+      /// the iterator to some well-defined value. So you should consider it
+      /// as uninitialized.
+      GraphItemIt() {}
+
+      /// \brief Copy constructor.
+      ///
+      /// Copy constructor.
+      GraphItemIt(const GraphItemIt& it) : Item(it) {}
+
+      /// \brief Constructor that sets the iterator to the first item.
+      ///
+      /// Constructor that sets the iterator to the first item.
+      explicit GraphItemIt(const GR&) {}
+
+      /// \brief Constructor for conversion from \c INVALID.
+      ///
+      /// Constructor for conversion from \c INVALID.
+      /// It initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      GraphItemIt(Invalid) {}
+
+      /// \brief Assignment operator.
+      ///
+      /// Assignment operator for the iterator.
+      GraphItemIt& operator=(const GraphItemIt&) { return *this; }
+
+      /// \brief Increment the iterator.
+      ///
+      /// This operator increments the iterator, i.e. assigns it to the
+      /// next item.
+      GraphItemIt& operator++() { return *this; }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator.
+      /// Two iterators are equal if and only if they point to the
+      /// same object or both are invalid.
+      bool operator==(const GraphItemIt&) const { return true;}
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator.
+      /// Two iterators are equal if and only if they point to the
+      /// same object or both are invalid.
+      bool operator!=(const GraphItemIt&) const { return true;}
+
+      template<typename _GraphItemIt>
+      struct Constraints {
+        void constraints() {
+          checkConcept<GraphItem<>, _GraphItemIt>();
+          _GraphItemIt it1(g);
+          _GraphItemIt it2;
+          _GraphItemIt it3 = it1;
+          _GraphItemIt it4 = INVALID;
+          ::lemon::ignore_unused_variable_warning(it3);
+          ::lemon::ignore_unused_variable_warning(it4);
+
+          it2 = ++it1;
+          ++it2 = it1;
+          ++(++it1);
+
+          Item bi = it1;
+          bi = it2;
+        }
+        const GR& g;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Concept class for \c InArcIt, \c OutArcIt and
+    /// \c IncEdgeIt types.
+    ///
+    /// This class describes the concept of \c InArcIt, \c OutArcIt
+    /// and \c IncEdgeIt subtypes of digraph and graph types.
+    ///
+    /// \note Since these iterator classes do not inherit from the same
+    /// base class, there is an additional template parameter (selector)
+    /// \c sel. For \c InArcIt you should instantiate it with character
+    /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
+    template <typename GR,
+              typename Item = typename GR::Arc,
+              typename Base = typename GR::Node,
+              char sel = '0'>
+    class GraphIncIt : public Item {
+    public:
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// \warning The default constructor is not required to set
+      /// the iterator to some well-defined value. So you should consider it
+      /// as uninitialized.
+      GraphIncIt() {}
+
+      /// \brief Copy constructor.
+      ///
+      /// Copy constructor.
+      GraphIncIt(const GraphIncIt& it) : Item(it) {}
+
+      /// \brief Constructor that sets the iterator to the first
+      /// incoming or outgoing arc.
+      ///
+      /// Constructor that sets the iterator to the first arc
+      /// incoming to or outgoing from the given node.
+      explicit GraphIncIt(const GR&, const Base&) {}
+
+      /// \brief Constructor for conversion from \c INVALID.
+      ///
+      /// Constructor for conversion from \c INVALID.
+      /// It initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      GraphIncIt(Invalid) {}
+
+      /// \brief Assignment operator.
+      ///
+      /// Assignment operator for the iterator.
+      GraphIncIt& operator=(const GraphIncIt&) { return *this; }
+
+      /// \brief Increment the iterator.
+      ///
+      /// This operator increments the iterator, i.e. assigns it to the
+      /// next arc incoming to or outgoing from the given node.
+      GraphIncIt& operator++() { return *this; }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator.
+      /// Two iterators are equal if and only if they point to the
+      /// same object or both are invalid.
+      bool operator==(const GraphIncIt&) const { return true;}
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator.
+      /// Two iterators are equal if and only if they point to the
+      /// same object or both are invalid.
+      bool operator!=(const GraphIncIt&) const { return true;}
+
+      template <typename _GraphIncIt>
+      struct Constraints {
+        void constraints() {
+          checkConcept<GraphItem<sel>, _GraphIncIt>();
+          _GraphIncIt it1(graph, node);
+          _GraphIncIt it2;
+          _GraphIncIt it3 = it1;
+          _GraphIncIt it4 = INVALID;
+          ::lemon::ignore_unused_variable_warning(it3);
+          ::lemon::ignore_unused_variable_warning(it4);
+
+          it2 = ++it1;
+          ++it2 = it1;
+          ++(++it1);
+          Item e = it1;
+          e = it2;
+        }
+        const Base& node;
+        const GR& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for iterable directed graphs.
+    ///
+    /// This class describes the interface of iterable directed
+    /// graphs. It extends \ref BaseDigraphComponent with the core
+    /// iterable interface.
+    /// This concept is part of the Digraph concept.
+    template <typename BAS = BaseDigraphComponent>
+    class IterableDigraphComponent : public BAS {
+
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::Arc Arc;
+
+      typedef IterableDigraphComponent Digraph;
+
+      /// \name Base Iteration
+      ///
+      /// This interface provides functions for iteration on digraph items.
+      ///
+      /// @{
+
+      /// \brief Return the first node.
+      ///
+      /// This function gives back the first node in the iteration order.
+      void first(Node&) const {}
+
+      /// \brief Return the next node.
+      ///
+      /// This function gives back the next node in the iteration order.
+      void next(Node&) const {}
+
+      /// \brief Return the first arc.
+      ///
+      /// This function gives back the first arc in the iteration order.
+      void first(Arc&) const {}
+
+      /// \brief Return the next arc.
+      ///
+      /// This function gives back the next arc in the iteration order.
+      void next(Arc&) const {}
+
+      /// \brief Return the first arc incoming to the given node.
+      ///
+      /// This function gives back the first arc incoming to the
+      /// given node.
+      void firstIn(Arc&, const Node&) const {}
+
+      /// \brief Return the next arc incoming to the given node.
+      ///
+      /// This function gives back the next arc incoming to the
+      /// given node.
+      void nextIn(Arc&) const {}
+
+      /// \brief Return the first arc outgoing form the given node.
+      ///
+      /// This function gives back the first arc outgoing form the
+      /// given node.
+      void firstOut(Arc&, const Node&) const {}
+
+      /// \brief Return the next arc outgoing form the given node.
+      ///
+      /// This function gives back the next arc outgoing form the
+      /// given node.
+      void nextOut(Arc&) const {}
+
+      /// @}
+
+      /// \name Class Based Iteration
+      ///
+      /// This interface provides iterator classes for digraph items.
+      ///
+      /// @{
+
+      /// \brief This iterator goes through each node.
+      ///
+      /// This iterator goes through each node.
+      ///
+      typedef GraphItemIt<Digraph, Node> NodeIt;
+
+      /// \brief This iterator goes through each arc.
+      ///
+      /// This iterator goes through each arc.
+      ///
+      typedef GraphItemIt<Digraph, Arc> ArcIt;
+
+      /// \brief This iterator goes trough the incoming arcs of a node.
+      ///
+      /// This iterator goes trough the \e incoming arcs of a certain node
+      /// of a digraph.
+      typedef GraphIncIt<Digraph, Arc, Node, 'i'> InArcIt;
+
+      /// \brief This iterator goes trough the outgoing arcs of a node.
+      ///
+      /// This iterator goes trough the \e outgoing arcs of a certain node
+      /// of a digraph.
+      typedef GraphIncIt<Digraph, Arc, Node, 'o'> OutArcIt;
+
+      /// \brief The base node of the iterator.
+      ///
+      /// This function gives back the base node of the iterator.
+      /// It is always the target node of the pointed arc.
+      Node baseNode(const InArcIt&) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// This function gives back the running node of the iterator.
+      /// It is always the source node of the pointed arc.
+      Node runningNode(const InArcIt&) const { return INVALID; }
+
+      /// \brief The base node of the iterator.
+      ///
+      /// This function gives back the base node of the iterator.
+      /// It is always the source node of the pointed arc.
+      Node baseNode(const OutArcIt&) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// This function gives back the running node of the iterator.
+      /// It is always the target node of the pointed arc.
+      Node runningNode(const OutArcIt&) const { return INVALID; }
+
+      /// @}
+
+      template <typename _Digraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _Digraph>();
+
+          {
+            typename _Digraph::Node node(INVALID);
+            typename _Digraph::Arc arc(INVALID);
+            {
+              digraph.first(node);
+              digraph.next(node);
+            }
+            {
+              digraph.first(arc);
+              digraph.next(arc);
+            }
+            {
+              digraph.firstIn(arc, node);
+              digraph.nextIn(arc);
+            }
+            {
+              digraph.firstOut(arc, node);
+              digraph.nextOut(arc);
+            }
+          }
+
+          {
+            checkConcept<GraphItemIt<_Digraph, typename _Digraph::Arc>,
+              typename _Digraph::ArcIt >();
+            checkConcept<GraphItemIt<_Digraph, typename _Digraph::Node>,
+              typename _Digraph::NodeIt >();
+            checkConcept<GraphIncIt<_Digraph, typename _Digraph::Arc,
+              typename _Digraph::Node, 'i'>, typename _Digraph::InArcIt>();
+            checkConcept<GraphIncIt<_Digraph, typename _Digraph::Arc,
+              typename _Digraph::Node, 'o'>, typename _Digraph::OutArcIt>();
+
+            typename _Digraph::Node n;
+            const typename _Digraph::InArcIt iait(INVALID);
+            const typename _Digraph::OutArcIt oait(INVALID);
+            n = digraph.baseNode(iait);
+            n = digraph.runningNode(iait);
+            n = digraph.baseNode(oait);
+            n = digraph.runningNode(oait);
+            ::lemon::ignore_unused_variable_warning(n);
+          }
+        }
+
+        const _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for iterable undirected graphs.
+    ///
+    /// This class describes the interface of iterable undirected
+    /// graphs. It extends \ref IterableDigraphComponent with the core
+    /// iterable interface of undirected graphs.
+    /// This concept is part of the Graph concept.
+    template <typename BAS = BaseGraphComponent>
+    class IterableGraphComponent : public IterableDigraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::Arc Arc;
+      typedef typename Base::Edge Edge;
+
+
+      typedef IterableGraphComponent Graph;
+
+      /// \name Base Iteration
+      ///
+      /// This interface provides functions for iteration on edges.
+      ///
+      /// @{
+
+      using IterableDigraphComponent<Base>::first;
+      using IterableDigraphComponent<Base>::next;
+
+      /// \brief Return the first edge.
+      ///
+      /// This function gives back the first edge in the iteration order.
+      void first(Edge&) const {}
+
+      /// \brief Return the next edge.
+      ///
+      /// This function gives back the next edge in the iteration order.
+      void next(Edge&) const {}
+
+      /// \brief Return the first edge incident to the given node.
+      ///
+      /// This function gives back the first edge incident to the given
+      /// node. The bool parameter gives back the direction for which the
+      /// source node of the directed arc representing the edge is the
+      /// given node.
+      void firstInc(Edge&, bool&, const Node&) const {}
+
+      /// \brief Gives back the next of the edges from the
+      /// given node.
+      ///
+      /// This function gives back the next edge incident to the given
+      /// node. The bool parameter should be used as \c firstInc() use it.
+      void nextInc(Edge&, bool&) const {}
+
+      using IterableDigraphComponent<Base>::baseNode;
+      using IterableDigraphComponent<Base>::runningNode;
+
+      /// @}
+
+      /// \name Class Based Iteration
+      ///
+      /// This interface provides iterator classes for edges.
+      ///
+      /// @{
+
+      /// \brief This iterator goes through each edge.
+      ///
+      /// This iterator goes through each edge.
+      typedef GraphItemIt<Graph, Edge> EdgeIt;
+
+      /// \brief This iterator goes trough the incident edges of a
+      /// node.
+      ///
+      /// This iterator goes trough the incident edges of a certain
+      /// node of a graph.
+      typedef GraphIncIt<Graph, Edge, Node, 'e'> IncEdgeIt;
+
+      /// \brief The base node of the iterator.
+      ///
+      /// This function gives back the base node of the iterator.
+      Node baseNode(const IncEdgeIt&) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// This function gives back the running node of the iterator.
+      Node runningNode(const IncEdgeIt&) const { return INVALID; }
+
+      /// @}
+
+      template <typename _Graph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<IterableDigraphComponent<Base>, _Graph>();
+
+          {
+            typename _Graph::Node node(INVALID);
+            typename _Graph::Edge edge(INVALID);
+            bool dir;
+            {
+              graph.first(edge);
+              graph.next(edge);
+            }
+            {
+              graph.firstInc(edge, dir, node);
+              graph.nextInc(edge, dir);
+            }
+
+          }
+
+          {
+            checkConcept<GraphItemIt<_Graph, typename _Graph::Edge>,
+              typename _Graph::EdgeIt >();
+            checkConcept<GraphIncIt<_Graph, typename _Graph::Edge,
+              typename _Graph::Node, 'e'>, typename _Graph::IncEdgeIt>();
+
+            typename _Graph::Node n;
+            const typename _Graph::IncEdgeIt ieit(INVALID);
+            n = graph.baseNode(ieit);
+            n = graph.runningNode(ieit);
+          }
+        }
+
+        const _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for iterable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of iterable undirected
+    /// bipartite graphs. It extends \ref IterableGraphComponent with
+    /// the core iterable interface of undirected bipartite graphs.
+    /// This concept is part of the BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class IterableBpGraphComponent : public IterableGraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+      typedef typename Base::Arc Arc;
+      typedef typename Base::Edge Edge;
+
+      typedef IterableBpGraphComponent BpGraph;
+
+      using IterableGraphComponent<BAS>::first;
+      using IterableGraphComponent<BAS>::next;
+
+      /// \name Base Iteration
+      ///
+      /// This interface provides functions for iteration on red and blue nodes.
+      ///
+      /// @{
+
+      /// \brief Return the first red node.
+      ///
+      /// This function gives back the first red node in the iteration order.
+      void first(RedNode&) const {}
+
+      /// \brief Return the next red node.
+      ///
+      /// This function gives back the next red node in the iteration order.
+      void next(RedNode&) const {}
+
+      /// \brief Return the first blue node.
+      ///
+      /// This function gives back the first blue node in the iteration order.
+      void first(BlueNode&) const {}
+
+      /// \brief Return the next blue node.
+      ///
+      /// This function gives back the next blue node in the iteration order.
+      void next(BlueNode&) const {}
+
+
+      /// @}
+
+      /// \name Class Based Iteration
+      ///
+      /// This interface provides iterator classes for red and blue nodes.
+      ///
+      /// @{
+
+      /// \brief This iterator goes through each red node.
+      ///
+      /// This iterator goes through each red node.
+      typedef GraphItemIt<BpGraph, RedNode> RedNodeIt;
+
+      /// \brief This iterator goes through each blue node.
+      ///
+      /// This iterator goes through each blue node.
+      typedef GraphItemIt<BpGraph, BlueNode> BlueNodeIt;
+
+      /// @}
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<IterableGraphComponent<Base>, _BpGraph>();
+
+          typename _BpGraph::RedNode rn(INVALID);
+          bpgraph.first(rn);
+          bpgraph.next(rn);
+          typename _BpGraph::BlueNode bn(INVALID);
+          bpgraph.first(bn);
+          bpgraph.next(bn);
+
+          checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::RedNode>,
+            typename _BpGraph::RedNodeIt>();
+          checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::BlueNode>,
+            typename _BpGraph::BlueNodeIt>();
+        }
+
+        const _BpGraph& bpgraph;
+      };
+    };
+
+    /// \brief Skeleton class for alterable directed graphs.
+    ///
+    /// This class describes the interface of alterable directed
+    /// graphs. It extends \ref BaseDigraphComponent with the alteration
+    /// notifier interface. It implements
+    /// an observer-notifier pattern for each digraph item. More
+    /// obsevers can be registered into the notifier and whenever an
+    /// alteration occured in the digraph all the observers will be
+    /// notified about it.
+    template <typename BAS = BaseDigraphComponent>
+    class AlterableDigraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::Arc Arc;
+
+
+      /// Node alteration notifier class.
+      typedef AlterationNotifier<AlterableDigraphComponent, Node>
+      NodeNotifier;
+      /// Arc alteration notifier class.
+      typedef AlterationNotifier<AlterableDigraphComponent, Arc>
+      ArcNotifier;
+
+      mutable NodeNotifier node_notifier;
+      mutable ArcNotifier arc_notifier;
+
+      /// \brief Return the node alteration notifier.
+      ///
+      /// This function gives back the node alteration notifier.
+      NodeNotifier& notifier(Node) const {
+        return node_notifier;
+      }
+
+      /// \brief Return the arc alteration notifier.
+      ///
+      /// This function gives back the arc alteration notifier.
+      ArcNotifier& notifier(Arc) const {
+        return arc_notifier;
+      }
+
+      template <typename _Digraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _Digraph>();
+          typename _Digraph::NodeNotifier& nn
+            = digraph.notifier(typename _Digraph::Node());
+
+          typename _Digraph::ArcNotifier& en
+            = digraph.notifier(typename _Digraph::Arc());
+
+          ::lemon::ignore_unused_variable_warning(nn);
+          ::lemon::ignore_unused_variable_warning(en);
+        }
+
+        const _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for alterable undirected graphs.
+    ///
+    /// This class describes the interface of alterable undirected
+    /// graphs. It extends \ref AlterableDigraphComponent with the alteration
+    /// notifier interface of undirected graphs. It implements
+    /// an observer-notifier pattern for the edges. More
+    /// obsevers can be registered into the notifier and whenever an
+    /// alteration occured in the graph all the observers will be
+    /// notified about it.
+    template <typename BAS = BaseGraphComponent>
+    class AlterableGraphComponent : public AlterableDigraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef AlterableDigraphComponent<Base> Parent;
+      typedef typename Base::Edge Edge;
+
+
+      /// Edge alteration notifier class.
+      typedef AlterationNotifier<AlterableGraphComponent, Edge>
+      EdgeNotifier;
+
+      mutable EdgeNotifier edge_notifier;
+
+      using Parent::notifier;
+
+      /// \brief Return the edge alteration notifier.
+      ///
+      /// This function gives back the edge alteration notifier.
+      EdgeNotifier& notifier(Edge) const {
+        return edge_notifier;
+      }
+
+      template <typename _Graph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<AlterableDigraphComponent<Base>, _Graph>();
+          typename _Graph::EdgeNotifier& uen
+            = graph.notifier(typename _Graph::Edge());
+          ::lemon::ignore_unused_variable_warning(uen);
+        }
+
+        const _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for alterable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of alterable undirected
+    /// bipartite graphs. It extends \ref AlterableGraphComponent with
+    /// the alteration notifier interface of bipartite graphs. It
+    /// implements an observer-notifier pattern for the red and blue
+    /// nodes. More obsevers can be registered into the notifier and
+    /// whenever an alteration occured in the graph all the observers
+    /// will be notified about it.
+    template <typename BAS = BaseBpGraphComponent>
+    class AlterableBpGraphComponent : public AlterableGraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef AlterableGraphComponent<Base> Parent;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+
+
+      /// Red node alteration notifier class.
+      typedef AlterationNotifier<AlterableBpGraphComponent, RedNode>
+      RedNodeNotifier;
+
+      /// Blue node alteration notifier class.
+      typedef AlterationNotifier<AlterableBpGraphComponent, BlueNode>
+      BlueNodeNotifier;
+
+      mutable RedNodeNotifier red_node_notifier;
+      mutable BlueNodeNotifier blue_node_notifier;
+
+      using Parent::notifier;
+
+      /// \brief Return the red node alteration notifier.
+      ///
+      /// This function gives back the red node alteration notifier.
+      RedNodeNotifier& notifier(RedNode) const {
+        return red_node_notifier;
+      }
+
+      /// \brief Return the blue node alteration notifier.
+      ///
+      /// This function gives back the blue node alteration notifier.
+      BlueNodeNotifier& notifier(BlueNode) const {
+        return blue_node_notifier;
+      }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<AlterableGraphComponent<Base>, _BpGraph>();
+          typename _BpGraph::RedNodeNotifier& rnn
+            = bpgraph.notifier(typename _BpGraph::RedNode());
+          typename _BpGraph::BlueNodeNotifier& bnn
+            = bpgraph.notifier(typename _BpGraph::BlueNode());
+          ::lemon::ignore_unused_variable_warning(rnn);
+          ::lemon::ignore_unused_variable_warning(bnn);
+        }
+
+        const _BpGraph& bpgraph;
+      };
+    };
+
+    /// \brief Concept class for standard graph maps.
+    ///
+    /// This class describes the concept of standard graph maps, i.e.
+    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
+    /// graph types, which can be used for associating data to graph items.
+    /// The standard graph maps must conform to the ReferenceMap concept.
+    template <typename GR, typename K, typename V>
+    class GraphMap : public ReferenceMap<K, V, V&, const V&> {
+      typedef ReferenceMap<K, V, V&, const V&> Parent;
+
+    public:
+
+      /// The key type of the map.
+      typedef K Key;
+      /// The value type of the map.
+      typedef V Value;
+      /// The reference type of the map.
+      typedef Value& Reference;
+      /// The const reference type of the map.
+      typedef const Value& ConstReference;
+
+      // The reference map tag.
+      typedef True ReferenceMapTag;
+
+      /// \brief Construct a new map.
+      ///
+      /// Construct a new map for the graph.
+      explicit GraphMap(const GR&) {}
+      /// \brief Construct a new map with default value.
+      ///
+      /// Construct a new map for the graph and initalize the values.
+      GraphMap(const GR&, const Value&) {}
+
+    private:
+      /// \brief Copy constructor.
+      ///
+      /// Copy Constructor.
+      GraphMap(const GraphMap&) : Parent() {}
+
+      /// \brief Assignment operator.
+      ///
+      /// Assignment operator. It does not mofify the underlying graph,
+      /// it just iterates on the current item set and set the  map
+      /// with the value returned by the assigned map.
+      template <typename CMap>
+      GraphMap& operator=(const CMap&) {
+        checkConcept<ReadMap<Key, Value>, CMap>();
+        return *this;
+      }
+
+    public:
+      template<typename _Map>
+      struct Constraints {
+        void constraints() {
+          checkConcept
+            <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
+          _Map m1(g);
+          _Map m2(g,t);
+
+          // Copy constructor
+          // _Map m3(m);
+
+          // Assignment operator
+          // ReadMap<Key, Value> cmap;
+          // m3 = cmap;
+
+          ::lemon::ignore_unused_variable_warning(m1);
+          ::lemon::ignore_unused_variable_warning(m2);
+          // ::lemon::ignore_unused_variable_warning(m3);
+        }
+
+        const _Map &m;
+        const GR &g;
+        const typename GraphMap::Value &t;
+        Constraints() {}
+      };
+
+    };
+
+    /// \brief Skeleton class for mappable directed graphs.
+    ///
+    /// This class describes the interface of mappable directed graphs.
+    /// It extends \ref BaseDigraphComponent with the standard digraph
+    /// map classes, namely \c NodeMap and \c ArcMap.
+    /// This concept is part of the Digraph concept.
+    template <typename BAS = BaseDigraphComponent>
+    class MappableDigraphComponent : public BAS  {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::Arc Arc;
+
+      typedef MappableDigraphComponent Digraph;
+
+      /// \brief Standard graph map for the nodes.
+      ///
+      /// Standard graph map for the nodes.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class NodeMap : public GraphMap<MappableDigraphComponent, Node, V> {
+        typedef GraphMap<MappableDigraphComponent, Node, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the digraph.
+        explicit NodeMap(const MappableDigraphComponent& digraph)
+          : Parent(digraph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the digraph and initalize the values.
+        NodeMap(const MappableDigraphComponent& digraph, const V& value)
+          : Parent(digraph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        NodeMap(const NodeMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        NodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+      /// \brief Standard graph map for the arcs.
+      ///
+      /// Standard graph map for the arcs.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class ArcMap : public GraphMap<MappableDigraphComponent, Arc, V> {
+        typedef GraphMap<MappableDigraphComponent, Arc, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the digraph.
+        explicit ArcMap(const MappableDigraphComponent& digraph)
+          : Parent(digraph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the digraph and initalize the values.
+        ArcMap(const MappableDigraphComponent& digraph, const V& value)
+          : Parent(digraph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        ArcMap(const ArcMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        ArcMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Arc, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+
+      template <typename _Digraph>
+      struct Constraints {
+
+        struct Dummy {
+          int value;
+          Dummy() : value(0) {}
+          Dummy(int _v) : value(_v) {}
+        };
+
+        void constraints() {
+          checkConcept<Base, _Digraph>();
+          { // int map test
+            typedef typename _Digraph::template NodeMap<int> IntNodeMap;
+            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, int>,
+              IntNodeMap >();
+          } { // bool map test
+            typedef typename _Digraph::template NodeMap<bool> BoolNodeMap;
+            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, bool>,
+              BoolNodeMap >();
+          } { // Dummy map test
+            typedef typename _Digraph::template NodeMap<Dummy> DummyNodeMap;
+            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, Dummy>,
+              DummyNodeMap >();
+          }
+
+          { // int map test
+            typedef typename _Digraph::template ArcMap<int> IntArcMap;
+            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, int>,
+              IntArcMap >();
+          } { // bool map test
+            typedef typename _Digraph::template ArcMap<bool> BoolArcMap;
+            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, bool>,
+              BoolArcMap >();
+          } { // Dummy map test
+            typedef typename _Digraph::template ArcMap<Dummy> DummyArcMap;
+            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, Dummy>,
+              DummyArcMap >();
+          }
+        }
+
+        const _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for mappable undirected graphs.
+    ///
+    /// This class describes the interface of mappable undirected graphs.
+    /// It extends \ref MappableDigraphComponent with the standard graph
+    /// map class for edges (\c EdgeMap).
+    /// This concept is part of the Graph concept.
+    template <typename BAS = BaseGraphComponent>
+    class MappableGraphComponent : public MappableDigraphComponent<BAS>  {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Edge Edge;
+
+      typedef MappableGraphComponent Graph;
+
+      /// \brief Standard graph map for the edges.
+      ///
+      /// Standard graph map for the edges.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class EdgeMap : public GraphMap<MappableGraphComponent, Edge, V> {
+        typedef GraphMap<MappableGraphComponent, Edge, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the graph.
+        explicit EdgeMap(const MappableGraphComponent& graph)
+          : Parent(graph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the graph and initalize the values.
+        EdgeMap(const MappableGraphComponent& graph, const V& value)
+          : Parent(graph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        EdgeMap(const EdgeMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        EdgeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Edge, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+
+      template <typename _Graph>
+      struct Constraints {
+
+        struct Dummy {
+          int value;
+          Dummy() : value(0) {}
+          Dummy(int _v) : value(_v) {}
+        };
+
+        void constraints() {
+          checkConcept<MappableDigraphComponent<Base>, _Graph>();
+
+          { // int map test
+            typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
+            checkConcept<GraphMap<_Graph, typename _Graph::Edge, int>,
+              IntEdgeMap >();
+          } { // bool map test
+            typedef typename _Graph::template EdgeMap<bool> BoolEdgeMap;
+            checkConcept<GraphMap<_Graph, typename _Graph::Edge, bool>,
+              BoolEdgeMap >();
+          } { // Dummy map test
+            typedef typename _Graph::template EdgeMap<Dummy> DummyEdgeMap;
+            checkConcept<GraphMap<_Graph, typename _Graph::Edge, Dummy>,
+              DummyEdgeMap >();
+          }
+        }
+
+        const _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for mappable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of mappable undirected
+    /// bipartite graphs.  It extends \ref MappableGraphComponent with
+    /// the standard graph map class for red and blue nodes (\c
+    /// RedNodeMap and BlueNodeMap). This concept is part of the
+    /// BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class MappableBpGraphComponent : public MappableGraphComponent<BAS>  {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+
+      typedef MappableBpGraphComponent BpGraph;
+
+      /// \brief Standard graph map for the red nodes.
+      ///
+      /// Standard graph map for the red nodes.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class RedNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> {
+        typedef GraphMap<MappableBpGraphComponent, Node, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the graph.
+        explicit RedNodeMap(const MappableBpGraphComponent& graph)
+          : Parent(graph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the graph and initalize the values.
+        RedNodeMap(const MappableBpGraphComponent& graph, const V& value)
+          : Parent(graph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        RedNodeMap(const RedNodeMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        RedNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+      /// \brief Standard graph map for the blue nodes.
+      ///
+      /// Standard graph map for the blue nodes.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class BlueNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> {
+        typedef GraphMap<MappableBpGraphComponent, Node, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the graph.
+        explicit BlueNodeMap(const MappableBpGraphComponent& graph)
+          : Parent(graph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the graph and initalize the values.
+        BlueNodeMap(const MappableBpGraphComponent& graph, const V& value)
+          : Parent(graph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        BlueNodeMap(const BlueNodeMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        BlueNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+
+      template <typename _BpGraph>
+      struct Constraints {
+
+        struct Dummy {
+          int value;
+          Dummy() : value(0) {}
+          Dummy(int _v) : value(_v) {}
+        };
+
+        void constraints() {
+          checkConcept<MappableGraphComponent<Base>, _BpGraph>();
+
+          { // int map test
+            typedef typename _BpGraph::template RedNodeMap<int>
+              IntRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, int>,
+              IntRedNodeMap >();
+          } { // bool map test
+            typedef typename _BpGraph::template RedNodeMap<bool>
+              BoolRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, bool>,
+              BoolRedNodeMap >();
+          } { // Dummy map test
+            typedef typename _BpGraph::template RedNodeMap<Dummy>
+              DummyRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, Dummy>,
+              DummyRedNodeMap >();
+          }
+
+          { // int map test
+            typedef typename _BpGraph::template BlueNodeMap<int>
+              IntBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, int>,
+              IntBlueNodeMap >();
+          } { // bool map test
+            typedef typename _BpGraph::template BlueNodeMap<bool>
+              BoolBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, bool>,
+              BoolBlueNodeMap >();
+          } { // Dummy map test
+            typedef typename _BpGraph::template BlueNodeMap<Dummy>
+              DummyBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, Dummy>,
+              DummyBlueNodeMap >();
+          }
+        }
+
+        const _BpGraph& bpgraph;
+      };
+    };
+
+    /// \brief Skeleton class for extendable directed graphs.
+    ///
+    /// This class describes the interface of extendable directed graphs.
+    /// It extends \ref BaseDigraphComponent with functions for adding
+    /// nodes and arcs to the digraph.
+    /// This concept requires \ref AlterableDigraphComponent.
+    template <typename BAS = BaseDigraphComponent>
+    class ExtendableDigraphComponent : public BAS {
+    public:
+      typedef BAS Base;
+
+      typedef typename Base::Node Node;
+      typedef typename Base::Arc Arc;
+
+      /// \brief Add a new node to the digraph.
+      ///
+      /// This function adds a new node to the digraph.
+      Node addNode() {
+        return INVALID;
+      }
+
+      /// \brief Add a new arc connecting the given two nodes.
+      ///
+      /// This function adds a new arc connecting the given two nodes
+      /// of the digraph.
+      Arc addArc(const Node&, const Node&) {
+        return INVALID;
+      }
+
+      template <typename _Digraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _Digraph>();
+          typename _Digraph::Node node_a, node_b;
+          node_a = digraph.addNode();
+          node_b = digraph.addNode();
+          typename _Digraph::Arc arc;
+          arc = digraph.addArc(node_a, node_b);
+        }
+
+        _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for extendable undirected graphs.
+    ///
+    /// This class describes the interface of extendable undirected graphs.
+    /// It extends \ref BaseGraphComponent with functions for adding
+    /// nodes and edges to the graph.
+    /// This concept requires \ref AlterableGraphComponent.
+    template <typename BAS = BaseGraphComponent>
+    class ExtendableGraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::Edge Edge;
+
+      /// \brief Add a new node to the digraph.
+      ///
+      /// This function adds a new node to the digraph.
+      Node addNode() {
+        return INVALID;
+      }
+
+      /// \brief Add a new edge connecting the given two nodes.
+      ///
+      /// This function adds a new edge connecting the given two nodes
+      /// of the graph.
+      Edge addEdge(const Node&, const Node&) {
+        return INVALID;
+      }
+
+      template <typename _Graph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _Graph>();
+          typename _Graph::Node node_a, node_b;
+          node_a = graph.addNode();
+          node_b = graph.addNode();
+          typename _Graph::Edge edge;
+          edge = graph.addEdge(node_a, node_b);
+        }
+
+        _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for extendable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of extendable undirected
+    /// bipartite graphs. It extends \ref BaseGraphComponent with
+    /// functions for adding nodes and edges to the graph. This
+    /// concept requires \ref AlterableBpGraphComponent.
+    template <typename BAS = BaseBpGraphComponent>
+    class ExtendableBpGraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+      typedef typename Base::Edge Edge;
+
+      /// \brief Add a new red node to the digraph.
+      ///
+      /// This function adds a red new node to the digraph.
+      RedNode addRedNode() {
+        return INVALID;
+      }
+
+      /// \brief Add a new blue node to the digraph.
+      ///
+      /// This function adds a blue new node to the digraph.
+      BlueNode addBlueNode() {
+        return INVALID;
+      }
+
+      /// \brief Add a new edge connecting the given two nodes.
+      ///
+      /// This function adds a new edge connecting the given two nodes
+      /// of the graph. The first node has to be a red node, and the
+      /// second one a blue node.
+      Edge addEdge(const RedNode&, const BlueNode&) {
+        return INVALID;
+      }
+      Edge addEdge(const BlueNode&, const RedNode&) {
+        return INVALID;
+      }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _BpGraph>();
+          typename _BpGraph::RedNode red_node;
+          typename _BpGraph::BlueNode blue_node;
+          red_node = bpgraph.addRedNode();
+          blue_node = bpgraph.addBlueNode();
+          typename _BpGraph::Edge edge;
+          edge = bpgraph.addEdge(red_node, blue_node);
+          edge = bpgraph.addEdge(blue_node, red_node);
+        }
+
+        _BpGraph& bpgraph;
+      };
+    };
+
+    /// \brief Skeleton class for erasable directed graphs.
+    ///
+    /// This class describes the interface of erasable directed graphs.
+    /// It extends \ref BaseDigraphComponent with functions for removing
+    /// nodes and arcs from the digraph.
+    /// This concept requires \ref AlterableDigraphComponent.
+    template <typename BAS = BaseDigraphComponent>
+    class ErasableDigraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::Arc Arc;
+
+      /// \brief Erase a node from the digraph.
+      ///
+      /// This function erases the given node from the digraph and all arcs
+      /// connected to the node.
+      void erase(const Node&) {}
+
+      /// \brief Erase an arc from the digraph.
+      ///
+      /// This function erases the given arc from the digraph.
+      void erase(const Arc&) {}
+
+      template <typename _Digraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _Digraph>();
+          const typename _Digraph::Node node(INVALID);
+          digraph.erase(node);
+          const typename _Digraph::Arc arc(INVALID);
+          digraph.erase(arc);
+        }
+
+        _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for erasable undirected graphs.
+    ///
+    /// This class describes the interface of erasable undirected graphs.
+    /// It extends \ref BaseGraphComponent with functions for removing
+    /// nodes and edges from the graph.
+    /// This concept requires \ref AlterableGraphComponent.
+    template <typename BAS = BaseGraphComponent>
+    class ErasableGraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::Edge Edge;
+
+      /// \brief Erase a node from the graph.
+      ///
+      /// This function erases the given node from the graph and all edges
+      /// connected to the node.
+      void erase(const Node&) {}
+
+      /// \brief Erase an edge from the digraph.
+      ///
+      /// This function erases the given edge from the digraph.
+      void erase(const Edge&) {}
+
+      template <typename _Graph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _Graph>();
+          const typename _Graph::Node node(INVALID);
+          graph.erase(node);
+          const typename _Graph::Edge edge(INVALID);
+          graph.erase(edge);
+        }
+
+        _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for erasable undirected graphs.
+    ///
+    /// This class describes the interface of erasable undirected
+    /// bipartite graphs. It extends \ref BaseBpGraphComponent with
+    /// functions for removing nodes and edges from the graph. This
+    /// concept requires \ref AlterableBpGraphComponent.
+    template <typename BAS = BaseBpGraphComponent>
+    class ErasableBpGraphComponent : public ErasableGraphComponent<BAS> {};
+
+    /// \brief Skeleton class for clearable directed graphs.
+    ///
+    /// This class describes the interface of clearable directed graphs.
+    /// It extends \ref BaseDigraphComponent with a function for clearing
+    /// the digraph.
+    /// This concept requires \ref AlterableDigraphComponent.
+    template <typename BAS = BaseDigraphComponent>
+    class ClearableDigraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+
+      /// \brief Erase all nodes and arcs from the digraph.
+      ///
+      /// This function erases all nodes and arcs from the digraph.
+      void clear() {}
+
+      template <typename _Digraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _Digraph>();
+          digraph.clear();
+        }
+
+        _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for clearable undirected graphs.
+    ///
+    /// This class describes the interface of clearable undirected graphs.
+    /// It extends \ref BaseGraphComponent with a function for clearing
+    /// the graph.
+    /// This concept requires \ref AlterableGraphComponent.
+    template <typename BAS = BaseGraphComponent>
+    class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {};
+
+    /// \brief Skeleton class for clearable undirected biparite graphs.
+    ///
+    /// This class describes the interface of clearable undirected
+    /// bipartite graphs. It extends \ref BaseBpGraphComponent with a
+    /// function for clearing the graph.  This concept requires \ref
+    /// AlterableBpGraphComponent.
+    template <typename BAS = BaseBpGraphComponent>
+    class ClearableBpGraphComponent : public ClearableGraphComponent<BAS> {};
+
+  }
+
+}
+
+#endif
diff --git a/lemon/concepts/heap.h b/lemon/concepts/heap.h
new file mode 100644
index 0000000..8c7a251
--- /dev/null
+++ b/lemon/concepts/heap.h
@@ -0,0 +1,324 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_CONCEPTS_HEAP_H
+#define LEMON_CONCEPTS_HEAP_H
+
+///\ingroup concept
+///\file
+///\brief The concept of heaps.
+
+#include <lemon/core.h>
+#include <lemon/concept_check.h>
+
+namespace lemon {
+
+  namespace concepts {
+
+    /// \addtogroup concept
+    /// @{
+
+    /// \brief The heap concept.
+    ///
+    /// This concept class describes the main interface of heaps.
+    /// The various \ref heaps "heap structures" are efficient
+    /// implementations of the abstract data type \e priority \e queue.
+    /// They store items with specified values called \e priorities
+    /// in such a way that finding and removing the item with minimum
+    /// priority are efficient. The basic operations are adding and
+    /// erasing items, changing the priority of an item, etc.
+    ///
+    /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
+    /// Any class that conforms to this concept can be used easily in such
+    /// algorithms.
+    ///
+    /// \tparam PR Type of the priorities of the items.
+    /// \tparam IM A read-writable item map with \c int values, used
+    /// internally to handle the cross references.
+    /// \tparam 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 Heap {
+    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;
+
+      /// \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. The "in heap" state constant.
+        PRE_HEAP = -1,  ///< = -1. The "pre-heap" state constant.
+        POST_HEAP = -2  ///< = -2. The "post-heap" state constant.
+      };
+
+      /// \brief Constructor.
+      ///
+      /// Constructor.
+      /// \param map A map that assigns \c int values to keys of type
+      /// \c Item. It is used internally by the heap implementations to
+      /// handle the cross references. The assigned value must be
+      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
+#ifdef DOXYGEN
+      explicit Heap(ItemIntMap &map) {}
+#else
+      explicit Heap(ItemIntMap&) {}
+#endif
+
+      /// \brief Constructor.
+      ///
+      /// Constructor.
+      /// \param map A map that assigns \c int values to keys of type
+      /// \c Item. It is used internally by the heap implementations to
+      /// handle the cross references. The assigned value must be
+      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
+      /// \param comp The function object used for comparing the priorities.
+#ifdef DOXYGEN
+      explicit Heap(ItemIntMap &map, const CMP &comp) {}
+#else
+      explicit Heap(ItemIntMap&, const CMP&) {}
+#endif
+
+      /// \brief The number of items stored in the heap.
+      ///
+      /// This function returns the number of items stored in the heap.
+      int size() const { return 0; }
+
+      /// \brief Check if the heap is empty.
+      ///
+      /// This function returns \c true if the heap is empty.
+      bool empty() const { return false; }
+
+      /// \brief Make the heap empty.
+      ///
+      /// This functon makes the heap empty.
+      /// It does not change the cross reference map. If you want to reuse
+      /// a heap that is not surely empty, you should first clear it and
+      /// then you should set the cross reference map to \c PRE_HEAP
+      /// for each item.
+      void clear() {}
+
+      /// \brief Insert an item into the heap with the given priority.
+      ///
+      /// This function inserts the given item into the heap with the
+      /// given priority.
+      /// \param i The item to insert.
+      /// \param p The priority of the item.
+      /// \pre \e i must not be stored in the heap.
+#ifdef DOXYGEN
+      void push(const Item &i, const Prio &p) {}
+#else
+      void push(const Item&, const Prio&) {}
+#endif
+
+      /// \brief Return the item having minimum priority.
+      ///
+      /// This function returns the item having minimum priority.
+      /// \pre The heap must be non-empty.
+      Item top() const { return Item(); }
+
+      /// \brief The minimum priority.
+      ///
+      /// This function returns the minimum priority.
+      /// \pre The heap must be non-empty.
+      Prio prio() const { return Prio(); }
+
+      /// \brief Remove the item having minimum priority.
+      ///
+      /// This function removes the item having minimum priority.
+      /// \pre The heap must be non-empty.
+      void pop() {}
+
+      /// \brief Remove the given item from the heap.
+      ///
+      /// This function removes the given item from the heap if it is
+      /// already stored.
+      /// \param i The item to delete.
+      /// \pre \e i must be in the heap.
+#ifdef DOXYGEN
+      void erase(const Item &i) {}
+#else
+      void erase(const Item&) {}
+#endif
+
+      /// \brief The priority of the given item.
+      ///
+      /// This function returns the priority of the given item.
+      /// \param i The item.
+      /// \pre \e i must be in the heap.
+#ifdef DOXYGEN
+      Prio operator[](const Item &i) const {}
+#else
+      Prio operator[](const Item&) const { return Prio(); }
+#endif
+
+      /// \brief Set the priority of an item or insert it, if it is
+      /// not stored in the heap.
+      ///
+      /// This method sets the priority of the given item if it is
+      /// already stored in the heap. Otherwise it inserts the given
+      /// item into the heap with the given priority.
+      ///
+      /// \param i The item.
+      /// \param p The priority.
+#ifdef DOXYGEN
+      void set(const Item &i, const Prio &p) {}
+#else
+      void set(const Item&, const Prio&) {}
+#endif
+
+      /// \brief Decrease the priority of an item to the given value.
+      ///
+      /// This function decreases the priority of an item to the given value.
+      /// \param i The item.
+      /// \param p The priority.
+      /// \pre \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.
+      ///
+      /// 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.
+#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.
+      ///
+      /// 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.
+#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.
+      ///
+      /// This function sets the state of the given item in the heap.
+      /// It can be used to manually clear the heap when it is important
+      /// to achive better time complexity.
+      /// \param i The item.
+      /// \param st The state. It should not be \c IN_HEAP.
+#ifdef DOXYGEN
+      void state(const Item& i, State st) {}
+#else
+      void state(const Item&, State) {}
+#endif
+
+
+      template <typename _Heap>
+      struct Constraints {
+      public:
+        void constraints() {
+          typedef typename _Heap::Item OwnItem;
+          typedef typename _Heap::Prio OwnPrio;
+          typedef typename _Heap::State OwnState;
+
+          Item item;
+          Prio prio;
+          item=Item();
+          prio=Prio();
+          ::lemon::ignore_unused_variable_warning(item);
+          ::lemon::ignore_unused_variable_warning(prio);
+
+          OwnItem own_item;
+          OwnPrio own_prio;
+          OwnState own_state;
+          own_item=Item();
+          own_prio=Prio();
+          ::lemon::ignore_unused_variable_warning(own_item);
+          ::lemon::ignore_unused_variable_warning(own_prio);
+          ::lemon::ignore_unused_variable_warning(own_state);
+
+          _Heap heap1(map);
+          _Heap heap2 = heap1;
+          ::lemon::ignore_unused_variable_warning(heap1);
+          ::lemon::ignore_unused_variable_warning(heap2);
+
+          int s = heap.size();
+          ::lemon::ignore_unused_variable_warning(s);
+          bool e = heap.empty();
+          ::lemon::ignore_unused_variable_warning(e);
+
+          prio = heap.prio();
+          item = heap.top();
+          prio = heap[item];
+          own_prio = heap.prio();
+          own_item = heap.top();
+          own_prio = heap[own_item];
+
+          heap.push(item, prio);
+          heap.push(own_item, own_prio);
+          heap.pop();
+
+          heap.set(item, prio);
+          heap.decrease(item, prio);
+          heap.increase(item, prio);
+          heap.set(own_item, own_prio);
+          heap.decrease(own_item, own_prio);
+          heap.increase(own_item, own_prio);
+
+          heap.erase(item);
+          heap.erase(own_item);
+          heap.clear();
+
+          own_state = heap.state(own_item);
+          heap.state(own_item, own_state);
+
+          own_state = _Heap::PRE_HEAP;
+          own_state = _Heap::IN_HEAP;
+          own_state = _Heap::POST_HEAP;
+        }
+
+        _Heap& heap;
+        ItemIntMap& map;
+        Constraints() {}
+      };
+    };
+
+    /// @}
+  } // namespace lemon
+}
+#endif
diff --git a/lemon/concepts/maps.h b/lemon/concepts/maps.h
new file mode 100644
index 0000000..88b66b5
--- /dev/null
+++ b/lemon/concepts/maps.h
@@ -0,0 +1,223 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_CONCEPTS_MAPS_H
+#define LEMON_CONCEPTS_MAPS_H
+
+#include <lemon/core.h>
+#include <lemon/concept_check.h>
+
+///\ingroup map_concepts
+///\file
+///\brief The concept of maps.
+
+namespace lemon {
+
+  namespace concepts {
+
+    /// \addtogroup map_concepts
+    /// @{
+
+    /// Readable map concept
+
+    /// Readable map concept.
+    ///
+    template<typename K, typename T>
+    class ReadMap
+    {
+    public:
+      /// The key type of the map.
+      typedef K Key;
+      /// \brief The value type of the map.
+      /// (The type of objects associated with the keys).
+      typedef T Value;
+
+      /// Returns the value associated with the given key.
+      Value operator[](const Key &) const {
+        return *(static_cast<Value *>(0)+1);
+      }
+
+      template<typename _ReadMap>
+      struct Constraints {
+        void constraints() {
+          Value val = m[key];
+          val = m[key];
+          typename _ReadMap::Value own_val = m[own_key];
+          own_val = m[own_key];
+
+          ::lemon::ignore_unused_variable_warning(key);
+          ::lemon::ignore_unused_variable_warning(val);
+          ::lemon::ignore_unused_variable_warning(own_key);
+          ::lemon::ignore_unused_variable_warning(own_val);
+        }
+        const Key& key;
+        const typename _ReadMap::Key& own_key;
+        const _ReadMap& m;
+        Constraints() {}
+      };
+
+    };
+
+
+    /// Writable map concept
+
+    /// Writable map concept.
+    ///
+    template<typename K, typename T>
+    class WriteMap
+    {
+    public:
+      /// The key type of the map.
+      typedef K Key;
+      /// \brief The value type of the map.
+      /// (The type of objects associated with the keys).
+      typedef T Value;
+
+      /// Sets the value associated with the given key.
+      void set(const Key &, const Value &) {}
+
+      /// Default constructor.
+      WriteMap() {}
+
+      template <typename _WriteMap>
+      struct Constraints {
+        void constraints() {
+          m.set(key, val);
+          m.set(own_key, own_val);
+
+          ::lemon::ignore_unused_variable_warning(key);
+          ::lemon::ignore_unused_variable_warning(val);
+          ::lemon::ignore_unused_variable_warning(own_key);
+          ::lemon::ignore_unused_variable_warning(own_val);
+        }
+        const Key& key;
+        const Value& val;
+        const typename _WriteMap::Key& own_key;
+        const typename _WriteMap::Value& own_val;
+        _WriteMap& m;
+        Constraints() {}
+      };
+    };
+
+    /// Read/writable map concept
+
+    /// Read/writable map concept.
+    ///
+    template<typename K, typename T>
+    class ReadWriteMap : public ReadMap<K,T>,
+                         public WriteMap<K,T>
+    {
+    public:
+      /// The key type of the map.
+      typedef K Key;
+      /// \brief The value type of the map.
+      /// (The type of objects associated with the keys).
+      typedef T Value;
+
+      /// Returns the value associated with the given key.
+      Value operator[](const Key &) const {
+        Value *r = 0;
+        return *r;
+      }
+
+      /// Sets the value associated with the given key.
+      void set(const Key &, const Value &) {}
+
+      template<typename _ReadWriteMap>
+      struct Constraints {
+        void constraints() {
+          checkConcept<ReadMap<K, T>, _ReadWriteMap >();
+          checkConcept<WriteMap<K, T>, _ReadWriteMap >();
+        }
+      };
+    };
+
+
+    /// Dereferable map concept
+
+    /// Dereferable map concept.
+    ///
+    template<typename K, typename T, typename R, typename CR>
+    class ReferenceMap : public ReadWriteMap<K,T>
+    {
+    public:
+      /// Tag for reference maps.
+      typedef True ReferenceMapTag;
+      /// The key type of the map.
+      typedef K Key;
+      /// \brief The value type of the map.
+      /// (The type of objects associated with the keys).
+      typedef T Value;
+      /// The reference type of the map.
+      typedef R Reference;
+      /// The const reference type of the map.
+      typedef CR ConstReference;
+
+    public:
+
+      /// Returns a reference to the value associated with the given key.
+      Reference operator[](const Key &) {
+        Value *r = 0;
+        return *r;
+      }
+
+      /// Returns a const reference to the value associated with the given key.
+      ConstReference operator[](const Key &) const {
+        Value *r = 0;
+        return *r;
+      }
+
+      /// Sets the value associated with the given key.
+      void set(const Key &k,const Value &t) { operator[](k)=t; }
+
+      template<typename _ReferenceMap>
+      struct Constraints {
+        typename enable_if<typename _ReferenceMap::ReferenceMapTag, void>::type
+        constraints() {
+          checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
+          ref = m[key];
+          m[key] = val;
+          m[key] = ref;
+          m[key] = cref;
+          own_ref = m[own_key];
+          m[own_key] = own_val;
+          m[own_key] = own_ref;
+          m[own_key] = own_cref;
+          m[key] = m[own_key];
+          m[own_key] = m[key];
+        }
+        const Key& key;
+        Value& val;
+        Reference ref;
+        ConstReference cref;
+        const typename _ReferenceMap::Key& own_key;
+        typename _ReferenceMap::Value& own_val;
+        typename _ReferenceMap::Reference own_ref;
+        typename _ReferenceMap::ConstReference own_cref;
+        _ReferenceMap& m;
+        Constraints() {}
+      };
+    };
+
+    // @}
+
+  } //namespace concepts
+
+} //namespace lemon
+
+#endif
diff --git a/lemon/concepts/path.h b/lemon/concepts/path.h
new file mode 100644
index 0000000..18e4b01
--- /dev/null
+++ b/lemon/concepts/path.h
@@ -0,0 +1,312 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup concept
+///\file
+///\brief The concept of paths
+///
+
+#ifndef LEMON_CONCEPTS_PATH_H
+#define LEMON_CONCEPTS_PATH_H
+
+#include <lemon/core.h>
+#include <lemon/concept_check.h>
+
+namespace lemon {
+  namespace concepts {
+
+    /// \addtogroup concept
+    /// @{
+
+    /// \brief A skeleton structure for representing directed paths in
+    /// a digraph.
+    ///
+    /// 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.
+    template <typename GR>
+    class Path {
+    public:
+
+      /// Type of the underlying digraph.
+      typedef GR Digraph;
+      /// Arc type of the underlying digraph.
+      typedef typename Digraph::Arc Arc;
+
+      class ArcIt;
+
+      /// \brief Default constructor
+      Path() {}
+
+      /// \brief Template copy constructor
+      template <typename CPath>
+      Path(const CPath& cpath) {}
+
+      /// \brief Template assigment operator
+      template <typename CPath>
+      Path& operator=(const CPath& cpath) {
+        ::lemon::ignore_unused_variable_warning(cpath);
+        return *this;
+      }
+
+      /// Length of the path, i.e. the number of arcs on the path.
+      int length() const { return 0;}
+
+      /// Returns whether the path is empty.
+      bool empty() const { return true;}
+
+      /// Resets the path to an empty path.
+      void clear() {}
+
+      /// \brief LEMON style iterator for enumerating the arcs of a path.
+      ///
+      /// LEMON style iterator class for enumerating the arcs of a path.
+      class ArcIt {
+      public:
+        /// Default constructor
+        ArcIt() {}
+        /// Invalid constructor
+        ArcIt(Invalid) {}
+        /// Sets the iterator to the first arc of the given path
+        ArcIt(const Path &) {}
+
+        /// Conversion to \c Arc
+        operator Arc() const { return INVALID; }
+
+        /// Next arc
+        ArcIt& operator++() {return *this;}
+
+        /// Comparison operator
+        bool operator==(const ArcIt&) const {return true;}
+        /// Comparison operator
+        bool operator!=(const ArcIt&) const {return true;}
+        /// Comparison operator
+        bool operator<(const ArcIt&) const {return false;}
+
+      };
+
+      template <typename _Path>
+      struct Constraints {
+        void constraints() {
+          Path<Digraph> pc;
+          _Path p, pp(pc);
+          int l = p.length();
+          int e = p.empty();
+          p.clear();
+
+          p = pc;
+
+          typename _Path::ArcIt id, ii(INVALID), i(p);
+
+          ++i;
+          typename Digraph::Arc ed = i;
+
+          e = (i == ii);
+          e = (i != ii);
+          e = (i < ii);
+
+          ::lemon::ignore_unused_variable_warning(l);
+          ::lemon::ignore_unused_variable_warning(pp);
+          ::lemon::ignore_unused_variable_warning(e);
+          ::lemon::ignore_unused_variable_warning(id);
+          ::lemon::ignore_unused_variable_warning(ii);
+          ::lemon::ignore_unused_variable_warning(ed);
+        }
+      };
+
+    };
+
+    namespace _path_bits {
+
+      template <typename _Digraph, typename _Path, typename RevPathTag = void>
+      struct PathDumperConstraints {
+        void constraints() {
+          int l = p.length();
+          int e = p.empty();
+
+          typename _Path::ArcIt id, i(p);
+
+          ++i;
+          typename _Digraph::Arc ed = i;
+
+          e = (i == INVALID);
+          e = (i != INVALID);
+
+          ::lemon::ignore_unused_variable_warning(l);
+          ::lemon::ignore_unused_variable_warning(e);
+          ::lemon::ignore_unused_variable_warning(id);
+          ::lemon::ignore_unused_variable_warning(ed);
+        }
+        _Path& p;
+        PathDumperConstraints() {}
+      };
+
+      template <typename _Digraph, typename _Path>
+      struct PathDumperConstraints<
+        _Digraph, _Path,
+        typename enable_if<typename _Path::RevPathTag, void>::type
+      > {
+        void constraints() {
+          int l = p.length();
+          int e = p.empty();
+
+          typename _Path::RevArcIt id, i(p);
+
+          ++i;
+          typename _Digraph::Arc ed = i;
+
+          e = (i == INVALID);
+          e = (i != INVALID);
+
+          ::lemon::ignore_unused_variable_warning(l);
+          ::lemon::ignore_unused_variable_warning(e);
+          ::lemon::ignore_unused_variable_warning(id);
+          ::lemon::ignore_unused_variable_warning(ed);
+        }
+        _Path& p;
+        PathDumperConstraints() {}
+      };
+
+    }
+
+
+    /// \brief A skeleton structure for path dumpers.
+    ///
+    /// A skeleton structure for path dumpers. The path dumpers are
+    /// 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 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.
+    template <typename GR>
+    class PathDumper {
+    public:
+
+      /// Type of the underlying digraph.
+      typedef GR Digraph;
+      /// Arc type of the underlying digraph.
+      typedef typename Digraph::Arc Arc;
+
+      /// Length of the path, i.e. the number of arcs on the path.
+      int length() const { return 0;}
+
+      /// Returns whether the path is empty.
+      bool empty() const { return true;}
+
+      /// \brief Forward or reverse dumping
+      ///
+      /// 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 enumerating the arcs of a path.
+      ///
+      /// LEMON style iterator class for enumerating the arcs of a path.
+      class ArcIt {
+      public:
+        /// Default constructor
+        ArcIt() {}
+        /// Invalid constructor
+        ArcIt(Invalid) {}
+        /// Sets the iterator to the first arc of the given path
+        ArcIt(const PathDumper&) {}
+
+        /// Conversion to \c Arc
+        operator Arc() const { return INVALID; }
+
+        /// Next arc
+        ArcIt& operator++() {return *this;}
+
+        /// Comparison operator
+        bool operator==(const ArcIt&) const {return true;}
+        /// Comparison operator
+        bool operator!=(const ArcIt&) const {return true;}
+        /// Comparison operator
+        bool operator<(const ArcIt&) const {return false;}
+
+      };
+
+      /// \brief LEMON style iterator for enumerating the arcs of a path
+      /// in reverse direction.
+      ///
+      /// LEMON style iterator class for enumerating the arcs of a path
+      /// in reverse direction.
+      class RevArcIt {
+      public:
+        /// Default constructor
+        RevArcIt() {}
+        /// Invalid constructor
+        RevArcIt(Invalid) {}
+        /// Sets the iterator to the last arc of the given path
+        RevArcIt(const PathDumper &) {}
+
+        /// Conversion to \c Arc
+        operator Arc() const { return INVALID; }
+
+        /// Next arc
+        RevArcIt& operator++() {return *this;}
+
+        /// Comparison operator
+        bool operator==(const RevArcIt&) const {return true;}
+        /// Comparison operator
+        bool operator!=(const RevArcIt&) const {return true;}
+        /// Comparison operator
+        bool operator<(const RevArcIt&) const {return false;}
+
+      };
+
+      template <typename _Path>
+      struct Constraints {
+        void constraints() {
+          function_requires<_path_bits::
+            PathDumperConstraints<Digraph, _Path> >();
+        }
+      };
+
+    };
+
+
+    ///@}
+  }
+
+} // namespace lemon
+
+#endif
diff --git a/lemon/config.h.in b/lemon/config.h.in
new file mode 100644
index 0000000..37d8c04
--- /dev/null
+++ b/lemon/config.h.in
@@ -0,0 +1,22 @@
+#define LEMON_VERSION "@PROJECT_VERSION@"
+#cmakedefine LEMON_HAVE_LONG_LONG 1
+
+#cmakedefine LEMON_HAVE_LP 1
+#cmakedefine LEMON_HAVE_MIP 1
+#cmakedefine LEMON_HAVE_GLPK 1
+#cmakedefine LEMON_HAVE_CPLEX 1
+#cmakedefine LEMON_HAVE_SOPLEX 1
+#cmakedefine LEMON_HAVE_CLP 1
+#cmakedefine LEMON_HAVE_CBC 1
+
+#define _LEMON_CPLEX 1
+#define _LEMON_CLP 2
+#define _LEMON_GLPK 3
+#define _LEMON_SOPLEX 4
+#define _LEMON_CBC 5
+
+#cmakedefine LEMON_DEFAULT_LP _LEMON_ at LEMON_DEFAULT_LP@
+#cmakedefine LEMON_DEFAULT_MIP _LEMON_ at LEMON_DEFAULT_MIP@
+
+#cmakedefine LEMON_USE_PTHREAD 1
+#cmakedefine LEMON_USE_WIN32_THREADS 1
diff --git a/lemon/connectivity.h b/lemon/connectivity.h
new file mode 100644
index 0000000..6bd85a1
--- /dev/null
+++ b/lemon/connectivity.h
@@ -0,0 +1,1688 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_CONNECTIVITY_H
+#define LEMON_CONNECTIVITY_H
+
+#include <lemon/dfs.h>
+#include <lemon/bfs.h>
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/adaptors.h>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concept_check.h>
+
+#include <stack>
+#include <functional>
+
+/// \ingroup graph_properties
+/// \file
+/// \brief Connectivity algorithms
+///
+/// Connectivity algorithms
+
+namespace lemon {
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is connected.
+  ///
+  /// This function checks whether the given undirected graph is connected,
+  /// i.e. there is a path between any two nodes in the graph.
+  ///
+  /// \return \c true if the graph is connected.
+  /// \note By definition, the empty graph is connected.
+  ///
+  /// \see countConnectedComponents(), connectedComponents()
+  /// \see stronglyConnected()
+  template <typename Graph>
+  bool connected(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+    if (NodeIt(graph) == INVALID) return true;
+    Dfs<Graph> dfs(graph);
+    dfs.run(NodeIt(graph));
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Count the number of connected components of an undirected graph
+  ///
+  /// This function counts the number of connected components of the given
+  /// undirected graph.
+  ///
+  /// The connected components are the classes of an equivalence relation
+  /// on the nodes of an undirected graph. Two nodes are in the same class
+  /// if they are connected with a path.
+  ///
+  /// \return The number of connected components.
+  /// \note By definition, the empty graph consists
+  /// of zero connected components.
+  ///
+  /// \see connected(), connectedComponents()
+  template <typename Graph>
+  int countConnectedComponents(const Graph &graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Arc Arc;
+
+    typedef NullMap<Node, Arc> PredMap;
+    typedef NullMap<Node, int> DistMap;
+
+    int compNum = 0;
+    typename Bfs<Graph>::
+      template SetPredMap<PredMap>::
+      template SetDistMap<DistMap>::
+      Create bfs(graph);
+
+    PredMap predMap;
+    bfs.predMap(predMap);
+
+    DistMap distMap;
+    bfs.distMap(distMap);
+
+    bfs.init();
+    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      if (!bfs.reached(n)) {
+        bfs.addSource(n);
+        bfs.start();
+        ++compNum;
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the connected components of an undirected graph
+  ///
+  /// This function finds the connected components of the given undirected
+  /// graph.
+  ///
+  /// The connected components are the classes of an equivalence relation
+  /// on the nodes of an undirected graph. Two nodes are in the same class
+  /// if they are connected with a path.
+  ///
+  /// \image html connected_components.png
+  /// \image latex connected_components.eps "Connected components" width=\textwidth
+  ///
+  /// \param graph The undirected graph.
+  /// \retval compMap A writable node map. The values will be set from 0 to
+  /// the number of the connected components minus one. Each value of the map
+  /// will be set exactly once, and the values of a certain component will be
+  /// set continuously.
+  /// \return The number of connected components.
+  /// \note By definition, the empty graph consists
+  /// of zero connected components.
+  ///
+  /// \see connected(), countConnectedComponents()
+  template <class Graph, class NodeMap>
+  int connectedComponents(const Graph &graph, NodeMap &compMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Arc Arc;
+    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
+
+    typedef NullMap<Node, Arc> PredMap;
+    typedef NullMap<Node, int> DistMap;
+
+    int compNum = 0;
+    typename Bfs<Graph>::
+      template SetPredMap<PredMap>::
+      template SetDistMap<DistMap>::
+      Create bfs(graph);
+
+    PredMap predMap;
+    bfs.predMap(predMap);
+
+    DistMap distMap;
+    bfs.distMap(distMap);
+
+    bfs.init();
+    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      if(!bfs.reached(n)) {
+        bfs.addSource(n);
+        while (!bfs.emptyQueue()) {
+          compMap.set(bfs.nextNode(), compNum);
+          bfs.processNextNode();
+        }
+        ++compNum;
+      }
+    }
+    return compNum;
+  }
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph, typename Iterator >
+    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      LeaveOrderVisitor(Iterator it) : _it(it) {}
+
+      void leave(const Node& node) {
+        *(_it++) = node;
+      }
+
+    private:
+      Iterator _it;
+    };
+
+    template <typename Digraph, typename Map>
+    struct FillMapVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Map::Value Value;
+
+      FillMapVisitor(Map& map, Value& value)
+        : _map(map), _value(value) {}
+
+      void reach(const Node& node) {
+        _map.set(node, _value);
+      }
+    private:
+      Map& _map;
+      Value& _value;
+    };
+
+    template <typename Digraph, typename ArcMap>
+    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+
+      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
+                                      ArcMap& cutMap,
+                                      int& cutNum)
+        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
+          _compMap(digraph, -1), _num(-1) {
+      }
+
+      void start(const Node&) {
+        ++_num;
+      }
+
+      void reach(const Node& node) {
+        _compMap.set(node, _num);
+      }
+
+      void examine(const Arc& arc) {
+         if (_compMap[_digraph.source(arc)] !=
+             _compMap[_digraph.target(arc)]) {
+           _cutMap.set(arc, true);
+           ++_cutNum;
+         }
+      }
+    private:
+      const Digraph& _digraph;
+      ArcMap& _cutMap;
+      int& _cutNum;
+
+      typename Digraph::template NodeMap<int> _compMap;
+      int _num;
+    };
+
+  }
+
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether a directed graph is strongly connected.
+  ///
+  /// This function checks whether the given directed graph is strongly
+  /// connected, i.e. any two nodes of the digraph are
+  /// connected with directed paths in both direction.
+  ///
+  /// \return \c true if the digraph is strongly connected.
+  /// \note By definition, the empty digraph is strongly connected.
+  ///
+  /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
+  /// \see connected()
+  template <typename Digraph>
+  bool stronglyConnected(const Digraph& digraph) {
+    checkConcept<concepts::Digraph, Digraph>();
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+
+    typename Digraph::Node source = NodeIt(digraph);
+    if (source == INVALID) return true;
+
+    using namespace _connectivity_bits;
+
+    typedef DfsVisitor<Digraph> Visitor;
+    Visitor visitor;
+
+    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
+    dfs.init();
+    dfs.addSource(source);
+    dfs.start();
+
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        return false;
+      }
+    }
+
+    typedef ReverseDigraph<const Digraph> RDigraph;
+    typedef typename RDigraph::NodeIt RNodeIt;
+    RDigraph rdigraph(digraph);
+
+    typedef DfsVisitor<RDigraph> RVisitor;
+    RVisitor rvisitor;
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
+    rdfs.init();
+    rdfs.addSource(source);
+    rdfs.start();
+
+    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
+      if (!rdfs.reached(it)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Count the number of strongly connected components of a
+  /// directed graph
+  ///
+  /// This function counts the number of strongly connected components of
+  /// the given directed graph.
+  ///
+  /// The strongly connected components are the classes of an
+  /// equivalence relation on the nodes of a digraph. Two nodes are in
+  /// the same class if they are connected with directed paths in both
+  /// direction.
+  ///
+  /// \return The number of strongly connected components.
+  /// \note By definition, the empty digraph has zero
+  /// strongly connected components.
+  ///
+  /// \see stronglyConnected(), stronglyConnectedComponents()
+  template <typename Digraph>
+  int countStronglyConnectedComponents(const Digraph& digraph) {
+    checkConcept<concepts::Digraph, Digraph>();
+
+    using namespace _connectivity_bits;
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::ArcIt ArcIt;
+
+    typedef std::vector<Node> Container;
+    typedef typename Container::iterator Iterator;
+
+    Container nodes(countNodes(digraph));
+    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
+    Visitor visitor(nodes.begin());
+
+    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+
+    typedef typename Container::reverse_iterator RIterator;
+    typedef ReverseDigraph<const Digraph> RDigraph;
+
+    RDigraph rdigraph(digraph);
+
+    typedef DfsVisitor<Digraph> RVisitor;
+    RVisitor rvisitor;
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
+
+    int compNum = 0;
+
+    rdfs.init();
+    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
+      if (!rdfs.reached(*it)) {
+        rdfs.addSource(*it);
+        rdfs.start();
+        ++compNum;
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the strongly connected components of a directed graph
+  ///
+  /// This function finds the strongly connected components of the given
+  /// directed graph. In addition, the numbering of the components will
+  /// satisfy that there is no arc going from a higher numbered component
+  /// to a lower one (i.e. it provides a topological order of the components).
+  ///
+  /// The strongly connected components are the classes of an
+  /// equivalence relation on the nodes of a digraph. Two nodes are in
+  /// the same class if they are connected with directed paths in both
+  /// direction.
+  ///
+  /// \image html strongly_connected_components.png
+  /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
+  ///
+  /// \param digraph The digraph.
+  /// \retval compMap A writable node map. The values will be set from 0 to
+  /// the number of the strongly connected components minus one. Each value
+  /// of the map will be set exactly once, and the values of a certain
+  /// component will be set continuously.
+  /// \return The number of strongly connected components.
+  /// \note By definition, the empty digraph has zero
+  /// strongly connected components.
+  ///
+  /// \see stronglyConnected(), countStronglyConnectedComponents()
+  template <typename Digraph, typename NodeMap>
+  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
+    checkConcept<concepts::Digraph, Digraph>();
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef std::vector<Node> Container;
+    typedef typename Container::iterator Iterator;
+
+    Container nodes(countNodes(digraph));
+    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
+    Visitor visitor(nodes.begin());
+
+    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+
+    typedef typename Container::reverse_iterator RIterator;
+    typedef ReverseDigraph<const Digraph> RDigraph;
+
+    RDigraph rdigraph(digraph);
+
+    int compNum = 0;
+
+    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
+    RVisitor rvisitor(compMap, compNum);
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
+
+    rdfs.init();
+    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
+      if (!rdfs.reached(*it)) {
+        rdfs.addSource(*it);
+        rdfs.start();
+        ++compNum;
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the cut arcs of the strongly connected components.
+  ///
+  /// This function finds the cut arcs of the strongly connected components
+  /// of the given digraph.
+  ///
+  /// The strongly connected components are the classes of an
+  /// equivalence relation on the nodes of a digraph. Two nodes are in
+  /// the same class if they are connected with directed paths in both
+  /// direction.
+  /// The strongly connected components are separated by the cut arcs.
+  ///
+  /// \param digraph The digraph.
+  /// \retval cutMap A writable arc map. The values will be set to \c true
+  /// for the cut arcs (exactly once for each cut arc), and will not be
+  /// changed for other arcs.
+  /// \return The number of cut arcs.
+  ///
+  /// \see stronglyConnected(), stronglyConnectedComponents()
+  template <typename Digraph, typename ArcMap>
+  int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
+    checkConcept<concepts::Digraph, Digraph>();
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::NodeIt NodeIt;
+    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef std::vector<Node> Container;
+    typedef typename Container::iterator Iterator;
+
+    Container nodes(countNodes(digraph));
+    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
+    Visitor visitor(nodes.begin());
+
+    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+
+    typedef typename Container::reverse_iterator RIterator;
+    typedef ReverseDigraph<const Digraph> RDigraph;
+
+    RDigraph rdigraph(digraph);
+
+    int cutNum = 0;
+
+    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
+    RVisitor rvisitor(rdigraph, cutMap, cutNum);
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
+
+    rdfs.init();
+    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
+      if (!rdfs.reached(*it)) {
+        rdfs.addSource(*it);
+        rdfs.start();
+      }
+    }
+    return cutNum;
+  }
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph>
+    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
+        : _graph(graph), _compNum(compNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), _graph.source(edge));
+      }
+
+      void examine(const Arc& edge) {
+        if (_graph.source(edge) == _graph.target(edge) &&
+            _graph.direction(edge)) {
+          ++_compNum;
+          return;
+        }
+        if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
+          return;
+        }
+        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
+          ++_compNum;
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      int& _compNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Node> _predMap;
+      int _num;
+    };
+
+    template <typename Digraph, typename ArcMap>
+    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      BiNodeConnectedComponentsVisitor(const Digraph& graph,
+                                       ArcMap& compMap, int &compNum)
+        : _graph(graph), _compMap(compMap), _compNum(compNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void discover(const Arc& edge) {
+        Node target = _graph.target(edge);
+        _predMap.set(target, edge);
+        _edgeStack.push(edge);
+      }
+
+      void examine(const Arc& edge) {
+        Node source = _graph.source(edge);
+        Node target = _graph.target(edge);
+        if (source == target && _graph.direction(edge)) {
+          _compMap.set(edge, _compNum);
+          ++_compNum;
+          return;
+        }
+        if (_numMap[target] < _numMap[source]) {
+          if (_predMap[source] != _graph.oppositeArc(edge)) {
+            _edgeStack.push(edge);
+          }
+        }
+        if (_predMap[source] != INVALID &&
+            target == _graph.source(_predMap[source])) {
+          return;
+        }
+        if (_retMap[source] > _numMap[target]) {
+          _retMap.set(source, _numMap[target]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        Node source = _graph.source(edge);
+        Node target = _graph.target(edge);
+        if (_retMap[source] > _retMap[target]) {
+          _retMap.set(source, _retMap[target]);
+        }
+        if (_numMap[source] <= _retMap[target]) {
+          while (_edgeStack.top() != edge) {
+            _compMap.set(_edgeStack.top(), _compNum);
+            _edgeStack.pop();
+          }
+          _compMap.set(edge, _compNum);
+          _edgeStack.pop();
+          ++_compNum;
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      ArcMap& _compMap;
+      int& _compNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Arc> _predMap;
+      std::stack<Edge> _edgeStack;
+      int _num;
+    };
+
+
+    template <typename Digraph, typename NodeMap>
+    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
+                                     int& cutNum)
+        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+        rootCut = false;
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), _graph.source(edge));
+      }
+
+      void examine(const Arc& edge) {
+        if (_graph.source(edge) == _graph.target(edge) &&
+            _graph.direction(edge)) {
+          if (!_cutMap[_graph.source(edge)]) {
+            _cutMap.set(_graph.source(edge), true);
+            ++_cutNum;
+          }
+          return;
+        }
+        if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
+        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
+          if (_predMap[_graph.source(edge)] != INVALID) {
+            if (!_cutMap[_graph.source(edge)]) {
+              _cutMap.set(_graph.source(edge), true);
+              ++_cutNum;
+            }
+          } else if (rootCut) {
+            if (!_cutMap[_graph.source(edge)]) {
+              _cutMap.set(_graph.source(edge), true);
+              ++_cutNum;
+            }
+          } else {
+            rootCut = true;
+          }
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      NodeMap& _cutMap;
+      int& _cutNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Node> _predMap;
+      std::stack<Edge> _edgeStack;
+      int _num;
+      bool rootCut;
+    };
+
+  }
+
+  template <typename Graph>
+  int countBiNodeConnectedComponents(const Graph& graph);
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is bi-node-connected.
+  ///
+  /// This function checks whether the given undirected graph is
+  /// bi-node-connected, i.e. a connected graph without articulation
+  /// node.
+  ///
+  /// \return \c true if the graph bi-node-connected.
+  ///
+  /// \note By definition,
+  /// \li a graph consisting of zero or one node is bi-node-connected,
+  /// \li a graph consisting of two isolated nodes
+  /// is \e not bi-node-connected and
+  /// \li a graph consisting of two nodes connected by an edge
+  /// is bi-node-connected.
+  ///
+  /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
+  template <typename Graph>
+  bool biNodeConnected(const Graph& graph) {
+    bool hasNonIsolated = false, hasIsolated = false;
+    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      if (typename Graph::OutArcIt(graph, n) == INVALID) {
+        if (hasIsolated || hasNonIsolated) {
+          return false;
+        } else {
+          hasIsolated = true;
+        }
+      } else {
+        if (hasIsolated) {
+          return false;
+        } else {
+          hasNonIsolated = true;
+        }
+      }
+    }
+    return countBiNodeConnectedComponents(graph) <= 1;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Count the number of bi-node-connected components of an
+  /// undirected graph.
+  ///
+  /// This function counts the number of bi-node-connected components of
+  /// the given undirected graph.
+  ///
+  /// The bi-node-connected components are the classes of an equivalence
+  /// relation on the edges of a undirected graph. Two edges are in the
+  /// same class if they are on same circle.
+  ///
+  /// \return The number of bi-node-connected components.
+  ///
+  /// \see biNodeConnected(), biNodeConnectedComponents()
+  template <typename Graph>
+  int countBiNodeConnectedComponents(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+
+    using namespace _connectivity_bits;
+
+    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
+
+    int compNum = 0;
+    Visitor visitor(graph, compNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bi-node-connected components of an undirected graph.
+  ///
+  /// This function finds the bi-node-connected components of the given
+  /// undirected graph.
+  ///
+  /// The bi-node-connected components are the classes of an equivalence
+  /// relation on the edges of a undirected graph. Two edges are in the
+  /// same class if they are on same circle.
+  ///
+  /// \image html node_biconnected_components.png
+  /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
+  ///
+  /// \param graph The undirected graph.
+  /// \retval compMap A writable edge map. The values will be set from 0
+  /// to the number of the bi-node-connected components minus one. Each
+  /// value of the map will be set exactly once, and the values of a
+  /// certain component will be set continuously.
+  /// \return The number of bi-node-connected components.
+  ///
+  /// \see biNodeConnected(), countBiNodeConnectedComponents()
+  template <typename Graph, typename EdgeMap>
+  int biNodeConnectedComponents(const Graph& graph,
+                                EdgeMap& compMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Edge Edge;
+    checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
+
+    int compNum = 0;
+    Visitor visitor(graph, compMap, compNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bi-node-connected cut nodes in an undirected graph.
+  ///
+  /// This function finds the bi-node-connected cut nodes in the given
+  /// undirected graph.
+  ///
+  /// The bi-node-connected components are the classes of an equivalence
+  /// relation on the edges of a undirected graph. Two edges are in the
+  /// same class if they are on same circle.
+  /// The bi-node-connected components are separted by the cut nodes of
+  /// the components.
+  ///
+  /// \param graph The undirected graph.
+  /// \retval cutMap A writable node map. The values will be set to
+  /// \c true for the nodes that separate two or more components
+  /// (exactly once for each cut node), and will not be changed for
+  /// other nodes.
+  /// \return The number of the cut nodes.
+  ///
+  /// \see biNodeConnected(), biNodeConnectedComponents()
+  template <typename Graph, typename NodeMap>
+  int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
+
+    int cutNum = 0;
+    Visitor visitor(graph, cutMap, cutNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return cutNum;
+  }
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph>
+    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
+        : _graph(graph), _compNum(compNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void leave(const Node& node) {
+        if (_numMap[node] <= _retMap[node]) {
+          ++_compNum;
+        }
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), edge);
+      }
+
+      void examine(const Arc& edge) {
+        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
+          return;
+        }
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      int& _compNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Arc> _predMap;
+      int _num;
+    };
+
+    template <typename Digraph, typename NodeMap>
+    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      BiEdgeConnectedComponentsVisitor(const Digraph& graph,
+                                       NodeMap& compMap, int &compNum)
+        : _graph(graph), _compMap(compMap), _compNum(compNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        _nodeStack.push(node);
+        ++_num;
+      }
+
+      void leave(const Node& node) {
+        if (_numMap[node] <= _retMap[node]) {
+          while (_nodeStack.top() != node) {
+            _compMap.set(_nodeStack.top(), _compNum);
+            _nodeStack.pop();
+          }
+          _compMap.set(node, _compNum);
+          _nodeStack.pop();
+          ++_compNum;
+        }
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), edge);
+      }
+
+      void examine(const Arc& edge) {
+        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
+          return;
+        }
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      NodeMap& _compMap;
+      int& _compNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Arc> _predMap;
+      std::stack<Node> _nodeStack;
+      int _num;
+    };
+
+
+    template <typename Digraph, typename ArcMap>
+    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
+                                     ArcMap& cutMap, int &cutNum)
+        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap[node] = INVALID;
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void leave(const Node& node) {
+        if (_numMap[node] <= _retMap[node]) {
+          if (_predMap[node] != INVALID) {
+            _cutMap.set(_predMap[node], true);
+            ++_cutNum;
+          }
+        }
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), edge);
+      }
+
+      void examine(const Arc& edge) {
+        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
+          return;
+        }
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      ArcMap& _cutMap;
+      int& _cutNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Arc> _predMap;
+      int _num;
+    };
+  }
+
+  template <typename Graph>
+  int countBiEdgeConnectedComponents(const Graph& graph);
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is bi-edge-connected.
+  ///
+  /// This function checks whether the given undirected graph is
+  /// bi-edge-connected, i.e. any two nodes are connected with at least
+  /// two edge-disjoint paths.
+  ///
+  /// \return \c true if the graph is bi-edge-connected.
+  /// \note By definition, the empty graph is bi-edge-connected.
+  ///
+  /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
+  template <typename Graph>
+  bool biEdgeConnected(const Graph& graph) {
+    return countBiEdgeConnectedComponents(graph) <= 1;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Count the number of bi-edge-connected components of an
+  /// undirected graph.
+  ///
+  /// This function counts the number of bi-edge-connected components of
+  /// the given undirected graph.
+  ///
+  /// The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes of an undirected graph. Two nodes are in the
+  /// same class if they are connected with at least two edge-disjoint
+  /// paths.
+  ///
+  /// \return The number of bi-edge-connected components.
+  ///
+  /// \see biEdgeConnected(), biEdgeConnectedComponents()
+  template <typename Graph>
+  int countBiEdgeConnectedComponents(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+
+    using namespace _connectivity_bits;
+
+    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
+
+    int compNum = 0;
+    Visitor visitor(graph, compNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bi-edge-connected components of an undirected graph.
+  ///
+  /// This function finds the bi-edge-connected components of the given
+  /// undirected graph.
+  ///
+  /// The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes of an undirected graph. Two nodes are in the
+  /// same class if they are connected with at least two edge-disjoint
+  /// paths.
+  ///
+  /// \image html edge_biconnected_components.png
+  /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
+  ///
+  /// \param graph The undirected graph.
+  /// \retval compMap A writable node map. The values will be set from 0 to
+  /// the number of the bi-edge-connected components minus one. Each value
+  /// of the map will be set exactly once, and the values of a certain
+  /// component will be set continuously.
+  /// \return The number of bi-edge-connected components.
+  ///
+  /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
+  template <typename Graph, typename NodeMap>
+  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Node Node;
+    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
+
+    int compNum = 0;
+    Visitor visitor(graph, compMap, compNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bi-edge-connected cut edges in an undirected graph.
+  ///
+  /// This function finds the bi-edge-connected cut edges in the given
+  /// undirected graph.
+  ///
+  /// The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes of an undirected graph. Two nodes are in the
+  /// same class if they are connected with at least two edge-disjoint
+  /// paths.
+  /// The bi-edge-connected components are separted by the cut edges of
+  /// the components.
+  ///
+  /// \param graph The undirected graph.
+  /// \retval cutMap A writable edge map. The values will be set to \c true
+  /// for the cut edges (exactly once for each cut edge), and will not be
+  /// changed for other edges.
+  /// \return The number of cut edges.
+  ///
+  /// \see biEdgeConnected(), biEdgeConnectedComponents()
+  template <typename Graph, typename EdgeMap>
+  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Edge Edge;
+    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
+
+    int cutNum = 0;
+    Visitor visitor(graph, cutMap, cutNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return cutNum;
+  }
+
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph, typename IntNodeMap>
+    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc edge;
+
+      TopologicalSortVisitor(IntNodeMap& order, int num)
+        : _order(order), _num(num) {}
+
+      void leave(const Node& node) {
+        _order.set(node, --_num);
+      }
+
+    private:
+      IntNodeMap& _order;
+      int _num;
+    };
+
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether a digraph is DAG.
+  ///
+  /// This function checks whether the given digraph is DAG, i.e.
+  /// \e Directed \e Acyclic \e Graph.
+  /// \return \c true if there is no directed cycle in the digraph.
+  /// \see acyclic()
+  template <typename Digraph>
+  bool dag(const Digraph& digraph) {
+
+    checkConcept<concepts::Digraph, Digraph>();
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+
+    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
+
+    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
+      Create dfs(digraph);
+
+    ProcessedMap processed(digraph);
+    dfs.processedMap(processed);
+
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        while (!dfs.emptyQueue()) {
+          Arc arc = dfs.nextArc();
+          Node target = digraph.target(arc);
+          if (dfs.reached(target) && !processed[target]) {
+            return false;
+          }
+          dfs.processNextArc();
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Sort the nodes of a DAG into topolgical order.
+  ///
+  /// This function sorts the nodes of the given acyclic digraph (DAG)
+  /// into topolgical order.
+  ///
+  /// \param digraph The digraph, which must be DAG.
+  /// \retval order A writable node map. The values will be set from 0 to
+  /// the number of the nodes in the digraph minus one. Each value of the
+  /// map will be set exactly once, and the values will be set descending
+  /// order.
+  ///
+  /// \see dag(), checkedTopologicalSort()
+  template <typename Digraph, typename NodeMap>
+  void topologicalSort(const Digraph& digraph, NodeMap& order) {
+    using namespace _connectivity_bits;
+
+    checkConcept<concepts::Digraph, Digraph>();
+    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+
+    TopologicalSortVisitor<Digraph, NodeMap>
+      visitor(order, countNodes(digraph));
+
+    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
+      dfs(digraph, visitor);
+
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Sort the nodes of a DAG into topolgical order.
+  ///
+  /// This function sorts the nodes of the given acyclic digraph (DAG)
+  /// into topolgical order and also checks whether the given digraph
+  /// is DAG.
+  ///
+  /// \param digraph The digraph.
+  /// \retval order A readable and writable node map. The values will be
+  /// set from 0 to the number of the nodes in the digraph minus one.
+  /// Each value of the map will be set exactly once, and the values will
+  /// be set descending order.
+  /// \return \c false if the digraph is not DAG.
+  ///
+  /// \see dag(), topologicalSort()
+  template <typename Digraph, typename NodeMap>
+  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
+    using namespace _connectivity_bits;
+
+    checkConcept<concepts::Digraph, Digraph>();
+    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
+      NodeMap>();
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      order.set(it, -1);
+    }
+
+    TopologicalSortVisitor<Digraph, NodeMap>
+      visitor(order, countNodes(digraph));
+
+    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
+      dfs(digraph, visitor);
+
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        while (!dfs.emptyQueue()) {
+           Arc arc = dfs.nextArc();
+           Node target = digraph.target(arc);
+           if (dfs.reached(target) && order[target] == -1) {
+             return false;
+           }
+           dfs.processNextArc();
+         }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is acyclic.
+  ///
+  /// This function checks whether the given undirected graph is acyclic.
+  /// \return \c true if there is no cycle in the graph.
+  /// \see dag()
+  template <typename Graph>
+  bool acyclic(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Arc Arc;
+    Dfs<Graph> dfs(graph);
+    dfs.init();
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        while (!dfs.emptyQueue()) {
+          Arc arc = dfs.nextArc();
+          Node source = graph.source(arc);
+          Node target = graph.target(arc);
+          if (dfs.reached(target) &&
+              dfs.predArc(source) != graph.oppositeArc(arc)) {
+            return false;
+          }
+          dfs.processNextArc();
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is tree.
+  ///
+  /// This function checks whether the given undirected graph is tree.
+  /// \return \c true if the graph is acyclic and connected.
+  /// \see acyclic(), connected()
+  template <typename Graph>
+  bool tree(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Arc Arc;
+    if (NodeIt(graph) == INVALID) return true;
+    Dfs<Graph> dfs(graph);
+    dfs.init();
+    dfs.addSource(NodeIt(graph));
+    while (!dfs.emptyQueue()) {
+      Arc arc = dfs.nextArc();
+      Node source = graph.source(arc);
+      Node target = graph.target(arc);
+      if (dfs.reached(target) &&
+          dfs.predArc(source) != graph.oppositeArc(arc)) {
+        return false;
+      }
+      dfs.processNextArc();
+    }
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph>
+    class BipartiteVisitor : public BfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Node Node;
+
+      BipartiteVisitor(const Digraph& graph, bool& bipartite)
+        : _graph(graph), _part(graph), _bipartite(bipartite) {}
+
+      void start(const Node& node) {
+        _part[node] = true;
+      }
+      void discover(const Arc& edge) {
+        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
+      }
+      void examine(const Arc& edge) {
+        _bipartite = _bipartite &&
+          _part[_graph.target(edge)] != _part[_graph.source(edge)];
+      }
+
+    private:
+
+      const Digraph& _graph;
+      typename Digraph::template NodeMap<bool> _part;
+      bool& _bipartite;
+    };
+
+    template <typename Digraph, typename PartMap>
+    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Node Node;
+
+      BipartitePartitionsVisitor(const Digraph& graph,
+                                 PartMap& part, bool& bipartite)
+        : _graph(graph), _part(part), _bipartite(bipartite) {}
+
+      void start(const Node& node) {
+        _part.set(node, true);
+      }
+      void discover(const Arc& edge) {
+        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
+      }
+      void examine(const Arc& edge) {
+        _bipartite = _bipartite &&
+          _part[_graph.target(edge)] != _part[_graph.source(edge)];
+      }
+
+    private:
+
+      const Digraph& _graph;
+      PartMap& _part;
+      bool& _bipartite;
+    };
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is bipartite.
+  ///
+  /// The function checks whether the given undirected graph is bipartite.
+  /// \return \c true if the graph is bipartite.
+  ///
+  /// \see bipartitePartitions()
+  template<typename Graph>
+  bool bipartite(const Graph &graph){
+    using namespace _connectivity_bits;
+
+    checkConcept<concepts::Graph, Graph>();
+
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::ArcIt ArcIt;
+
+    bool bipartite = true;
+
+    BipartiteVisitor<Graph>
+      visitor(graph, bipartite);
+    BfsVisit<Graph, BipartiteVisitor<Graph> >
+      bfs(graph, visitor);
+    bfs.init();
+    for(NodeIt it(graph); it != INVALID; ++it) {
+      if(!bfs.reached(it)){
+        bfs.addSource(it);
+        while (!bfs.emptyQueue()) {
+          bfs.processNextNode();
+          if (!bipartite) return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bipartite partitions of an undirected graph.
+  ///
+  /// This function checks whether the given undirected graph is bipartite
+  /// and gives back the bipartite partitions.
+  ///
+  /// \image html bipartite_partitions.png
+  /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
+  ///
+  /// \param graph The undirected graph.
+  /// \retval partMap A writable node map of \c bool (or convertible) value
+  /// type. The values will be set to \c true for one component and
+  /// \c false for the other one.
+  /// \return \c true if the graph is bipartite, \c false otherwise.
+  ///
+  /// \see bipartite()
+  template<typename Graph, typename NodeMap>
+  bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
+    using namespace _connectivity_bits;
+
+    checkConcept<concepts::Graph, Graph>();
+    checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
+
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::ArcIt ArcIt;
+
+    bool bipartite = true;
+
+    BipartitePartitionsVisitor<Graph, NodeMap>
+      visitor(graph, partMap, bipartite);
+    BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
+      bfs(graph, visitor);
+    bfs.init();
+    for(NodeIt it(graph); it != INVALID; ++it) {
+      if(!bfs.reached(it)){
+        bfs.addSource(it);
+        while (!bfs.emptyQueue()) {
+          bfs.processNextNode();
+          if (!bipartite) return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether the given graph contains no loop arcs/edges.
+  ///
+  /// This function returns \c true if there are no loop arcs/edges in
+  /// the given graph. It works for both directed and undirected graphs.
+  template <typename Graph>
+  bool loopFree(const Graph& graph) {
+    for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
+      if (graph.source(it) == graph.target(it)) return false;
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether the given graph contains no parallel arcs/edges.
+  ///
+  /// This function returns \c true if there are no parallel arcs/edges in
+  /// the given graph. It works for both directed and undirected graphs.
+  template <typename Graph>
+  bool parallelFree(const Graph& graph) {
+    typename Graph::template NodeMap<int> reached(graph, 0);
+    int cnt = 1;
+    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
+        if (reached[graph.target(a)] == cnt) return false;
+        reached[graph.target(a)] = cnt;
+      }
+      ++cnt;
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether the given graph is simple.
+  ///
+  /// This function returns \c true if the given graph is simple, i.e.
+  /// it contains no loop arcs/edges and no parallel arcs/edges.
+  /// The function works for both directed and undirected graphs.
+  /// \see loopFree(), parallelFree()
+  template <typename Graph>
+  bool simpleGraph(const Graph& graph) {
+    typename Graph::template NodeMap<int> reached(graph, 0);
+    int cnt = 1;
+    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      reached[n] = cnt;
+      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
+        if (reached[graph.target(a)] == cnt) return false;
+        reached[graph.target(a)] = cnt;
+      }
+      ++cnt;
+    }
+    return true;
+  }
+
+} //namespace lemon
+
+#endif //LEMON_CONNECTIVITY_H
diff --git a/lemon/core.h b/lemon/core.h
new file mode 100644
index 0000000..507943d
--- /dev/null
+++ b/lemon/core.h
@@ -0,0 +1,2506 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_CORE_H
+#define LEMON_CORE_H
+
+#include <vector>
+#include <algorithm>
+
+#include <lemon/config.h>
+#include <lemon/bits/enable_if.h>
+#include <lemon/bits/traits.h>
+#include <lemon/assert.h>
+
+// Disable the following warnings when compiling with MSVC:
+// C4250: 'class1' : inherits 'class2::member' via dominance
+// C4355: 'this' : used in base member initializer list
+// C4503: 'function' : decorated name length exceeded, name was truncated
+// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
+// C4996: 'function': was declared deprecated
+#ifdef _MSC_VER
+#pragma warning( disable : 4250 4355 4503 4800 4996 )
+#endif
+
+#ifdef __GNUC__
+#define GCC_VERSION (__GNUC__ * 10000                   \
+                     + __GNUC_MINOR__ * 100             \
+                     + __GNUC_PATCHLEVEL__)
+#endif
+
+#if GCC_VERSION >= 40800
+// Needed by the [DI]GRAPH_TYPEDEFS marcos for gcc 4.8
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#endif
+
+///\file
+///\brief LEMON core utilities.
+///
+///This header file contains core utilities for LEMON.
+///It is automatically included by all graph types, therefore it usually
+///do not have to be included directly.
+
+namespace lemon {
+
+  /// \brief Dummy type to make it easier to create invalid iterators.
+  ///
+  /// Dummy type to make it easier to create invalid iterators.
+  /// See \ref INVALID for the usage.
+  struct Invalid {
+  public:
+    bool operator==(Invalid) { return true;  }
+    bool operator!=(Invalid) { return false; }
+    bool operator< (Invalid) { return false; }
+  };
+
+  /// \brief Invalid iterators.
+  ///
+  /// \ref Invalid is a global type that converts to each iterator
+  /// in such a way that the value of the target iterator will be invalid.
+#ifdef LEMON_ONLY_TEMPLATES
+  const Invalid INVALID = Invalid();
+#else
+  extern const Invalid INVALID;
+#endif
+
+  /// \addtogroup gutils
+  /// @{
+
+  ///Create convenience typedefs for the digraph types and iterators
+
+  ///This \c \#define creates convenient type definitions for the following
+  ///types of \c Digraph: \c Node,  \c NodeIt, \c Arc, \c ArcIt, \c InArcIt,
+  ///\c OutArcIt, \c BoolNodeMap, \c IntNodeMap, \c DoubleNodeMap,
+  ///\c BoolArcMap, \c IntArcMap, \c DoubleArcMap.
+  ///
+  ///\note If the graph type is a dependent type, ie. the graph type depend
+  ///on a template parameter, then use \c TEMPLATE_DIGRAPH_TYPEDEFS()
+  ///macro.
+#define DIGRAPH_TYPEDEFS(Digraph)                                       \
+  typedef Digraph::Node Node;                                           \
+  typedef Digraph::NodeIt NodeIt;                                       \
+  typedef Digraph::Arc Arc;                                             \
+  typedef Digraph::ArcIt ArcIt;                                         \
+  typedef Digraph::InArcIt InArcIt;                                     \
+  typedef Digraph::OutArcIt OutArcIt;                                   \
+  typedef Digraph::NodeMap<bool> BoolNodeMap;                           \
+  typedef Digraph::NodeMap<int> IntNodeMap;                             \
+  typedef Digraph::NodeMap<double> DoubleNodeMap;                       \
+  typedef Digraph::ArcMap<bool> BoolArcMap;                             \
+  typedef Digraph::ArcMap<int> IntArcMap;                               \
+  typedef Digraph::ArcMap<double> DoubleArcMap
+
+  ///Create convenience typedefs for the digraph types and iterators
+
+  ///\see DIGRAPH_TYPEDEFS
+  ///
+  ///\note Use this macro, if the graph type is a dependent type,
+  ///ie. the graph type depend on a template parameter.
+#define TEMPLATE_DIGRAPH_TYPEDEFS(Digraph)                              \
+  typedef typename Digraph::Node Node;                                  \
+  typedef typename Digraph::NodeIt NodeIt;                              \
+  typedef typename Digraph::Arc Arc;                                    \
+  typedef typename Digraph::ArcIt ArcIt;                                \
+  typedef typename Digraph::InArcIt InArcIt;                            \
+  typedef typename Digraph::OutArcIt OutArcIt;                          \
+  typedef typename Digraph::template NodeMap<bool> BoolNodeMap;         \
+  typedef typename Digraph::template NodeMap<int> IntNodeMap;           \
+  typedef typename Digraph::template NodeMap<double> DoubleNodeMap;     \
+  typedef typename Digraph::template ArcMap<bool> BoolArcMap;           \
+  typedef typename Digraph::template ArcMap<int> IntArcMap;             \
+  typedef typename Digraph::template ArcMap<double> DoubleArcMap
+
+  ///Create convenience typedefs for the graph types and iterators
+
+  ///This \c \#define creates the same convenient type definitions as defined
+  ///by \ref DIGRAPH_TYPEDEFS(Graph) and six more, namely it creates
+  ///\c Edge, \c EdgeIt, \c IncEdgeIt, \c BoolEdgeMap, \c IntEdgeMap,
+  ///\c DoubleEdgeMap.
+  ///
+  ///\note If the graph type is a dependent type, ie. the graph type depend
+  ///on a template parameter, then use \c TEMPLATE_GRAPH_TYPEDEFS()
+  ///macro.
+#define GRAPH_TYPEDEFS(Graph)                                           \
+  DIGRAPH_TYPEDEFS(Graph);                                              \
+  typedef Graph::Edge Edge;                                             \
+  typedef Graph::EdgeIt EdgeIt;                                         \
+  typedef Graph::IncEdgeIt IncEdgeIt;                                   \
+  typedef Graph::EdgeMap<bool> BoolEdgeMap;                             \
+  typedef Graph::EdgeMap<int> IntEdgeMap;                               \
+  typedef Graph::EdgeMap<double> DoubleEdgeMap
+
+  ///Create convenience typedefs for the graph types and iterators
+
+  ///\see GRAPH_TYPEDEFS
+  ///
+  ///\note Use this macro, if the graph type is a dependent type,
+  ///ie. the graph type depend on a template parameter.
+#define TEMPLATE_GRAPH_TYPEDEFS(Graph)                                  \
+  TEMPLATE_DIGRAPH_TYPEDEFS(Graph);                                     \
+  typedef typename Graph::Edge Edge;                                    \
+  typedef typename Graph::EdgeIt EdgeIt;                                \
+  typedef typename Graph::IncEdgeIt IncEdgeIt;                          \
+  typedef typename Graph::template EdgeMap<bool> BoolEdgeMap;           \
+  typedef typename Graph::template EdgeMap<int> IntEdgeMap;             \
+  typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
+
+  ///Create convenience typedefs for the bipartite graph types and iterators
+
+  ///This \c \#define creates the same convenient type definitions as
+  ///defined by \ref GRAPH_TYPEDEFS(BpGraph) and ten more, namely it
+  ///creates \c RedNode, \c RedNodeIt, \c BoolRedNodeMap,
+  ///\c IntRedNodeMap, \c DoubleRedNodeMap, \c BlueNode, \c BlueNodeIt,
+  ///\c BoolBlueNodeMap, \c IntBlueNodeMap, \c DoubleBlueNodeMap.
+  ///
+  ///\note If the graph type is a dependent type, ie. the graph type depend
+  ///on a template parameter, then use \c TEMPLATE_BPGRAPH_TYPEDEFS()
+  ///macro.
+#define BPGRAPH_TYPEDEFS(BpGraph)                                       \
+  GRAPH_TYPEDEFS(BpGraph);                                              \
+  typedef BpGraph::RedNode RedNode;                                     \
+  typedef BpGraph::RedNodeIt RedNodeIt;                                 \
+  typedef BpGraph::RedNodeMap<bool> BoolRedNodeMap;                     \
+  typedef BpGraph::RedNodeMap<int> IntRedNodeMap;                       \
+  typedef BpGraph::RedNodeMap<double> DoubleRedNodeMap;                 \
+  typedef BpGraph::BlueNode BlueNode;                                   \
+  typedef BpGraph::BlueNodeIt BlueNodeIt;                               \
+  typedef BpGraph::BlueNodeMap<bool> BoolBlueNodeMap;                   \
+  typedef BpGraph::BlueNodeMap<int> IntBlueNodeMap;                     \
+  typedef BpGraph::BlueNodeMap<double> DoubleBlueNodeMap
+
+  ///Create convenience typedefs for the bipartite graph types and iterators
+
+  ///\see BPGRAPH_TYPEDEFS
+  ///
+  ///\note Use this macro, if the graph type is a dependent type,
+  ///ie. the graph type depend on a template parameter.
+#define TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph)                                  \
+  TEMPLATE_GRAPH_TYPEDEFS(BpGraph);                                         \
+  typedef typename BpGraph::RedNode RedNode;                                \
+  typedef typename BpGraph::RedNodeIt RedNodeIt;                            \
+  typedef typename BpGraph::template RedNodeMap<bool> BoolRedNodeMap;       \
+  typedef typename BpGraph::template RedNodeMap<int> IntRedNodeMap;         \
+  typedef typename BpGraph::template RedNodeMap<double> DoubleRedNodeMap;   \
+  typedef typename BpGraph::BlueNode BlueNode;                              \
+  typedef typename BpGraph::BlueNodeIt BlueNodeIt;                          \
+  typedef typename BpGraph::template BlueNodeMap<bool> BoolBlueNodeMap;     \
+  typedef typename BpGraph::template BlueNodeMap<int> IntBlueNodeMap;       \
+  typedef typename BpGraph::template BlueNodeMap<double> DoubleBlueNodeMap
+
+  /// \brief Function to count the items in a graph.
+  ///
+  /// This function counts the items (nodes, arcs etc.) in a graph.
+  /// The complexity of the function is linear because
+  /// it iterates on all of the items.
+  template <typename Graph, typename Item>
+  inline int countItems(const Graph& g) {
+    typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
+    int num = 0;
+    for (ItemIt it(g); it != INVALID; ++it) {
+      ++num;
+    }
+    return num;
+  }
+
+  // Node counting:
+
+  namespace _core_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct CountNodesSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::Node>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountNodesSelector<
+      Graph, typename
+      enable_if<typename Graph::NodeNumTag, void>::type>
+    {
+      static int count(const Graph &g) {
+        return g.nodeNum();
+      }
+    };
+  }
+
+  /// \brief Function to count the nodes in the graph.
+  ///
+  /// This function counts the nodes in the graph.
+  /// The complexity of the function is <em>O</em>(<em>n</em>), but for some
+  /// graph structures it is specialized to run in <em>O</em>(1).
+  ///
+  /// \note If the graph contains a \c nodeNum() member function and a
+  /// \c NodeNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the node set.
+  template <typename Graph>
+  inline int countNodes(const Graph& g) {
+    return _core_bits::CountNodesSelector<Graph>::count(g);
+  }
+
+  namespace _graph_utils_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct CountRedNodesSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::RedNode>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountRedNodesSelector<
+      Graph, typename
+      enable_if<typename Graph::NodeNumTag, void>::type>
+    {
+      static int count(const Graph &g) {
+        return g.redNum();
+      }
+    };
+  }
+
+  /// \brief Function to count the red nodes in the graph.
+  ///
+  /// This function counts the red nodes in the graph.
+  /// The complexity of the function is O(n) but for some
+  /// graph structures it is specialized to run in O(1).
+  ///
+  /// If the graph contains a \e redNum() member function and a
+  /// \e NodeNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the node set.
+  template <typename Graph>
+  inline int countRedNodes(const Graph& g) {
+    return _graph_utils_bits::CountRedNodesSelector<Graph>::count(g);
+  }
+
+  namespace _graph_utils_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct CountBlueNodesSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::BlueNode>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountBlueNodesSelector<
+      Graph, typename
+      enable_if<typename Graph::NodeNumTag, void>::type>
+    {
+      static int count(const Graph &g) {
+        return g.blueNum();
+      }
+    };
+  }
+
+  /// \brief Function to count the blue nodes in the graph.
+  ///
+  /// This function counts the blue nodes in the graph.
+  /// The complexity of the function is O(n) but for some
+  /// graph structures it is specialized to run in O(1).
+  ///
+  /// If the graph contains a \e blueNum() member function and a
+  /// \e NodeNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the node set.
+  template <typename Graph>
+  inline int countBlueNodes(const Graph& g) {
+    return _graph_utils_bits::CountBlueNodesSelector<Graph>::count(g);
+  }
+
+  // Arc counting:
+
+  namespace _core_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct CountArcsSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::Arc>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountArcsSelector<
+      Graph,
+      typename enable_if<typename Graph::ArcNumTag, void>::type>
+    {
+      static int count(const Graph &g) {
+        return g.arcNum();
+      }
+    };
+  }
+
+  /// \brief Function to count the arcs in the graph.
+  ///
+  /// This function counts the arcs in the graph.
+  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
+  /// graph structures it is specialized to run in <em>O</em>(1).
+  ///
+  /// \note If the graph contains a \c arcNum() member function and a
+  /// \c ArcNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the arc set.
+  template <typename Graph>
+  inline int countArcs(const Graph& g) {
+    return _core_bits::CountArcsSelector<Graph>::count(g);
+  }
+
+  // Edge counting:
+
+  namespace _core_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct CountEdgesSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::Edge>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountEdgesSelector<
+      Graph,
+      typename enable_if<typename Graph::EdgeNumTag, void>::type>
+    {
+      static int count(const Graph &g) {
+        return g.edgeNum();
+      }
+    };
+  }
+
+  /// \brief Function to count the edges in the graph.
+  ///
+  /// This function counts the edges in the graph.
+  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
+  /// graph structures it is specialized to run in <em>O</em>(1).
+  ///
+  /// \note If the graph contains a \c edgeNum() member function and a
+  /// \c EdgeNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the edge set.
+  template <typename Graph>
+  inline int countEdges(const Graph& g) {
+    return _core_bits::CountEdgesSelector<Graph>::count(g);
+
+  }
+
+
+  template <typename Graph, typename DegIt>
+  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
+    int num = 0;
+    for (DegIt it(_g, _n); it != INVALID; ++it) {
+      ++num;
+    }
+    return num;
+  }
+
+  /// \brief Function to count the number of the out-arcs from node \c n.
+  ///
+  /// This function counts the number of the out-arcs from node \c n
+  /// in the graph \c g.
+  template <typename Graph>
+  inline int countOutArcs(const Graph& g,  const typename Graph::Node& n) {
+    return countNodeDegree<Graph, typename Graph::OutArcIt>(g, n);
+  }
+
+  /// \brief Function to count the number of the in-arcs to node \c n.
+  ///
+  /// This function counts the number of the in-arcs to node \c n
+  /// in the graph \c g.
+  template <typename Graph>
+  inline int countInArcs(const Graph& g,  const typename Graph::Node& n) {
+    return countNodeDegree<Graph, typename Graph::InArcIt>(g, n);
+  }
+
+  /// \brief Function to count the number of the inc-edges to node \c n.
+  ///
+  /// This function counts the number of the inc-edges to node \c n
+  /// in the undirected graph \c g.
+  template <typename Graph>
+  inline int countIncEdges(const Graph& g,  const typename Graph::Node& n) {
+    return countNodeDegree<Graph, typename Graph::IncEdgeIt>(g, n);
+  }
+
+  namespace _core_bits {
+
+    template <typename Digraph, typename Item, typename RefMap>
+    class MapCopyBase {
+    public:
+      virtual void copy(const Digraph& from, const RefMap& refMap) = 0;
+
+      virtual ~MapCopyBase() {}
+    };
+
+    template <typename Digraph, typename Item, typename RefMap,
+              typename FromMap, typename ToMap>
+    class MapCopy : public MapCopyBase<Digraph, Item, RefMap> {
+    public:
+
+      MapCopy(const FromMap& map, ToMap& tmap)
+        : _map(map), _tmap(tmap) {}
+
+      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
+        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
+        for (ItemIt it(digraph); it != INVALID; ++it) {
+          _tmap.set(refMap[it], _map[it]);
+        }
+      }
+
+    private:
+      const FromMap& _map;
+      ToMap& _tmap;
+    };
+
+    template <typename Digraph, typename Item, typename RefMap, typename It>
+    class ItemCopy : public MapCopyBase<Digraph, Item, RefMap> {
+    public:
+
+      ItemCopy(const Item& item, It& it) : _item(item), _it(it) {}
+
+      virtual void copy(const Digraph&, const RefMap& refMap) {
+        _it = refMap[_item];
+      }
+
+    private:
+      Item _item;
+      It& _it;
+    };
+
+    template <typename Digraph, typename Item, typename RefMap, typename Ref>
+    class RefCopy : public MapCopyBase<Digraph, Item, RefMap> {
+    public:
+
+      RefCopy(Ref& map) : _map(map) {}
+
+      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
+        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
+        for (ItemIt it(digraph); it != INVALID; ++it) {
+          _map.set(it, refMap[it]);
+        }
+      }
+
+    private:
+      Ref& _map;
+    };
+
+    template <typename Digraph, typename Item, typename RefMap,
+              typename CrossRef>
+    class CrossRefCopy : public MapCopyBase<Digraph, Item, RefMap> {
+    public:
+
+      CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {}
+
+      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
+        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
+        for (ItemIt it(digraph); it != INVALID; ++it) {
+          _cmap.set(refMap[it], it);
+        }
+      }
+
+    private:
+      CrossRef& _cmap;
+    };
+
+    template <typename Digraph, typename Enable = void>
+    struct DigraphCopySelector {
+      template <typename From, typename NodeRefMap, typename ArcRefMap>
+      static void copy(const From& from, Digraph &to,
+                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
+        to.clear();
+        for (typename From::NodeIt it(from); it != INVALID; ++it) {
+          nodeRefMap[it] = to.addNode();
+        }
+        for (typename From::ArcIt it(from); it != INVALID; ++it) {
+          arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)],
+                                    nodeRefMap[from.target(it)]);
+        }
+      }
+    };
+
+    template <typename Digraph>
+    struct DigraphCopySelector<
+      Digraph,
+      typename enable_if<typename Digraph::BuildTag, void>::type>
+    {
+      template <typename From, typename NodeRefMap, typename ArcRefMap>
+      static void copy(const From& from, Digraph &to,
+                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
+        to.build(from, nodeRefMap, arcRefMap);
+      }
+    };
+
+    template <typename Graph, typename Enable = void>
+    struct GraphCopySelector {
+      template <typename From, typename NodeRefMap, typename EdgeRefMap>
+      static void copy(const From& from, Graph &to,
+                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
+        to.clear();
+        for (typename From::NodeIt it(from); it != INVALID; ++it) {
+          nodeRefMap[it] = to.addNode();
+        }
+        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
+          edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)],
+                                      nodeRefMap[from.v(it)]);
+        }
+      }
+    };
+
+    template <typename Graph>
+    struct GraphCopySelector<
+      Graph,
+      typename enable_if<typename Graph::BuildTag, void>::type>
+    {
+      template <typename From, typename NodeRefMap, typename EdgeRefMap>
+      static void copy(const From& from, Graph &to,
+                       NodeRefMap& nodeRefMap,
+                       EdgeRefMap& edgeRefMap) {
+        to.build(from, nodeRefMap, edgeRefMap);
+      }
+    };
+
+    template <typename BpGraph, typename Enable = void>
+    struct BpGraphCopySelector {
+      template <typename From, typename RedNodeRefMap,
+                typename BlueNodeRefMap, typename EdgeRefMap>
+      static void copy(const From& from, BpGraph &to,
+                       RedNodeRefMap& redNodeRefMap,
+                       BlueNodeRefMap& blueNodeRefMap,
+                       EdgeRefMap& edgeRefMap) {
+        to.clear();
+        for (typename From::RedNodeIt it(from); it != INVALID; ++it) {
+          redNodeRefMap[it] = to.addRedNode();
+        }
+        for (typename From::BlueNodeIt it(from); it != INVALID; ++it) {
+          blueNodeRefMap[it] = to.addBlueNode();
+        }
+        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
+          edgeRefMap[it] = to.addEdge(redNodeRefMap[from.redNode(it)],
+                                      blueNodeRefMap[from.blueNode(it)]);
+        }
+      }
+    };
+
+    template <typename BpGraph>
+    struct BpGraphCopySelector<
+      BpGraph,
+      typename enable_if<typename BpGraph::BuildTag, void>::type>
+    {
+      template <typename From, typename RedNodeRefMap,
+                typename BlueNodeRefMap, typename EdgeRefMap>
+      static void copy(const From& from, BpGraph &to,
+                       RedNodeRefMap& redNodeRefMap,
+                       BlueNodeRefMap& blueNodeRefMap,
+                       EdgeRefMap& edgeRefMap) {
+        to.build(from, redNodeRefMap, blueNodeRefMap, edgeRefMap);
+      }
+    };
+
+  }
+
+  /// \brief Check whether a graph is undirected.
+  ///
+  /// This function returns \c true if the given graph is undirected.
+#ifdef DOXYGEN
+  template <typename GR>
+  bool undirected(const GR& g) { return false; }
+#else
+  template <typename GR>
+  typename enable_if<UndirectedTagIndicator<GR>, bool>::type
+  undirected(const GR&) {
+    return true;
+  }
+  template <typename GR>
+  typename disable_if<UndirectedTagIndicator<GR>, bool>::type
+  undirected(const GR&) {
+    return false;
+  }
+#endif
+
+  /// \brief Class to copy a digraph.
+  ///
+  /// Class to copy a digraph to another digraph (duplicate a digraph). The
+  /// simplest way of using it is through the \c digraphCopy() function.
+  ///
+  /// This class not only make a copy of a digraph, but it can create
+  /// references and cross references between the nodes and arcs of
+  /// the two digraphs, and it can copy maps to use with the newly created
+  /// digraph.
+  ///
+  /// To make a copy from a digraph, first an instance of DigraphCopy
+  /// should be created, then the data belongs to the digraph should
+  /// assigned to copy. In the end, the \c run() member should be
+  /// called.
+  ///
+  /// The next code copies a digraph with several data:
+  ///\code
+  ///  DigraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
+  ///  // Create references for the nodes
+  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
+  ///  cg.nodeRef(nr);
+  ///  // Create cross references (inverse) for the arcs
+  ///  NewGraph::ArcMap<OrigGraph::Arc> acr(new_graph);
+  ///  cg.arcCrossRef(acr);
+  ///  // Copy an arc map
+  ///  OrigGraph::ArcMap<double> oamap(orig_graph);
+  ///  NewGraph::ArcMap<double> namap(new_graph);
+  ///  cg.arcMap(oamap, namap);
+  ///  // Copy a node
+  ///  OrigGraph::Node on;
+  ///  NewGraph::Node nn;
+  ///  cg.node(on, nn);
+  ///  // Execute copying
+  ///  cg.run();
+  ///\endcode
+  template <typename From, typename To>
+  class DigraphCopy {
+  private:
+
+    typedef typename From::Node Node;
+    typedef typename From::NodeIt NodeIt;
+    typedef typename From::Arc Arc;
+    typedef typename From::ArcIt ArcIt;
+
+    typedef typename To::Node TNode;
+    typedef typename To::Arc TArc;
+
+    typedef typename From::template NodeMap<TNode> NodeRefMap;
+    typedef typename From::template ArcMap<TArc> ArcRefMap;
+
+  public:
+
+    /// \brief Constructor of DigraphCopy.
+    ///
+    /// Constructor of DigraphCopy for copying the content of the
+    /// \c from digraph into the \c to digraph.
+    DigraphCopy(const From& from, To& to)
+      : _from(from), _to(to) {}
+
+    /// \brief Destructor of DigraphCopy
+    ///
+    /// Destructor of DigraphCopy.
+    ~DigraphCopy() {
+      for (int i = 0; i < int(_node_maps.size()); ++i) {
+        delete _node_maps[i];
+      }
+      for (int i = 0; i < int(_arc_maps.size()); ++i) {
+        delete _arc_maps[i];
+      }
+
+    }
+
+    /// \brief Copy the node references into the given map.
+    ///
+    /// This function copies the node references into the given map.
+    /// The parameter should be a map, whose key type is the Node type of
+    /// the source digraph, while the value type is the Node type of the
+    /// destination digraph.
+    template <typename NodeRef>
+    DigraphCopy& nodeRef(NodeRef& map) {
+      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
+                           NodeRefMap, NodeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the node cross references into the given map.
+    ///
+    /// This function copies the node cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Node type of the destination digraph, while the value type is
+    /// the Node type of the source digraph.
+    template <typename NodeCrossRef>
+    DigraphCopy& nodeCrossRef(NodeCrossRef& map) {
+      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
+                           NodeRefMap, NodeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node map.
+    ///
+    /// This function makes a copy of the given node map for the newly
+    /// created digraph.
+    /// The key type of the new map \c tmap should be the Node type of the
+    /// destination digraph, and the key type of the original map \c map
+    /// should be the Node type of the source digraph.
+    template <typename FromMap, typename ToMap>
+    DigraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
+      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
+                           NodeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node.
+    ///
+    /// This function makes a copy of the given node.
+    DigraphCopy& node(const Node& node, TNode& tnode) {
+      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
+                           NodeRefMap, TNode>(node, tnode));
+      return *this;
+    }
+
+    /// \brief Copy the arc references into the given map.
+    ///
+    /// This function copies the arc references into the given map.
+    /// The parameter should be a map, whose key type is the Arc type of
+    /// the source digraph, while the value type is the Arc type of the
+    /// destination digraph.
+    template <typename ArcRef>
+    DigraphCopy& arcRef(ArcRef& map) {
+      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
+                          ArcRefMap, ArcRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the arc cross references into the given map.
+    ///
+    /// This function copies the arc cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Arc type of the destination digraph, while the value type is
+    /// the Arc type of the source digraph.
+    template <typename ArcCrossRef>
+    DigraphCopy& arcCrossRef(ArcCrossRef& map) {
+      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
+                          ArcRefMap, ArcCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given arc map.
+    ///
+    /// This function makes a copy of the given arc map for the newly
+    /// created digraph.
+    /// The key type of the new map \c tmap should be the Arc type of the
+    /// destination digraph, and the key type of the original map \c map
+    /// should be the Arc type of the source digraph.
+    template <typename FromMap, typename ToMap>
+    DigraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
+      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
+                          ArcRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given arc.
+    ///
+    /// This function makes a copy of the given arc.
+    DigraphCopy& arc(const Arc& arc, TArc& tarc) {
+      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
+                          ArcRefMap, TArc>(arc, tarc));
+      return *this;
+    }
+
+    /// \brief Execute copying.
+    ///
+    /// This function executes the copying of the digraph along with the
+    /// copying of the assigned data.
+    void run() {
+      NodeRefMap nodeRefMap(_from);
+      ArcRefMap arcRefMap(_from);
+      _core_bits::DigraphCopySelector<To>::
+        copy(_from, _to, nodeRefMap, arcRefMap);
+      for (int i = 0; i < int(_node_maps.size()); ++i) {
+        _node_maps[i]->copy(_from, nodeRefMap);
+      }
+      for (int i = 0; i < int(_arc_maps.size()); ++i) {
+        _arc_maps[i]->copy(_from, arcRefMap);
+      }
+    }
+
+  protected:
+
+    const From& _from;
+    To& _to;
+
+    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
+      _node_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
+      _arc_maps;
+
+  };
+
+  /// \brief Copy a digraph to another digraph.
+  ///
+  /// This function copies a digraph to another digraph.
+  /// The complete usage of it is detailed in the DigraphCopy class, but
+  /// a short example shows a basic work:
+  ///\code
+  /// digraphCopy(src, trg).nodeRef(nr).arcCrossRef(acr).run();
+  ///\endcode
+  ///
+  /// After the copy the \c nr map will contain the mapping from the
+  /// nodes of the \c from digraph to the nodes of the \c to digraph and
+  /// \c acr will contain the mapping from the arcs of the \c to digraph
+  /// to the arcs of the \c from digraph.
+  ///
+  /// \see DigraphCopy
+  template <typename From, typename To>
+  DigraphCopy<From, To> digraphCopy(const From& from, To& to) {
+    return DigraphCopy<From, To>(from, to);
+  }
+
+  /// \brief Class to copy a graph.
+  ///
+  /// Class to copy a graph to another graph (duplicate a graph). The
+  /// simplest way of using it is through the \c graphCopy() function.
+  ///
+  /// This class not only make a copy of a graph, but it can create
+  /// references and cross references between the nodes, edges and arcs of
+  /// the two graphs, and it can copy maps for using with the newly created
+  /// graph.
+  ///
+  /// To make a copy from a graph, first an instance of GraphCopy
+  /// should be created, then the data belongs to the graph should
+  /// assigned to copy. In the end, the \c run() member should be
+  /// called.
+  ///
+  /// The next code copies a graph with several data:
+  ///\code
+  ///  GraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
+  ///  // Create references for the nodes
+  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
+  ///  cg.nodeRef(nr);
+  ///  // Create cross references (inverse) for the edges
+  ///  NewGraph::EdgeMap<OrigGraph::Edge> ecr(new_graph);
+  ///  cg.edgeCrossRef(ecr);
+  ///  // Copy an edge map
+  ///  OrigGraph::EdgeMap<double> oemap(orig_graph);
+  ///  NewGraph::EdgeMap<double> nemap(new_graph);
+  ///  cg.edgeMap(oemap, nemap);
+  ///  // Copy a node
+  ///  OrigGraph::Node on;
+  ///  NewGraph::Node nn;
+  ///  cg.node(on, nn);
+  ///  // Execute copying
+  ///  cg.run();
+  ///\endcode
+  template <typename From, typename To>
+  class GraphCopy {
+  private:
+
+    typedef typename From::Node Node;
+    typedef typename From::NodeIt NodeIt;
+    typedef typename From::Arc Arc;
+    typedef typename From::ArcIt ArcIt;
+    typedef typename From::Edge Edge;
+    typedef typename From::EdgeIt EdgeIt;
+
+    typedef typename To::Node TNode;
+    typedef typename To::Arc TArc;
+    typedef typename To::Edge TEdge;
+
+    typedef typename From::template NodeMap<TNode> NodeRefMap;
+    typedef typename From::template EdgeMap<TEdge> EdgeRefMap;
+
+    struct ArcRefMap {
+      ArcRefMap(const From& from, const To& to,
+                const EdgeRefMap& edge_ref, const NodeRefMap& node_ref)
+        : _from(from), _to(to),
+          _edge_ref(edge_ref), _node_ref(node_ref) {}
+
+      typedef typename From::Arc Key;
+      typedef typename To::Arc Value;
+
+      Value operator[](const Key& key) const {
+        bool forward = _from.u(key) != _from.v(key) ?
+          _node_ref[_from.source(key)] ==
+          _to.source(_to.direct(_edge_ref[key], true)) :
+          _from.direction(key);
+        return _to.direct(_edge_ref[key], forward);
+      }
+
+      const From& _from;
+      const To& _to;
+      const EdgeRefMap& _edge_ref;
+      const NodeRefMap& _node_ref;
+    };
+
+  public:
+
+    /// \brief Constructor of GraphCopy.
+    ///
+    /// Constructor of GraphCopy for copying the content of the
+    /// \c from graph into the \c to graph.
+    GraphCopy(const From& from, To& to)
+      : _from(from), _to(to) {}
+
+    /// \brief Destructor of GraphCopy
+    ///
+    /// Destructor of GraphCopy.
+    ~GraphCopy() {
+      for (int i = 0; i < int(_node_maps.size()); ++i) {
+        delete _node_maps[i];
+      }
+      for (int i = 0; i < int(_arc_maps.size()); ++i) {
+        delete _arc_maps[i];
+      }
+      for (int i = 0; i < int(_edge_maps.size()); ++i) {
+        delete _edge_maps[i];
+      }
+    }
+
+    /// \brief Copy the node references into the given map.
+    ///
+    /// This function copies the node references into the given map.
+    /// The parameter should be a map, whose key type is the Node type of
+    /// the source graph, while the value type is the Node type of the
+    /// destination graph.
+    template <typename NodeRef>
+    GraphCopy& nodeRef(NodeRef& map) {
+      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
+                           NodeRefMap, NodeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the node cross references into the given map.
+    ///
+    /// This function copies the node cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Node type of the destination graph, while the value type is
+    /// the Node type of the source graph.
+    template <typename NodeCrossRef>
+    GraphCopy& nodeCrossRef(NodeCrossRef& map) {
+      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
+                           NodeRefMap, NodeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node map.
+    ///
+    /// This function makes a copy of the given node map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Node type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Node type of the source graph.
+    template <typename FromMap, typename ToMap>
+    GraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
+      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
+                           NodeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node.
+    ///
+    /// This function makes a copy of the given node.
+    GraphCopy& node(const Node& node, TNode& tnode) {
+      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
+                           NodeRefMap, TNode>(node, tnode));
+      return *this;
+    }
+
+    /// \brief Copy the arc references into the given map.
+    ///
+    /// This function copies the arc references into the given map.
+    /// The parameter should be a map, whose key type is the Arc type of
+    /// the source graph, while the value type is the Arc type of the
+    /// destination graph.
+    template <typename ArcRef>
+    GraphCopy& arcRef(ArcRef& map) {
+      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
+                          ArcRefMap, ArcRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the arc cross references into the given map.
+    ///
+    /// This function copies the arc cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Arc type of the destination graph, while the value type is
+    /// the Arc type of the source graph.
+    template <typename ArcCrossRef>
+    GraphCopy& arcCrossRef(ArcCrossRef& map) {
+      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
+                          ArcRefMap, ArcCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given arc map.
+    ///
+    /// This function makes a copy of the given arc map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Arc type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Arc type of the source graph.
+    template <typename FromMap, typename ToMap>
+    GraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
+      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
+                          ArcRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given arc.
+    ///
+    /// This function makes a copy of the given arc.
+    GraphCopy& arc(const Arc& arc, TArc& tarc) {
+      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
+                          ArcRefMap, TArc>(arc, tarc));
+      return *this;
+    }
+
+    /// \brief Copy the edge references into the given map.
+    ///
+    /// This function copies the edge references into the given map.
+    /// The parameter should be a map, whose key type is the Edge type of
+    /// the source graph, while the value type is the Edge type of the
+    /// destination graph.
+    template <typename EdgeRef>
+    GraphCopy& edgeRef(EdgeRef& map) {
+      _edge_maps.push_back(new _core_bits::RefCopy<From, Edge,
+                           EdgeRefMap, EdgeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the edge cross references into the given map.
+    ///
+    /// This function copies the edge cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Edge type of the destination graph, while the value type is
+    /// the Edge type of the source graph.
+    template <typename EdgeCrossRef>
+    GraphCopy& edgeCrossRef(EdgeCrossRef& map) {
+      _edge_maps.push_back(new _core_bits::CrossRefCopy<From,
+                           Edge, EdgeRefMap, EdgeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given edge map.
+    ///
+    /// This function makes a copy of the given edge map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Edge type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Edge type of the source graph.
+    template <typename FromMap, typename ToMap>
+    GraphCopy& edgeMap(const FromMap& map, ToMap& tmap) {
+      _edge_maps.push_back(new _core_bits::MapCopy<From, Edge,
+                           EdgeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given edge.
+    ///
+    /// This function makes a copy of the given edge.
+    GraphCopy& edge(const Edge& edge, TEdge& tedge) {
+      _edge_maps.push_back(new _core_bits::ItemCopy<From, Edge,
+                           EdgeRefMap, TEdge>(edge, tedge));
+      return *this;
+    }
+
+    /// \brief Execute copying.
+    ///
+    /// This function executes the copying of the graph along with the
+    /// copying of the assigned data.
+    void run() {
+      NodeRefMap nodeRefMap(_from);
+      EdgeRefMap edgeRefMap(_from);
+      ArcRefMap arcRefMap(_from, _to, edgeRefMap, nodeRefMap);
+      _core_bits::GraphCopySelector<To>::
+        copy(_from, _to, nodeRefMap, edgeRefMap);
+      for (int i = 0; i < int(_node_maps.size()); ++i) {
+        _node_maps[i]->copy(_from, nodeRefMap);
+      }
+      for (int i = 0; i < int(_edge_maps.size()); ++i) {
+        _edge_maps[i]->copy(_from, edgeRefMap);
+      }
+      for (int i = 0; i < int(_arc_maps.size()); ++i) {
+        _arc_maps[i]->copy(_from, arcRefMap);
+      }
+    }
+
+  private:
+
+    const From& _from;
+    To& _to;
+
+    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
+      _node_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
+      _arc_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, Edge, EdgeRefMap>* >
+      _edge_maps;
+
+  };
+
+  /// \brief Copy a graph to another graph.
+  ///
+  /// This function copies a graph to another graph.
+  /// The complete usage of it is detailed in the GraphCopy class,
+  /// but a short example shows a basic work:
+  ///\code
+  /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run();
+  ///\endcode
+  ///
+  /// After the copy the \c nr map will contain the mapping from the
+  /// nodes of the \c from graph to the nodes of the \c to graph and
+  /// \c ecr will contain the mapping from the edges of the \c to graph
+  /// to the edges of the \c from graph.
+  ///
+  /// \see GraphCopy
+  template <typename From, typename To>
+  GraphCopy<From, To>
+  graphCopy(const From& from, To& to) {
+    return GraphCopy<From, To>(from, to);
+  }
+
+  /// \brief Class to copy a bipartite graph.
+  ///
+  /// Class to copy a bipartite graph to another graph (duplicate a
+  /// graph). The simplest way of using it is through the
+  /// \c bpGraphCopy() function.
+  ///
+  /// This class not only make a copy of a bipartite graph, but it can
+  /// create references and cross references between the nodes, edges
+  /// and arcs of the two graphs, and it can copy maps for using with
+  /// the newly created graph.
+  ///
+  /// To make a copy from a graph, first an instance of BpGraphCopy
+  /// should be created, then the data belongs to the graph should
+  /// assigned to copy. In the end, the \c run() member should be
+  /// called.
+  ///
+  /// The next code copies a graph with several data:
+  ///\code
+  ///  BpGraphCopy<OrigBpGraph, NewBpGraph> cg(orig_graph, new_graph);
+  ///  // Create references for the nodes
+  ///  OrigBpGraph::NodeMap<NewBpGraph::Node> nr(orig_graph);
+  ///  cg.nodeRef(nr);
+  ///  // Create cross references (inverse) for the edges
+  ///  NewBpGraph::EdgeMap<OrigBpGraph::Edge> ecr(new_graph);
+  ///  cg.edgeCrossRef(ecr);
+  ///  // Copy a red node map
+  ///  OrigBpGraph::RedNodeMap<double> ormap(orig_graph);
+  ///  NewBpGraph::RedNodeMap<double> nrmap(new_graph);
+  ///  cg.redNodeMap(ormap, nrmap);
+  ///  // Copy a node
+  ///  OrigBpGraph::Node on;
+  ///  NewBpGraph::Node nn;
+  ///  cg.node(on, nn);
+  ///  // Execute copying
+  ///  cg.run();
+  ///\endcode
+  template <typename From, typename To>
+  class BpGraphCopy {
+  private:
+
+    typedef typename From::Node Node;
+    typedef typename From::RedNode RedNode;
+    typedef typename From::BlueNode BlueNode;
+    typedef typename From::NodeIt NodeIt;
+    typedef typename From::Arc Arc;
+    typedef typename From::ArcIt ArcIt;
+    typedef typename From::Edge Edge;
+    typedef typename From::EdgeIt EdgeIt;
+
+    typedef typename To::Node TNode;
+    typedef typename To::RedNode TRedNode;
+    typedef typename To::BlueNode TBlueNode;
+    typedef typename To::Arc TArc;
+    typedef typename To::Edge TEdge;
+
+    typedef typename From::template RedNodeMap<TRedNode> RedNodeRefMap;
+    typedef typename From::template BlueNodeMap<TBlueNode> BlueNodeRefMap;
+    typedef typename From::template EdgeMap<TEdge> EdgeRefMap;
+
+    struct NodeRefMap {
+      NodeRefMap(const From& from, const RedNodeRefMap& red_node_ref,
+                 const BlueNodeRefMap& blue_node_ref)
+        : _from(from), _red_node_ref(red_node_ref),
+          _blue_node_ref(blue_node_ref) {}
+
+      typedef typename From::Node Key;
+      typedef typename To::Node Value;
+
+      Value operator[](const Key& key) const {
+        if (_from.red(key)) {
+          return _red_node_ref[_from.asRedNodeUnsafe(key)];
+        } else {
+          return _blue_node_ref[_from.asBlueNodeUnsafe(key)];
+        }
+      }
+
+      const From& _from;
+      const RedNodeRefMap& _red_node_ref;
+      const BlueNodeRefMap& _blue_node_ref;
+    };
+
+    struct ArcRefMap {
+      ArcRefMap(const From& from, const To& to, const EdgeRefMap& edge_ref)
+        : _from(from), _to(to), _edge_ref(edge_ref) {}
+
+      typedef typename From::Arc Key;
+      typedef typename To::Arc Value;
+
+      Value operator[](const Key& key) const {
+        return _to.direct(_edge_ref[key], _from.direction(key));
+      }
+
+      const From& _from;
+      const To& _to;
+      const EdgeRefMap& _edge_ref;
+    };
+
+  public:
+
+    /// \brief Constructor of BpGraphCopy.
+    ///
+    /// Constructor of BpGraphCopy for copying the content of the
+    /// \c from graph into the \c to graph.
+    BpGraphCopy(const From& from, To& to)
+      : _from(from), _to(to) {}
+
+    /// \brief Destructor of BpGraphCopy
+    ///
+    /// Destructor of BpGraphCopy.
+    ~BpGraphCopy() {
+      for (int i = 0; i < int(_node_maps.size()); ++i) {
+        delete _node_maps[i];
+      }
+      for (int i = 0; i < int(_red_maps.size()); ++i) {
+        delete _red_maps[i];
+      }
+      for (int i = 0; i < int(_blue_maps.size()); ++i) {
+        delete _blue_maps[i];
+      }
+      for (int i = 0; i < int(_arc_maps.size()); ++i) {
+        delete _arc_maps[i];
+      }
+      for (int i = 0; i < int(_edge_maps.size()); ++i) {
+        delete _edge_maps[i];
+      }
+    }
+
+    /// \brief Copy the node references into the given map.
+    ///
+    /// This function copies the node references into the given map.
+    /// The parameter should be a map, whose key type is the Node type of
+    /// the source graph, while the value type is the Node type of the
+    /// destination graph.
+    template <typename NodeRef>
+    BpGraphCopy& nodeRef(NodeRef& map) {
+      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
+                           NodeRefMap, NodeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the node cross references into the given map.
+    ///
+    /// This function copies the node cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Node type of the destination graph, while the value type is
+    /// the Node type of the source graph.
+    template <typename NodeCrossRef>
+    BpGraphCopy& nodeCrossRef(NodeCrossRef& map) {
+      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
+                           NodeRefMap, NodeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node map.
+    ///
+    /// This function makes a copy of the given node map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Node type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Node type of the source graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
+      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
+                           NodeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node.
+    ///
+    /// This function makes a copy of the given node.
+    BpGraphCopy& node(const Node& node, TNode& tnode) {
+      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
+                           NodeRefMap, TNode>(node, tnode));
+      return *this;
+    }
+
+    /// \brief Copy the red node references into the given map.
+    ///
+    /// This function copies the red node references into the given
+    /// map.  The parameter should be a map, whose key type is the
+    /// Node type of the source graph with the red item set, while the
+    /// value type is the Node type of the destination graph.
+    template <typename RedRef>
+    BpGraphCopy& redRef(RedRef& map) {
+      _red_maps.push_back(new _core_bits::RefCopy<From, RedNode,
+                          RedNodeRefMap, RedRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the red node cross references into the given map.
+    ///
+    /// This function copies the red node cross references (reverse
+    /// references) into the given map. The parameter should be a map,
+    /// whose key type is the Node type of the destination graph with
+    /// the red item set, while the value type is the Node type of the
+    /// source graph.
+    template <typename RedCrossRef>
+    BpGraphCopy& redCrossRef(RedCrossRef& map) {
+      _red_maps.push_back(new _core_bits::CrossRefCopy<From, RedNode,
+                          RedNodeRefMap, RedCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given red node map.
+    ///
+    /// This function makes a copy of the given red node map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Node type of
+    /// the destination graph with the red items, and the key type of
+    /// the original map \c map should be the Node type of the source
+    /// graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& redNodeMap(const FromMap& map, ToMap& tmap) {
+      _red_maps.push_back(new _core_bits::MapCopy<From, RedNode,
+                          RedNodeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given red node.
+    ///
+    /// This function makes a copy of the given red node.
+    BpGraphCopy& redNode(const RedNode& node, TRedNode& tnode) {
+      _red_maps.push_back(new _core_bits::ItemCopy<From, RedNode,
+                          RedNodeRefMap, TRedNode>(node, tnode));
+      return *this;
+    }
+
+    /// \brief Copy the blue node references into the given map.
+    ///
+    /// This function copies the blue node references into the given
+    /// map.  The parameter should be a map, whose key type is the
+    /// Node type of the source graph with the blue item set, while the
+    /// value type is the Node type of the destination graph.
+    template <typename BlueRef>
+    BpGraphCopy& blueRef(BlueRef& map) {
+      _blue_maps.push_back(new _core_bits::RefCopy<From, BlueNode,
+                           BlueNodeRefMap, BlueRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the blue node cross references into the given map.
+    ///
+    /// This function copies the blue node cross references (reverse
+    /// references) into the given map. The parameter should be a map,
+    /// whose key type is the Node type of the destination graph with
+    /// the blue item set, while the value type is the Node type of the
+    /// source graph.
+    template <typename BlueCrossRef>
+    BpGraphCopy& blueCrossRef(BlueCrossRef& map) {
+      _blue_maps.push_back(new _core_bits::CrossRefCopy<From, BlueNode,
+                           BlueNodeRefMap, BlueCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given blue node map.
+    ///
+    /// This function makes a copy of the given blue node map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Node type of
+    /// the destination graph with the blue items, and the key type of
+    /// the original map \c map should be the Node type of the source
+    /// graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& blueNodeMap(const FromMap& map, ToMap& tmap) {
+      _blue_maps.push_back(new _core_bits::MapCopy<From, BlueNode,
+                           BlueNodeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given blue node.
+    ///
+    /// This function makes a copy of the given blue node.
+    BpGraphCopy& blueNode(const BlueNode& node, TBlueNode& tnode) {
+      _blue_maps.push_back(new _core_bits::ItemCopy<From, BlueNode,
+                           BlueNodeRefMap, TBlueNode>(node, tnode));
+      return *this;
+    }
+
+    /// \brief Copy the arc references into the given map.
+    ///
+    /// This function copies the arc references into the given map.
+    /// The parameter should be a map, whose key type is the Arc type of
+    /// the source graph, while the value type is the Arc type of the
+    /// destination graph.
+    template <typename ArcRef>
+    BpGraphCopy& arcRef(ArcRef& map) {
+      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
+                          ArcRefMap, ArcRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the arc cross references into the given map.
+    ///
+    /// This function copies the arc cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Arc type of the destination graph, while the value type is
+    /// the Arc type of the source graph.
+    template <typename ArcCrossRef>
+    BpGraphCopy& arcCrossRef(ArcCrossRef& map) {
+      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
+                          ArcRefMap, ArcCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given arc map.
+    ///
+    /// This function makes a copy of the given arc map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Arc type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Arc type of the source graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
+      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
+                          ArcRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given arc.
+    ///
+    /// This function makes a copy of the given arc.
+    BpGraphCopy& arc(const Arc& arc, TArc& tarc) {
+      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
+                          ArcRefMap, TArc>(arc, tarc));
+      return *this;
+    }
+
+    /// \brief Copy the edge references into the given map.
+    ///
+    /// This function copies the edge references into the given map.
+    /// The parameter should be a map, whose key type is the Edge type of
+    /// the source graph, while the value type is the Edge type of the
+    /// destination graph.
+    template <typename EdgeRef>
+    BpGraphCopy& edgeRef(EdgeRef& map) {
+      _edge_maps.push_back(new _core_bits::RefCopy<From, Edge,
+                           EdgeRefMap, EdgeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the edge cross references into the given map.
+    ///
+    /// This function copies the edge cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Edge type of the destination graph, while the value type is
+    /// the Edge type of the source graph.
+    template <typename EdgeCrossRef>
+    BpGraphCopy& edgeCrossRef(EdgeCrossRef& map) {
+      _edge_maps.push_back(new _core_bits::CrossRefCopy<From,
+                           Edge, EdgeRefMap, EdgeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given edge map.
+    ///
+    /// This function makes a copy of the given edge map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Edge type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Edge type of the source graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& edgeMap(const FromMap& map, ToMap& tmap) {
+      _edge_maps.push_back(new _core_bits::MapCopy<From, Edge,
+                           EdgeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given edge.
+    ///
+    /// This function makes a copy of the given edge.
+    BpGraphCopy& edge(const Edge& edge, TEdge& tedge) {
+      _edge_maps.push_back(new _core_bits::ItemCopy<From, Edge,
+                           EdgeRefMap, TEdge>(edge, tedge));
+      return *this;
+    }
+
+    /// \brief Execute copying.
+    ///
+    /// This function executes the copying of the graph along with the
+    /// copying of the assigned data.
+    void run() {
+      RedNodeRefMap redNodeRefMap(_from);
+      BlueNodeRefMap blueNodeRefMap(_from);
+      NodeRefMap nodeRefMap(_from, redNodeRefMap, blueNodeRefMap);
+      EdgeRefMap edgeRefMap(_from);
+      ArcRefMap arcRefMap(_from, _to, edgeRefMap);
+      _core_bits::BpGraphCopySelector<To>::
+        copy(_from, _to, redNodeRefMap, blueNodeRefMap, edgeRefMap);
+      for (int i = 0; i < int(_node_maps.size()); ++i) {
+        _node_maps[i]->copy(_from, nodeRefMap);
+      }
+      for (int i = 0; i < int(_red_maps.size()); ++i) {
+        _red_maps[i]->copy(_from, redNodeRefMap);
+      }
+      for (int i = 0; i < int(_blue_maps.size()); ++i) {
+        _blue_maps[i]->copy(_from, blueNodeRefMap);
+      }
+      for (int i = 0; i < int(_edge_maps.size()); ++i) {
+        _edge_maps[i]->copy(_from, edgeRefMap);
+      }
+      for (int i = 0; i < int(_arc_maps.size()); ++i) {
+        _arc_maps[i]->copy(_from, arcRefMap);
+      }
+    }
+
+  private:
+
+    const From& _from;
+    To& _to;
+
+    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
+      _node_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, RedNode, RedNodeRefMap>* >
+      _red_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, BlueNode, BlueNodeRefMap>* >
+      _blue_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
+      _arc_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, Edge, EdgeRefMap>* >
+      _edge_maps;
+
+  };
+
+  /// \brief Copy a graph to another graph.
+  ///
+  /// This function copies a graph to another graph.
+  /// The complete usage of it is detailed in the BpGraphCopy class,
+  /// but a short example shows a basic work:
+  ///\code
+  /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run();
+  ///\endcode
+  ///
+  /// After the copy the \c nr map will contain the mapping from the
+  /// nodes of the \c from graph to the nodes of the \c to graph and
+  /// \c ecr will contain the mapping from the edges of the \c to graph
+  /// to the edges of the \c from graph.
+  ///
+  /// \see BpGraphCopy
+  template <typename From, typename To>
+  BpGraphCopy<From, To>
+  bpGraphCopy(const From& from, To& to) {
+    return BpGraphCopy<From, To>(from, to);
+  }
+
+  namespace _core_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct FindArcSelector {
+      typedef typename Graph::Node Node;
+      typedef typename Graph::Arc Arc;
+      static Arc find(const Graph &g, Node u, Node v, Arc e) {
+        if (e == INVALID) {
+          g.firstOut(e, u);
+        } else {
+          g.nextOut(e);
+        }
+        while (e != INVALID && g.target(e) != v) {
+          g.nextOut(e);
+        }
+        return e;
+      }
+    };
+
+    template <typename Graph>
+    struct FindArcSelector<
+      Graph,
+      typename enable_if<typename Graph::FindArcTag, void>::type>
+    {
+      typedef typename Graph::Node Node;
+      typedef typename Graph::Arc Arc;
+      static Arc find(const Graph &g, Node u, Node v, Arc prev) {
+        return g.findArc(u, v, prev);
+      }
+    };
+  }
+
+  /// \brief Find an arc between two nodes of a digraph.
+  ///
+  /// This function finds an arc from node \c u to node \c v in the
+  /// digraph \c g.
+  ///
+  /// If \c prev is \ref INVALID (this is the default value), then
+  /// it finds the first arc from \c u to \c v. Otherwise it looks for
+  /// the next arc from \c u to \c v after \c prev.
+  /// \return The found arc or \ref INVALID if there is no such an arc.
+  ///
+  /// Thus you can iterate through each arc from \c u to \c v as it follows.
+  ///\code
+  /// for(Arc e = findArc(g,u,v); e != INVALID; e = findArc(g,u,v,e)) {
+  ///   ...
+  /// }
+  ///\endcode
+  ///
+  /// \note \ref ConArcIt provides iterator interface for the same
+  /// functionality.
+  ///
+  ///\sa ConArcIt
+  ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
+  template <typename Graph>
+  inline typename Graph::Arc
+  findArc(const Graph &g, typename Graph::Node u, typename Graph::Node v,
+          typename Graph::Arc prev = INVALID) {
+    return _core_bits::FindArcSelector<Graph>::find(g, u, v, prev);
+  }
+
+  /// \brief Iterator for iterating on parallel arcs connecting the same nodes.
+  ///
+  /// Iterator for iterating on parallel arcs connecting the same nodes. It is
+  /// a higher level interface for the \ref findArc() function. You can
+  /// use it the following way:
+  ///\code
+  /// for (ConArcIt<Graph> it(g, src, trg); it != INVALID; ++it) {
+  ///   ...
+  /// }
+  ///\endcode
+  ///
+  ///\sa findArc()
+  ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
+  template <typename GR>
+  class ConArcIt : public GR::Arc {
+    typedef typename GR::Arc Parent;
+
+  public:
+
+    typedef typename GR::Arc Arc;
+    typedef typename GR::Node Node;
+
+    /// \brief Constructor.
+    ///
+    /// Construct a new ConArcIt iterating on the arcs that
+    /// connects nodes \c u and \c v.
+    ConArcIt(const GR& g, Node u, Node v) : _graph(g) {
+      Parent::operator=(findArc(_graph, u, v));
+    }
+
+    /// \brief Constructor.
+    ///
+    /// Construct a new ConArcIt that continues the iterating from arc \c a.
+    ConArcIt(const GR& g, Arc a) : Parent(a), _graph(g) {}
+
+    /// \brief Increment operator.
+    ///
+    /// It increments the iterator and gives back the next arc.
+    ConArcIt& operator++() {
+      Parent::operator=(findArc(_graph, _graph.source(*this),
+                                _graph.target(*this), *this));
+      return *this;
+    }
+  private:
+    const GR& _graph;
+  };
+
+  namespace _core_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct FindEdgeSelector {
+      typedef typename Graph::Node Node;
+      typedef typename Graph::Edge Edge;
+      static Edge find(const Graph &g, Node u, Node v, Edge e) {
+        bool b;
+        if (u != v) {
+          if (e == INVALID) {
+            g.firstInc(e, b, u);
+          } else {
+            b = g.u(e) == u;
+            g.nextInc(e, b);
+          }
+          while (e != INVALID && (b ? g.v(e) : g.u(e)) != v) {
+            g.nextInc(e, b);
+          }
+        } else {
+          if (e == INVALID) {
+            g.firstInc(e, b, u);
+          } else {
+            b = true;
+            g.nextInc(e, b);
+          }
+          while (e != INVALID && (!b || g.v(e) != v)) {
+            g.nextInc(e, b);
+          }
+        }
+        return e;
+      }
+    };
+
+    template <typename Graph>
+    struct FindEdgeSelector<
+      Graph,
+      typename enable_if<typename Graph::FindEdgeTag, void>::type>
+    {
+      typedef typename Graph::Node Node;
+      typedef typename Graph::Edge Edge;
+      static Edge find(const Graph &g, Node u, Node v, Edge prev) {
+        return g.findEdge(u, v, prev);
+      }
+    };
+  }
+
+  /// \brief Find an edge between two nodes of a graph.
+  ///
+  /// This function finds an edge from node \c u to node \c v in graph \c g.
+  /// If node \c u and node \c v is equal then each loop edge
+  /// will be enumerated once.
+  ///
+  /// If \c prev is \ref INVALID (this is the default value), then
+  /// it finds the first edge from \c u to \c v. Otherwise it looks for
+  /// the next edge from \c u to \c v after \c prev.
+  /// \return The found edge or \ref INVALID if there is no such an edge.
+  ///
+  /// Thus you can iterate through each edge between \c u and \c v
+  /// as it follows.
+  ///\code
+  /// for(Edge e = findEdge(g,u,v); e != INVALID; e = findEdge(g,u,v,e)) {
+  ///   ...
+  /// }
+  ///\endcode
+  ///
+  /// \note \ref ConEdgeIt provides iterator interface for the same
+  /// functionality.
+  ///
+  ///\sa ConEdgeIt
+  template <typename Graph>
+  inline typename Graph::Edge
+  findEdge(const Graph &g, typename Graph::Node u, typename Graph::Node v,
+            typename Graph::Edge p = INVALID) {
+    return _core_bits::FindEdgeSelector<Graph>::find(g, u, v, p);
+  }
+
+  /// \brief Iterator for iterating on parallel edges connecting the same nodes.
+  ///
+  /// Iterator for iterating on parallel edges connecting the same nodes.
+  /// It is a higher level interface for the findEdge() function. You can
+  /// use it the following way:
+  ///\code
+  /// for (ConEdgeIt<Graph> it(g, u, v); it != INVALID; ++it) {
+  ///   ...
+  /// }
+  ///\endcode
+  ///
+  ///\sa findEdge()
+  template <typename GR>
+  class ConEdgeIt : public GR::Edge {
+    typedef typename GR::Edge Parent;
+
+  public:
+
+    typedef typename GR::Edge Edge;
+    typedef typename GR::Node Node;
+
+    /// \brief Constructor.
+    ///
+    /// Construct a new ConEdgeIt iterating on the edges that
+    /// connects nodes \c u and \c v.
+    ConEdgeIt(const GR& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
+      Parent::operator=(findEdge(_graph, _u, _v));
+    }
+
+    /// \brief Constructor.
+    ///
+    /// Construct a new ConEdgeIt that continues iterating from edge \c e.
+    ConEdgeIt(const GR& g, Edge e) : Parent(e), _graph(g) {}
+
+    /// \brief Increment operator.
+    ///
+    /// It increments the iterator and gives back the next edge.
+    ConEdgeIt& operator++() {
+      Parent::operator=(findEdge(_graph, _u, _v, *this));
+      return *this;
+    }
+  private:
+    const GR& _graph;
+    Node _u, _v;
+  };
+
+
+  ///Dynamic arc look-up between given endpoints.
+
+  ///Using this class, you can find an arc in a digraph from a given
+  ///source to a given target in amortized time <em>O</em>(log<em>d</em>),
+  ///where <em>d</em> is the out-degree of the source node.
+  ///
+  ///It is possible to find \e all parallel arcs between two nodes with
+  ///the \c operator() member.
+  ///
+  ///This is a dynamic data structure. Consider to use \ref ArcLookUp or
+  ///\ref AllArcLookUp if your digraph is not changed so frequently.
+  ///
+  ///This class uses a self-adjusting binary search tree, the Splay tree
+  ///of Sleator and Tarjan to guarantee the logarithmic amortized
+  ///time bound for arc look-ups. This class also guarantees the
+  ///optimal time bound in a constant factor for any distribution of
+  ///queries.
+  ///
+  ///\tparam GR The type of the underlying digraph.
+  ///
+  ///\sa ArcLookUp
+  ///\sa AllArcLookUp
+  template <typename GR>
+  class DynArcLookUp
+    : protected ItemSetTraits<GR, typename GR::Arc>::ItemNotifier::ObserverBase
+  {
+    typedef typename ItemSetTraits<GR, typename GR::Arc>
+    ::ItemNotifier::ObserverBase Parent;
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  public:
+
+    /// The Digraph type
+    typedef GR Digraph;
+
+  protected:
+
+    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type
+    {
+      typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
+
+    public:
+
+      AutoNodeMap(const GR& digraph) : Parent(digraph, INVALID) {}
+
+      virtual void add(const Node& node) {
+        Parent::add(node);
+        Parent::set(node, INVALID);
+      }
+
+      virtual void add(const std::vector<Node>& nodes) {
+        Parent::add(nodes);
+        for (int i = 0; i < int(nodes.size()); ++i) {
+          Parent::set(nodes[i], INVALID);
+        }
+      }
+
+      virtual void build() {
+        Parent::build();
+        Node it;
+        typename Parent::Notifier* nf = Parent::notifier();
+        for (nf->first(it); it != INVALID; nf->next(it)) {
+          Parent::set(it, INVALID);
+        }
+      }
+    };
+
+    class ArcLess {
+      const Digraph &g;
+    public:
+      ArcLess(const Digraph &_g) : g(_g) {}
+      bool operator()(Arc a,Arc b) const
+      {
+        return g.target(a)<g.target(b);
+      }
+    };
+
+  protected:
+
+    const Digraph &_g;
+    AutoNodeMap _head;
+    typename Digraph::template ArcMap<Arc> _parent;
+    typename Digraph::template ArcMap<Arc> _left;
+    typename Digraph::template ArcMap<Arc> _right;
+
+  public:
+
+    ///Constructor
+
+    ///Constructor.
+    ///
+    ///It builds up the search database.
+    DynArcLookUp(const Digraph &g)
+      : _g(g),_head(g),_parent(g),_left(g),_right(g)
+    {
+      Parent::attach(_g.notifier(typename Digraph::Arc()));
+      refresh();
+    }
+
+  protected:
+
+    virtual void add(const Arc& arc) {
+      insert(arc);
+    }
+
+    virtual void add(const std::vector<Arc>& arcs) {
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        insert(arcs[i]);
+      }
+    }
+
+    virtual void erase(const Arc& arc) {
+      remove(arc);
+    }
+
+    virtual void erase(const std::vector<Arc>& arcs) {
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        remove(arcs[i]);
+      }
+    }
+
+    virtual void build() {
+      refresh();
+    }
+
+    virtual void clear() {
+      for(NodeIt n(_g);n!=INVALID;++n) {
+        _head[n] = INVALID;
+      }
+    }
+
+    void insert(Arc arc) {
+      Node s = _g.source(arc);
+      Node t = _g.target(arc);
+      _left[arc] = INVALID;
+      _right[arc] = INVALID;
+
+      Arc e = _head[s];
+      if (e == INVALID) {
+        _head[s] = arc;
+        _parent[arc] = INVALID;
+        return;
+      }
+      while (true) {
+        if (t < _g.target(e)) {
+          if (_left[e] == INVALID) {
+            _left[e] = arc;
+            _parent[arc] = e;
+            splay(arc);
+            return;
+          } else {
+            e = _left[e];
+          }
+        } else {
+          if (_right[e] == INVALID) {
+            _right[e] = arc;
+            _parent[arc] = e;
+            splay(arc);
+            return;
+          } else {
+            e = _right[e];
+          }
+        }
+      }
+    }
+
+    void remove(Arc arc) {
+      if (_left[arc] == INVALID) {
+        if (_right[arc] != INVALID) {
+          _parent[_right[arc]] = _parent[arc];
+        }
+        if (_parent[arc] != INVALID) {
+          if (_left[_parent[arc]] == arc) {
+            _left[_parent[arc]] = _right[arc];
+          } else {
+            _right[_parent[arc]] = _right[arc];
+          }
+        } else {
+          _head[_g.source(arc)] = _right[arc];
+        }
+      } else if (_right[arc] == INVALID) {
+        _parent[_left[arc]] = _parent[arc];
+        if (_parent[arc] != INVALID) {
+          if (_left[_parent[arc]] == arc) {
+            _left[_parent[arc]] = _left[arc];
+          } else {
+            _right[_parent[arc]] = _left[arc];
+          }
+        } else {
+          _head[_g.source(arc)] = _left[arc];
+        }
+      } else {
+        Arc e = _left[arc];
+        if (_right[e] != INVALID) {
+          e = _right[e];
+          while (_right[e] != INVALID) {
+            e = _right[e];
+          }
+          Arc s = _parent[e];
+          _right[_parent[e]] = _left[e];
+          if (_left[e] != INVALID) {
+            _parent[_left[e]] = _parent[e];
+          }
+
+          _left[e] = _left[arc];
+          _parent[_left[arc]] = e;
+          _right[e] = _right[arc];
+          _parent[_right[arc]] = e;
+
+          _parent[e] = _parent[arc];
+          if (_parent[arc] != INVALID) {
+            if (_left[_parent[arc]] == arc) {
+              _left[_parent[arc]] = e;
+            } else {
+              _right[_parent[arc]] = e;
+            }
+          }
+          splay(s);
+        } else {
+          _right[e] = _right[arc];
+          _parent[_right[arc]] = e;
+          _parent[e] = _parent[arc];
+
+          if (_parent[arc] != INVALID) {
+            if (_left[_parent[arc]] == arc) {
+              _left[_parent[arc]] = e;
+            } else {
+              _right[_parent[arc]] = e;
+            }
+          } else {
+            _head[_g.source(arc)] = e;
+          }
+        }
+      }
+    }
+
+    Arc refreshRec(std::vector<Arc> &v,int a,int b)
+    {
+      int m=(a+b)/2;
+      Arc me=v[m];
+      if (a < m) {
+        Arc left = refreshRec(v,a,m-1);
+        _left[me] = left;
+        _parent[left] = me;
+      } else {
+        _left[me] = INVALID;
+      }
+      if (m < b) {
+        Arc right = refreshRec(v,m+1,b);
+        _right[me] = right;
+        _parent[right] = me;
+      } else {
+        _right[me] = INVALID;
+      }
+      return me;
+    }
+
+    void refresh() {
+      for(NodeIt n(_g);n!=INVALID;++n) {
+        std::vector<Arc> v;
+        for(OutArcIt a(_g,n);a!=INVALID;++a) v.push_back(a);
+        if (!v.empty()) {
+          std::sort(v.begin(),v.end(),ArcLess(_g));
+          Arc head = refreshRec(v,0,v.size()-1);
+          _head[n] = head;
+          _parent[head] = INVALID;
+        }
+        else _head[n] = INVALID;
+      }
+    }
+
+    void zig(Arc v) {
+      Arc w = _parent[v];
+      _parent[v] = _parent[w];
+      _parent[w] = v;
+      _left[w] = _right[v];
+      _right[v] = w;
+      if (_parent[v] != INVALID) {
+        if (_right[_parent[v]] == w) {
+          _right[_parent[v]] = v;
+        } else {
+          _left[_parent[v]] = v;
+        }
+      }
+      if (_left[w] != INVALID){
+        _parent[_left[w]] = w;
+      }
+    }
+
+    void zag(Arc v) {
+      Arc w = _parent[v];
+      _parent[v] = _parent[w];
+      _parent[w] = v;
+      _right[w] = _left[v];
+      _left[v] = w;
+      if (_parent[v] != INVALID){
+        if (_left[_parent[v]] == w) {
+          _left[_parent[v]] = v;
+        } else {
+          _right[_parent[v]] = v;
+        }
+      }
+      if (_right[w] != INVALID){
+        _parent[_right[w]] = w;
+      }
+    }
+
+    void splay(Arc v) {
+      while (_parent[v] != INVALID) {
+        if (v == _left[_parent[v]]) {
+          if (_parent[_parent[v]] == INVALID) {
+            zig(v);
+          } else {
+            if (_parent[v] == _left[_parent[_parent[v]]]) {
+              zig(_parent[v]);
+              zig(v);
+            } else {
+              zig(v);
+              zag(v);
+            }
+          }
+        } else {
+          if (_parent[_parent[v]] == INVALID) {
+            zag(v);
+          } else {
+            if (_parent[v] == _left[_parent[_parent[v]]]) {
+              zag(v);
+              zig(v);
+            } else {
+              zag(_parent[v]);
+              zag(v);
+            }
+          }
+        }
+      }
+      _head[_g.source(v)] = v;
+    }
+
+
+  public:
+
+    ///Find an arc between two nodes.
+
+    ///Find an arc between two nodes.
+    ///\param s The source node.
+    ///\param t The target node.
+    ///\param p The previous arc between \c s and \c t. It it is INVALID or
+    ///not given, the operator finds the first appropriate arc.
+    ///\return An arc from \c s to \c t after \c p or
+    ///\ref INVALID if there is no more.
+    ///
+    ///For example, you can count the number of arcs from \c u to \c v in the
+    ///following way.
+    ///\code
+    ///DynArcLookUp<ListDigraph> ae(g);
+    ///...
+    ///int n = 0;
+    ///for(Arc a = ae(u,v); a != INVALID; a = ae(u,v,a)) n++;
+    ///\endcode
+    ///
+    ///Finding the arcs take at most <em>O</em>(log<em>d</em>)
+    ///amortized time, specifically, the time complexity of the lookups
+    ///is equal to the optimal search tree implementation for the
+    ///current query distribution in a constant factor.
+    ///
+    ///\note This is a dynamic data structure, therefore the data
+    ///structure is updated after each graph alteration. Thus although
+    ///this data structure is theoretically faster than \ref ArcLookUp
+    ///and \ref AllArcLookUp, it often provides worse performance than
+    ///them.
+    Arc operator()(Node s, Node t, Arc p = INVALID) const  {
+      if (p == INVALID) {
+        Arc a = _head[s];
+        if (a == INVALID) return INVALID;
+        Arc r = INVALID;
+        while (true) {
+          if (_g.target(a) < t) {
+            if (_right[a] == INVALID) {
+              const_cast<DynArcLookUp&>(*this).splay(a);
+              return r;
+            } else {
+              a = _right[a];
+            }
+          } else {
+            if (_g.target(a) == t) {
+              r = a;
+            }
+            if (_left[a] == INVALID) {
+              const_cast<DynArcLookUp&>(*this).splay(a);
+              return r;
+            } else {
+              a = _left[a];
+            }
+          }
+        }
+      } else {
+        Arc a = p;
+        if (_right[a] != INVALID) {
+          a = _right[a];
+          while (_left[a] != INVALID) {
+            a = _left[a];
+          }
+          const_cast<DynArcLookUp&>(*this).splay(a);
+        } else {
+          while (_parent[a] != INVALID && _right[_parent[a]] ==  a) {
+            a = _parent[a];
+          }
+          if (_parent[a] == INVALID) {
+            return INVALID;
+          } else {
+            a = _parent[a];
+            const_cast<DynArcLookUp&>(*this).splay(a);
+          }
+        }
+        if (_g.target(a) == t) return a;
+        else return INVALID;
+      }
+    }
+
+  };
+
+  ///Fast arc look-up between given endpoints.
+
+  ///Using this class, you can find an arc in a digraph from a given
+  ///source to a given target in time <em>O</em>(log<em>d</em>),
+  ///where <em>d</em> is the out-degree of the source node.
+  ///
+  ///It is not possible to find \e all parallel arcs between two nodes.
+  ///Use \ref AllArcLookUp for this purpose.
+  ///
+  ///\warning This class is static, so you should call refresh() (or at
+  ///least refresh(Node)) to refresh this data structure whenever the
+  ///digraph changes. This is a time consuming (superlinearly proportional
+  ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
+  ///
+  ///\tparam GR The type of the underlying digraph.
+  ///
+  ///\sa DynArcLookUp
+  ///\sa AllArcLookUp
+  template<class GR>
+  class ArcLookUp
+  {
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  public:
+
+    /// The Digraph type
+    typedef GR Digraph;
+
+  protected:
+    const Digraph &_g;
+    typename Digraph::template NodeMap<Arc> _head;
+    typename Digraph::template ArcMap<Arc> _left;
+    typename Digraph::template ArcMap<Arc> _right;
+
+    class ArcLess {
+      const Digraph &g;
+    public:
+      ArcLess(const Digraph &_g) : g(_g) {}
+      bool operator()(Arc a,Arc b) const
+      {
+        return g.target(a)<g.target(b);
+      }
+    };
+
+  public:
+
+    ///Constructor
+
+    ///Constructor.
+    ///
+    ///It builds up the search database, which remains valid until the digraph
+    ///changes.
+    ArcLookUp(const Digraph &g) :_g(g),_head(g),_left(g),_right(g) {refresh();}
+
+  private:
+    Arc refreshRec(std::vector<Arc> &v,int a,int b)
+    {
+      int m=(a+b)/2;
+      Arc me=v[m];
+      _left[me] = a<m?refreshRec(v,a,m-1):INVALID;
+      _right[me] = m<b?refreshRec(v,m+1,b):INVALID;
+      return me;
+    }
+  public:
+    ///Refresh the search data structure at a node.
+
+    ///Build up the search database of node \c n.
+    ///
+    ///It runs in time <em>O</em>(<em>d</em> log<em>d</em>), where <em>d</em>
+    ///is the number of the outgoing arcs of \c n.
+    void refresh(Node n)
+    {
+      std::vector<Arc> v;
+      for(OutArcIt e(_g,n);e!=INVALID;++e) v.push_back(e);
+      if(v.size()) {
+        std::sort(v.begin(),v.end(),ArcLess(_g));
+        _head[n]=refreshRec(v,0,v.size()-1);
+      }
+      else _head[n]=INVALID;
+    }
+    ///Refresh the full data structure.
+
+    ///Build up the full search database. In fact, it simply calls
+    ///\ref refresh(Node) "refresh(n)" for each node \c n.
+    ///
+    ///It runs in time <em>O</em>(<em>m</em> log<em>D</em>), where <em>m</em> is
+    ///the number of the arcs in the digraph and <em>D</em> is the maximum
+    ///out-degree of the digraph.
+    void refresh()
+    {
+      for(NodeIt n(_g);n!=INVALID;++n) refresh(n);
+    }
+
+    ///Find an arc between two nodes.
+
+    ///Find an arc between two nodes in time <em>O</em>(log<em>d</em>),
+    ///where <em>d</em> is the number of outgoing arcs of \c s.
+    ///\param s The source node.
+    ///\param t The target node.
+    ///\return An arc from \c s to \c t if there exists,
+    ///\ref INVALID otherwise.
+    ///
+    ///\warning If you change the digraph, refresh() must be called before using
+    ///this operator. If you change the outgoing arcs of
+    ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough.
+    Arc operator()(Node s, Node t) const
+    {
+      Arc e;
+      for(e=_head[s];
+          e!=INVALID&&_g.target(e)!=t;
+          e = t < _g.target(e)?_left[e]:_right[e]) ;
+      return e;
+    }
+
+  };
+
+  ///Fast look-up of all arcs between given endpoints.
+
+  ///This class is the same as \ref ArcLookUp, with the addition
+  ///that it makes it possible to find all parallel arcs between given
+  ///endpoints.
+  ///
+  ///\warning This class is static, so you should call refresh() (or at
+  ///least refresh(Node)) to refresh this data structure whenever the
+  ///digraph changes. This is a time consuming (superlinearly proportional
+  ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
+  ///
+  ///\tparam GR The type of the underlying digraph.
+  ///
+  ///\sa DynArcLookUp
+  ///\sa ArcLookUp
+  template<class GR>
+  class AllArcLookUp : public ArcLookUp<GR>
+  {
+    using ArcLookUp<GR>::_g;
+    using ArcLookUp<GR>::_right;
+    using ArcLookUp<GR>::_left;
+    using ArcLookUp<GR>::_head;
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+    typename GR::template ArcMap<Arc> _next;
+
+    Arc refreshNext(Arc head,Arc next=INVALID)
+    {
+      if(head==INVALID) return next;
+      else {
+        next=refreshNext(_right[head],next);
+        _next[head]=( next!=INVALID && _g.target(next)==_g.target(head))
+          ? next : INVALID;
+        return refreshNext(_left[head],head);
+      }
+    }
+
+    void refreshNext()
+    {
+      for(NodeIt n(_g);n!=INVALID;++n) refreshNext(_head[n]);
+    }
+
+  public:
+
+    /// The Digraph type
+    typedef GR Digraph;
+
+    ///Constructor
+
+    ///Constructor.
+    ///
+    ///It builds up the search database, which remains valid until the digraph
+    ///changes.
+    AllArcLookUp(const Digraph &g) : ArcLookUp<GR>(g), _next(g) {refreshNext();}
+
+    ///Refresh the data structure at a node.
+
+    ///Build up the search database of node \c n.
+    ///
+    ///It runs in time <em>O</em>(<em>d</em> log<em>d</em>), where <em>d</em> is
+    ///the number of the outgoing arcs of \c n.
+    void refresh(Node n)
+    {
+      ArcLookUp<GR>::refresh(n);
+      refreshNext(_head[n]);
+    }
+
+    ///Refresh the full data structure.
+
+    ///Build up the full search database. In fact, it simply calls
+    ///\ref refresh(Node) "refresh(n)" for each node \c n.
+    ///
+    ///It runs in time <em>O</em>(<em>m</em> log<em>D</em>), where <em>m</em> is
+    ///the number of the arcs in the digraph and <em>D</em> is the maximum
+    ///out-degree of the digraph.
+    void refresh()
+    {
+      for(NodeIt n(_g);n!=INVALID;++n) refresh(_head[n]);
+    }
+
+    ///Find an arc between two nodes.
+
+    ///Find an arc between two nodes.
+    ///\param s The source node.
+    ///\param t The target node.
+    ///\param prev The previous arc between \c s and \c t. It it is INVALID or
+    ///not given, the operator finds the first appropriate arc.
+    ///\return An arc from \c s to \c t after \c prev or
+    ///\ref INVALID if there is no more.
+    ///
+    ///For example, you can count the number of arcs from \c u to \c v in the
+    ///following way.
+    ///\code
+    ///AllArcLookUp<ListDigraph> ae(g);
+    ///...
+    ///int n = 0;
+    ///for(Arc a = ae(u,v); a != INVALID; a=ae(u,v,a)) n++;
+    ///\endcode
+    ///
+    ///Finding the first arc take <em>O</em>(log<em>d</em>) time,
+    ///where <em>d</em> is the number of outgoing arcs of \c s. Then the
+    ///consecutive arcs are found in constant time.
+    ///
+    ///\warning If you change the digraph, refresh() must be called before using
+    ///this operator. If you change the outgoing arcs of
+    ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough.
+    ///
+    Arc operator()(Node s, Node t, Arc prev=INVALID) const
+    {
+      if(prev==INVALID)
+        {
+          Arc f=INVALID;
+          Arc e;
+          for(e=_head[s];
+              e!=INVALID&&_g.target(e)!=t;
+              e = t < _g.target(e)?_left[e]:_right[e]) ;
+          while(e!=INVALID)
+            if(_g.target(e)==t)
+              {
+                f = e;
+                e = _left[e];
+              }
+            else e = _right[e];
+          return f;
+        }
+      else return _next[prev];
+    }
+
+  };
+
+  /// @}
+
+} //namespace lemon
+
+#endif
diff --git a/lemon/cost_scaling.h b/lemon/cost_scaling.h
new file mode 100644
index 0000000..efecdfe
--- /dev/null
+++ b/lemon/cost_scaling.h
@@ -0,0 +1,1607 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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" \cite amo93networkflows,
+  /// \cite goldberg90approximation,
+  /// \cite goldberg97efficient, \cite 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.
+  /// It is a polynomial algorithm, its running time complexity is
+  /// \f$O(n^2m\log(nK))\f$, where <i>K</i> denotes the maximum arc cost.
+  ///
+  /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest
+  /// implementations available in LEMON for solving this problem.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
+  ///
+  /// 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 \c V and \c C must be signed number types.
+  /// \warning All input data (capacities, supply values, and costs) must
+  /// be integer.
+  /// \warning This algorithm does not support negative costs for
+  /// arcs having 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;
+
+    /// \brief The \ref lemon::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 turned out 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::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 _has_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;
+
+  public:
+
+    /// \brief Constant for infinite upper bounds (capacities).
+    ///
+    /// Constant for infinite upper bounds (capacities).
+    /// It is \c std::numeric_limits<Value>::infinity() if available,
+    /// \c std::numeric_limits<Value>::max() otherwise.
+    const Value INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type, which is used for internal computations in the algorithm.
+    /// \c Cost must be convertible to \c LargeCost.
+    template <typename T>
+    struct SetLargeCost
+      : public CostScaling<GR, V, C, SetLargeCostTraits<T> > {
+      typedef  CostScaling<GR, V, C, SetLargeCostTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    CostScaling() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    CostScaling(const GR& graph) :
+      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
+      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) {
+      _has_lower = true;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _lower[_arc_idf[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 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 at least two.
+    ///
+    /// \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 = 16) {
+      LEMON_ASSERT(factor >= 2, "The scaling factor must be at least 2");
+      _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;
+      }
+      _has_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. By default, 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()
+    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);
+
+      // 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(m).
+    ///
+    /// \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 Copy the flow values (the primal solution) into the
+    /// given map.
+    ///
+    /// 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 Copy the potential values (the dual solution) into the
+    /// given map.
+    ///
+    /// 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;
+
+      // Check lower and upper bounds
+      LEMON_DEBUG(checkBoundMaps(),
+          "Upper bounds must be greater or equal to the lower bounds");
+
+
+      // 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 (_has_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 (_has_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;
+        }
+      }
+
+      // 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);
+
+      return OPTIMAL;
+    }
+
+    // Check if the upper bound is greater than or equal to the lower bound
+    // on each forward arc.
+    bool checkBoundMaps() {
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_forward[j] && _upper[j] < _lower[j]) return false;
+      }
+      return true;
+    }
+
+    // Execute the algorithm and transform the results
+    void start(Method method) {
+      const int MAX_PARTIAL_PATH_LENGTH = 4;
+
+      switch (method) {
+        case PUSH:
+          startPush();
+          break;
+        case AUGMENT:
+          startAugment(_res_node_num - 1);
+          break;
+        case PARTIAL_AUGMENT:
+          startAugment(MAX_PARTIAL_PATH_LENGTH);
+          break;
+      }
+
+      // Compute node potentials (dual solution)
+      for (int i = 0; i != _res_node_num; ++i) {
+        _pi[i] = static_cast<Cost>(_pi[i] / (_res_node_num * _alpha));
+      }
+      bool optimal = true;
+      for (int i = 0; optimal && i != _res_node_num; ++i) {
+        LargeCost pi_i = _pi[i];
+        int last_out = _first_out[i+1];
+        for (int j = _first_out[i]; j != last_out; ++j) {
+          if (_res_cap[j] > 0 && _scost[j] + pi_i - _pi[_target[j]] < 0) {
+            optimal = false;
+            break;
+          }
+        }
+      }
+
+      if (!optimal) {
+        // Compute node potentials for the original costs with BellmanFord
+        // (if it is necessary)
+        typedef std::pair<int, int> IntPair;
+        StaticDigraph sgr;
+        std::vector<IntPair> arc_vec;
+        std::vector<LargeCost> cost_vec;
+        LargeCostArcMap cost_map(cost_vec);
+
+        arc_vec.clear();
+        cost_vec.clear();
+        for (int j = 0; j != _res_arc_num; ++j) {
+          if (_res_cap[j] > 0) {
+            int u = _source[j], v = _target[j];
+            arc_vec.push_back(IntPair(u, v));
+            cost_vec.push_back(_scost[j] + _pi[u] - _pi[v]);
+          }
+        }
+        sgr.build(_res_node_num, arc_vec.begin(), arc_vec.end());
+
+        typename BellmanFord<StaticDigraph, LargeCostArcMap>::Create
+          bf(sgr, cost_map);
+        bf.init(0);
+        bf.start();
+
+        for (int i = 0; i != _res_node_num; ++i) {
+          _pi[i] += bf.dist(sgr.node(i));
+        }
+      }
+
+      // Shift potentials to meet the requirements of the GEQ type
+      // optimality conditions
+      LargeCost max_pot = _pi[_root];
+      for (int i = 0; i != _res_node_num; ++i) {
+        if (_pi[i] > max_pot) max_pot = _pi[i];
+      }
+      if (max_pot != 0) {
+        for (int i = 0; i != _res_node_num; ++i) {
+          _pi[i] -= max_pot;
+        }
+      }
+
+      // Handle non-zero lower bounds
+      if (_has_lower) {
+        int limit = _first_out[_root];
+        for (int j = 0; j != limit; ++j) {
+          if (_forward[j]) _res_cap[_reverse[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) {
+          Value delta = _res_cap[a];
+          if (delta > 0) {
+            int v = _target[a];
+            if (_cost[a] + pi_u - _pi[v] < 0) {
+              _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];
+      }
+    }
+
+    // Price (potential) refinement heuristic
+    bool priceRefinement() {
+
+      // Stack for stroing the topological order
+      IntVector stack(_res_node_num);
+      int stack_top;
+
+      // Perform phases
+      while (topologicalSort(stack, stack_top)) {
+
+        // Compute node ranks in the acyclic admissible network and
+        // store the nodes in buckets
+        for (int i = 0; i != _res_node_num; ++i) {
+          _rank[i] = 0;
+        }
+        const int bucket_end = _root + 1;
+        for (int r = 0; r != _max_rank; ++r) {
+          _buckets[r] = bucket_end;
+        }
+        int top_rank = 0;
+        for ( ; stack_top >= 0; --stack_top) {
+          int u = stack[stack_top], v;
+          int rank_u = _rank[u];
+
+          LargeCost rc, pi_u = _pi[u];
+          int last_out = _first_out[u+1];
+          for (int a = _first_out[u]; a != last_out; ++a) {
+            if (_res_cap[a] > 0) {
+              v = _target[a];
+              rc = _cost[a] + pi_u - _pi[v];
+              if (rc < 0) {
+                LargeCost nrc = static_cast<LargeCost>((-rc - 0.5) / _epsilon);
+                if (nrc < LargeCost(_max_rank)) {
+                  int new_rank_v = rank_u + static_cast<int>(nrc);
+                  if (new_rank_v > _rank[v]) {
+                    _rank[v] = new_rank_v;
+                  }
+                }
+              }
+            }
+          }
+
+          if (rank_u > 0) {
+            top_rank = std::max(top_rank, rank_u);
+            int bfirst = _buckets[rank_u];
+            _bucket_next[u] = bfirst;
+            _bucket_prev[bfirst] = u;
+            _buckets[rank_u] = u;
+          }
+        }
+
+        // Check if the current flow is epsilon-optimal
+        if (top_rank == 0) {
+          return true;
+        }
+
+        // Process buckets in top-down order
+        for (int rank = top_rank; rank > 0; --rank) {
+          while (_buckets[rank] != bucket_end) {
+            // Remove the first node from the current bucket
+            int u = _buckets[rank];
+            _buckets[rank] = _bucket_next[u];
+
+            // Search the outgoing arcs of u
+            LargeCost rc, pi_u = _pi[u];
+            int last_out = _first_out[u+1];
+            int v, old_rank_v, new_rank_v;
+            for (int a = _first_out[u]; a != last_out; ++a) {
+              if (_res_cap[a] > 0) {
+                v = _target[a];
+                old_rank_v = _rank[v];
+
+                if (old_rank_v < rank) {
+
+                  // Compute the new rank of node v
+                  rc = _cost[a] + pi_u - _pi[v];
+                  if (rc < 0) {
+                    new_rank_v = rank;
+                  } else {
+                    LargeCost nrc = rc / _epsilon;
+                    new_rank_v = 0;
+                    if (nrc < LargeCost(_max_rank)) {
+                      new_rank_v = rank - 1 - static_cast<int>(nrc);
+                    }
+                  }
+
+                  // Change the rank of node v
+                  if (new_rank_v > old_rank_v) {
+                    _rank[v] = new_rank_v;
+
+                    // Remove v from its old bucket
+                    if (old_rank_v > 0) {
+                      if (_buckets[old_rank_v] == v) {
+                        _buckets[old_rank_v] = _bucket_next[v];
+                      } else {
+                        int pv = _bucket_prev[v], nv = _bucket_next[v];
+                        _bucket_next[pv] = nv;
+                        _bucket_prev[nv] = pv;
+                      }
+                    }
+
+                    // Insert v into its new bucket
+                    int nv = _buckets[new_rank_v];
+                    _bucket_next[v] = nv;
+                    _bucket_prev[nv] = v;
+                    _buckets[new_rank_v] = v;
+                  }
+                }
+              }
+            }
+
+            // Refine potential of node u
+            _pi[u] -= rank * _epsilon;
+          }
+        }
+
+      }
+
+      return false;
+    }
+
+    // Find and cancel cycles in the admissible network and
+    // determine topological order using DFS
+    bool topologicalSort(IntVector &stack, int &stack_top) {
+      const int MAX_CYCLE_CANCEL = 1;
+
+      BoolVector reached(_res_node_num, false);
+      BoolVector processed(_res_node_num, false);
+      IntVector pred(_res_node_num);
+      for (int i = 0; i != _res_node_num; ++i) {
+        _next_out[i] = _first_out[i];
+      }
+      stack_top = -1;
+
+      int cycle_cnt = 0;
+      for (int start = 0; start != _res_node_num; ++start) {
+        if (reached[start]) continue;
+
+        // Start DFS search from this start node
+        pred[start] = -1;
+        int tip = start, v;
+        while (true) {
+          // Check the outgoing arcs of the current tip node
+          reached[tip] = true;
+          LargeCost pi_tip = _pi[tip];
+          int a, last_out = _first_out[tip+1];
+          for (a = _next_out[tip]; a != last_out; ++a) {
+            if (_res_cap[a] > 0) {
+              v = _target[a];
+              if (_cost[a] + pi_tip - _pi[v] < 0) {
+                if (!reached[v]) {
+                  // A new node is reached
+                  reached[v] = true;
+                  pred[v] = tip;
+                  _next_out[tip] = a;
+                  tip = v;
+                  a = _next_out[tip];
+                  last_out = _first_out[tip+1];
+                  break;
+                }
+                else if (!processed[v]) {
+                  // A cycle is found
+                  ++cycle_cnt;
+                  _next_out[tip] = a;
+
+                  // Find the minimum residual capacity along the cycle
+                  Value d, delta = _res_cap[a];
+                  int u, delta_node = tip;
+                  for (u = tip; u != v; ) {
+                    u = pred[u];
+                    d = _res_cap[_next_out[u]];
+                    if (d <= delta) {
+                      delta = d;
+                      delta_node = u;
+                    }
+                  }
+
+                  // Augment along the cycle
+                  _res_cap[a] -= delta;
+                  _res_cap[_reverse[a]] += delta;
+                  for (u = tip; u != v; ) {
+                    u = pred[u];
+                    int ca = _next_out[u];
+                    _res_cap[ca] -= delta;
+                    _res_cap[_reverse[ca]] += delta;
+                  }
+
+                  // Check the maximum number of cycle canceling
+                  if (cycle_cnt >= MAX_CYCLE_CANCEL) {
+                    return false;
+                  }
+
+                  // Roll back search to delta_node
+                  if (delta_node != tip) {
+                    for (u = tip; u != delta_node; u = pred[u]) {
+                      reached[u] = false;
+                    }
+                    tip = delta_node;
+                    a = _next_out[tip] + 1;
+                    last_out = _first_out[tip+1];
+                    break;
+                  }
+                }
+              }
+            }
+          }
+
+          // Step back to the previous node
+          if (a == last_out) {
+            processed[tip] = true;
+            stack[++stack_top] = tip;
+            tip = pred[tip];
+            if (tip < 0) {
+              // Finish DFS from the current start node
+              break;
+            }
+            ++_next_out[tip];
+          }
+        }
+
+      }
+
+      return (cycle_cnt == 0);
+    }
+
+    // Global potential update heuristic
+    void globalUpdate() {
+      const int bucket_end = _root + 1;
+
+      // Initialize buckets
+      for (int r = 0; r != _max_rank; ++r) {
+        _buckets[r] = bucket_end;
+      }
+      Value total_excess = 0;
+      int b0 = bucket_end;
+      for (int i = 0; i != _res_node_num; ++i) {
+        if (_excess[i] < 0) {
+          _rank[i] = 0;
+          _bucket_next[i] = b0;
+          _bucket_prev[b0] = i;
+          b0 = i;
+        } else {
+          total_excess += _excess[i];
+          _rank[i] = _max_rank;
+        }
+      }
+      if (total_excess == 0) return;
+      _buckets[0] = b0;
+
+      // 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 incoming 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 + static_cast<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 {
+                      int pv = _bucket_prev[v], nv = _bucket_next[v];
+                      _bucket_next[pv] = nv;
+                      _bucket_prev[nv] = pv;
+                    }
+                  }
+
+                  // Insert v into its new bucket
+                  int nv = _buckets[new_rank_v];
+                  _bucket_next[v] = nv;
+                  _bucket_prev[nv] = v;
+                  _buckets[new_rank_v] = v;
+                }
+              }
+            }
+          }
+
+          // Finish search if there are no more active nodes
+          if (_excess[u] > 0) {
+            total_excess -= _excess[u];
+            if (total_excess <= 0) break;
+          }
+        }
+        if (total_excess <= 0) break;
+      }
+
+      // Relabel nodes
+      for (int u = 0; u != _res_node_num; ++u) {
+        int k = std::min(_rank[u], r);
+        if (k > 0) {
+          _pi[u] -= _epsilon * k;
+          _next_out[u] = _first_out[u];
+        }
+      }
+    }
+
+    /// Execute the algorithm performing augment and relabel operations
+    void startAugment(int max_length) {
+      // Paramters for heuristics
+      const int PRICE_REFINEMENT_LIMIT = 2;
+      const double GLOBAL_UPDATE_FACTOR = 1.0;
+      const int global_update_skip = static_cast<int>(GLOBAL_UPDATE_FACTOR *
+        (_res_node_num + _sup_node_num * _sup_node_num));
+      int next_global_update_limit = global_update_skip;
+
+      // Perform cost scaling phases
+      IntVector path;
+      BoolVector path_arc(_res_arc_num, false);
+      int relabel_cnt = 0;
+      int eps_phase_cnt = 0;
+      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
+                                        1 : _epsilon / _alpha )
+      {
+        ++eps_phase_cnt;
+
+        // Price refinement heuristic
+        if (eps_phase_cnt >= PRICE_REFINEMENT_LIMIT) {
+          if (priceRefinement()) continue;
+        }
+
+        // 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
+          int tip = start;
+          while (int(path.size()) < max_length && _excess[tip] >= 0) {
+            int u;
+            LargeCost rc, min_red_cost = std::numeric_limits<LargeCost>::max();
+            LargeCost pi_tip = _pi[tip];
+            int last_out = _first_out[tip+1];
+            for (int a = _next_out[tip]; a != last_out; ++a) {
+              if (_res_cap[a] > 0) {
+                u = _target[a];
+                rc = _cost[a] + pi_tip - _pi[u];
+                if (rc < 0) {
+                  path.push_back(a);
+                  _next_out[tip] = a;
+                  if (path_arc[a]) {
+                    goto augment;   // a cycle is found, stop path search
+                  }
+                  tip = u;
+                  path_arc[a] = true;
+                  goto next_step;
+                }
+                else if (rc < min_red_cost) {
+                  min_red_cost = rc;
+                }
+              }
+            }
+
+            // Relabel tip node
+            if (tip != start) {
+              int ra = _reverse[path.back()];
+              min_red_cost =
+                std::min(min_red_cost, _cost[ra] + pi_tip - _pi[_target[ra]]);
+            }
+            last_out = _next_out[tip];
+            for (int a = _first_out[tip]; a != last_out; ++a) {
+              if (_res_cap[a] > 0) {
+                rc = _cost[a] + pi_tip - _pi[_target[a]];
+                if (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) {
+              int pa = path.back();
+              path_arc[pa] = false;
+              tip = _source[pa];
+              path.pop_back();
+            }
+
+          next_step: ;
+          }
+
+          // Augment along the found path (as much flow as possible)
+        augment:
+          Value delta;
+          int pa, u, v = start;
+          for (int i = 0; i != int(path.size()); ++i) {
+            pa = path[i];
+            u = v;
+            v = _target[pa];
+            path_arc[pa] = false;
+            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);
+            }
+          }
+          path.clear();
+
+          // Global update heuristic
+          if (relabel_cnt >= next_global_update_limit) {
+            globalUpdate();
+            next_global_update_limit += global_update_skip;
+          }
+        }
+
+      }
+
+    }
+
+    /// Execute the algorithm performing push and relabel operations
+    void startPush() {
+      // Paramters for heuristics
+      const int PRICE_REFINEMENT_LIMIT = 2;
+      const double GLOBAL_UPDATE_FACTOR = 2.0;
+
+      const int global_update_skip = static_cast<int>(GLOBAL_UPDATE_FACTOR *
+        (_res_node_num + _sup_node_num * _sup_node_num));
+      int next_global_update_limit = global_update_skip;
+
+      // Perform cost scaling phases
+      BoolVector hyper(_res_node_num, false);
+      LargeCostVector hyper_cost(_res_node_num);
+      int relabel_cnt = 0;
+      int eps_phase_cnt = 0;
+      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
+                                        1 : _epsilon / _alpha )
+      {
+        ++eps_phase_cnt;
+
+        // Price refinement heuristic
+        if (eps_phase_cnt >= PRICE_REFINEMENT_LIMIT) {
+          if (priceRefinement()) continue;
+        }
+
+        // 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) {
+              if (_res_cap[a] > 0) {
+                rc = _cost[a] + pi_n - _pi[_target[a]];
+                if (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_global_update_limit) {
+            globalUpdate();
+            for (int u = 0; u != _res_node_num; ++u)
+              hyper[u] = false;
+            next_global_update_limit += global_update_skip;
+          }
+        }
+      }
+    }
+
+  }; //class CostScaling
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_COST_SCALING_H
diff --git a/lemon/counter.h b/lemon/counter.h
new file mode 100644
index 0000000..a004991
--- /dev/null
+++ b/lemon/counter.h
@@ -0,0 +1,249 @@
+/* -*- 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_COUNTER_H
+#define LEMON_COUNTER_H
+
+#include <string>
+#include <iostream>
+
+///\ingroup timecount
+///\file
+///\brief Tools for counting steps and events
+
+namespace lemon
+{
+
+  template<class P> class _NoSubCounter;
+
+  template<class P>
+  class _SubCounter
+  {
+    P &_parent;
+    std::string _title;
+    std::ostream &_os;
+    int count;
+  public:
+
+    typedef _SubCounter<_SubCounter<P> > SubCounter;
+    typedef _NoSubCounter<_SubCounter<P> > NoSubCounter;
+
+    _SubCounter(P &parent)
+      : _parent(parent), _title(), _os(std::cerr), count(0) {}
+    _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
+      : _parent(parent), _title(title), _os(os), count(0) {}
+    _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
+      : _parent(parent), _title(title), _os(os), count(0) {}
+    ~_SubCounter() {
+      _os << _title << count <<std::endl;
+      _parent+=count;
+    }
+    _SubCounter &operator++() { count++; return *this;}
+    int operator++(int) { return count++; }
+    _SubCounter &operator--() { count--; return *this;}
+    int operator--(int) { return count--; }
+    _SubCounter &operator+=(int c) { count+=c; return *this;}
+    _SubCounter &operator-=(int c) { count-=c; return *this;}
+    operator int() {return count;}
+  };
+
+  template<class P>
+  class _NoSubCounter
+  {
+    P &_parent;
+  public:
+    typedef _NoSubCounter<_NoSubCounter<P> > SubCounter;
+    typedef _NoSubCounter<_NoSubCounter<P> > NoSubCounter;
+
+    _NoSubCounter(P &parent) :_parent(parent) {}
+    _NoSubCounter(P &parent,std::string,std::ostream &)
+      :_parent(parent) {}
+    _NoSubCounter(P &parent,std::string)
+      :_parent(parent) {}
+    _NoSubCounter(P &parent,const char *,std::ostream &)
+      :_parent(parent) {}
+    _NoSubCounter(P &parent,const char *)
+      :_parent(parent) {}
+    ~_NoSubCounter() {}
+    _NoSubCounter &operator++() { ++_parent; return *this;}
+    int operator++(int) { _parent++; return 0;}
+    _NoSubCounter &operator--() { --_parent; return *this;}
+    int operator--(int) { _parent--; return 0;}
+    _NoSubCounter &operator+=(int c) { _parent+=c; return *this;}
+    _NoSubCounter &operator-=(int c) { _parent-=c; return *this;}
+    operator int() {return 0;}
+  };
+
+
+  /// \addtogroup timecount
+  /// @{
+
+  /// A counter class
+
+  /// This class makes it easier to count certain events (e.g. for debug
+  /// reasons).
+  /// You can increment or decrement the counter using \c operator++,
+  /// \c operator--, \c operator+= and \c operator-=. You can also
+  /// define subcounters for the different phases of the algorithm or
+  /// for different types of operations.
+  /// A report containing the given title and the value of the counter
+  /// is automatically printed on destruction.
+  ///
+  /// The following example shows the usage of counters and subcounters.
+  /// \code
+  /// // Bubble sort
+  /// std::vector<T> v;
+  /// ...
+  /// Counter op("Operations: ");
+  /// Counter::SubCounter as(op, "Assignments: ");
+  /// Counter::SubCounter co(op, "Comparisons: ");
+  /// for (int i = v.size()-1; i > 0; --i) {
+  ///   for (int j = 0; j < i; ++j) {
+  ///     if (v[j] > v[j+1]) {
+  ///       T tmp = v[j];
+  ///       v[j] = v[j+1];
+  ///       v[j+1] = tmp;
+  ///       as += 3;          // three assignments
+  ///     }
+  ///     ++co;               // one comparison
+  ///   }
+  /// }
+  /// \endcode
+  ///
+  /// This code prints out something like that:
+  /// \code
+  /// Comparisons: 45
+  /// Assignments: 57
+  /// Operations: 102
+  /// \endcode
+  ///
+  /// \sa NoCounter
+  class Counter
+  {
+    std::string _title;
+    std::ostream &_os;
+    int count;
+  public:
+
+    /// SubCounter class
+
+    /// This class can be used to setup subcounters for a \ref Counter
+    /// to have finer reports. A subcounter provides exactly the same
+    /// operations as the main \ref Counter, but it also increments and
+    /// decrements the value of its parent.
+    /// Subcounters can also have subcounters.
+    ///
+    /// The parent counter must be given as the first parameter of the
+    /// constructor. Apart from that a title and an \c ostream object
+    /// can also be given just like for the main \ref Counter.
+    ///
+    /// A report containing the given title and the value of the
+    /// subcounter is automatically printed on destruction. If you
+    /// would like to turn off this report, use \ref NoSubCounter
+    /// instead.
+    ///
+    /// \sa NoSubCounter
+    typedef _SubCounter<Counter> SubCounter;
+
+    /// SubCounter class without printing report on destruction
+
+    /// This class can be used to setup subcounters for a \ref Counter.
+    /// It is the same as \ref SubCounter but it does not print report
+    /// on destruction. (It modifies the value of its parent, so 'No'
+    /// only means 'do not print'.)
+    ///
+    /// Replacing \ref SubCounter "SubCounter"s with \ref NoSubCounter
+    /// "NoSubCounter"s makes it possible to turn off reporting
+    /// subcounter values without actually removing the definitions
+    /// and the increment or decrement operators.
+    ///
+    /// \sa SubCounter
+    typedef _NoSubCounter<Counter> NoSubCounter;
+
+    /// Constructor.
+    Counter() : _title(), _os(std::cerr), count(0) {}
+    /// Constructor.
+    Counter(std::string title,std::ostream &os=std::cerr)
+      : _title(title), _os(os), count(0) {}
+    /// Constructor.
+    Counter(const char *title,std::ostream &os=std::cerr)
+      : _title(title), _os(os), count(0) {}
+    /// Destructor. Prints the given title and the value of the counter.
+    ~Counter() {
+      _os << _title << count <<std::endl;
+    }
+    ///\e
+    Counter &operator++() { count++; return *this;}
+    ///\e
+    int operator++(int) { return count++;}
+    ///\e
+    Counter &operator--() { count--; return *this;}
+    ///\e
+    int operator--(int) { return count--;}
+    ///\e
+    Counter &operator+=(int c) { count+=c; return *this;}
+    ///\e
+    Counter &operator-=(int c) { count-=c; return *this;}
+    /// Resets the counter to the given value.
+
+    /// Resets the counter to the given value.
+    /// \note This function does not reset the values of
+    /// \ref SubCounter "SubCounter"s but it resets \ref NoSubCounter
+    /// "NoSubCounter"s along with the main counter.
+    void reset(int c=0) {count=c;}
+    /// Returns the value of the counter.
+    operator int() {return count;}
+  };
+
+  /// 'Do nothing' version of Counter.
+
+  /// 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.
+  ///
+  /// Replacing a \ref Counter with a \ref NoCounter makes it possible
+  /// to turn off all counting and reporting (SubCounters should also
+  /// be replaced with NoSubCounters), so it does not affect the
+  /// efficiency of the program at all.
+  ///
+  /// \sa Counter
+  class NoCounter
+  {
+  public:
+    typedef _NoSubCounter<NoCounter> SubCounter;
+    typedef _NoSubCounter<NoCounter> NoSubCounter;
+
+    NoCounter() {}
+    NoCounter(std::string,std::ostream &) {}
+    NoCounter(const char *,std::ostream &) {}
+    NoCounter(std::string) {}
+    NoCounter(const char *) {}
+    NoCounter &operator++() { return *this; }
+    int operator++(int) { return 0; }
+    NoCounter &operator--() { return *this; }
+    int operator--(int) { return 0; }
+    NoCounter &operator+=(int) { return *this;}
+    NoCounter &operator-=(int) { return *this;}
+    void reset(int) {}
+    void reset() {}
+    operator int() {return 0;}
+  };
+
+  ///@}
+}
+
+#endif
diff --git a/lemon/cplex.cc b/lemon/cplex.cc
new file mode 100644
index 0000000..029a3ef
--- /dev/null
+++ b/lemon/cplex.cc
@@ -0,0 +1,994 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <vector>
+#include <cstring>
+
+#include <lemon/cplex.h>
+
+extern "C" {
+#include <ilcplex/cplex.h>
+}
+
+
+///\file
+///\brief Implementation of the LEMON-CPLEX lp solver interface.
+namespace lemon {
+
+  CplexEnv::LicenseError::LicenseError(int status) {
+    if (!CPXgeterrorstring(0, status, _message)) {
+      std::strcpy(_message, "Cplex unknown error");
+    }
+  }
+
+  CplexEnv::CplexEnv() {
+    int status;
+    _cnt = new int;
+    (*_cnt) = 1;
+    _env = CPXopenCPLEX(&status);
+    if (_env == 0) {
+      delete _cnt;
+      _cnt = 0;
+      throw LicenseError(status);
+    }
+  }
+
+  CplexEnv::CplexEnv(const CplexEnv& other) {
+    _env = other._env;
+    _cnt = other._cnt;
+    ++(*_cnt);
+  }
+
+  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
+    _env = other._env;
+    _cnt = other._cnt;
+    ++(*_cnt);
+    return *this;
+  }
+
+  CplexEnv::~CplexEnv() {
+    --(*_cnt);
+    if (*_cnt == 0) {
+      delete _cnt;
+      CPXcloseCPLEX(&_env);
+    }
+  }
+
+  CplexBase::CplexBase() : LpBase() {
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  CplexBase::CplexBase(const CplexEnv& env)
+    : LpBase(), _env(env) {
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  CplexBase::CplexBase(const CplexBase& cplex)
+    : LpBase() {
+    int status;
+    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
+    rows = cplex.rows;
+    cols = cplex.cols;
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  CplexBase::~CplexBase() {
+    CPXfreeprob(cplexEnv(),&_prob);
+  }
+
+  int CplexBase::_addCol() {
+    int i = CPXgetnumcols(cplexEnv(), _prob);
+    double lb = -INF, ub = INF;
+    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
+    return i;
+  }
+
+
+  int CplexBase::_addRow() {
+    int i = CPXgetnumrows(cplexEnv(), _prob);
+    const double ub = INF;
+    const char s = 'L';
+    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
+    return i;
+  }
+
+  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) {
+    CPXdelcols(cplexEnv(), _prob, i, i);
+  }
+
+  void CplexBase::_eraseRow(int i) {
+    CPXdelrows(cplexEnv(), _prob, i, i);
+  }
+
+  void CplexBase::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+  void CplexBase::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void CplexBase::_getColName(int col, std::string &name) const {
+    int size;
+    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
+    if (size == 0) {
+      name.clear();
+      return;
+    }
+
+    size *= -1;
+    std::vector<char> buf(size);
+    char *cname;
+    int tmp;
+    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
+                  &tmp, col, col);
+    name = cname;
+  }
+
+  void CplexBase::_setColName(int col, const std::string &name) {
+    char *cname;
+    cname = const_cast<char*>(name.c_str());
+    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
+  }
+
+  int CplexBase::_colByName(const std::string& name) const {
+    int index;
+    if (CPXgetcolindex(cplexEnv(), _prob,
+                       const_cast<char*>(name.c_str()), &index) == 0) {
+      return index;
+    }
+    return -1;
+  }
+
+  void CplexBase::_getRowName(int row, std::string &name) const {
+    int size;
+    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
+    if (size == 0) {
+      name.clear();
+      return;
+    }
+
+    size *= -1;
+    std::vector<char> buf(size);
+    char *cname;
+    int tmp;
+    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
+                  &tmp, row, row);
+    name = cname;
+  }
+
+  void CplexBase::_setRowName(int row, const std::string &name) {
+    char *cname;
+    cname = const_cast<char*>(name.c_str());
+    CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
+  }
+
+  int CplexBase::_rowByName(const std::string& name) const {
+    int index;
+    if (CPXgetrowindex(cplexEnv(), _prob,
+                       const_cast<char*>(name.c_str()), &index) == 0) {
+      return index;
+    }
+    return -1;
+  }
+
+  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
+                                      ExprIterator e)
+  {
+    std::vector<int> indices;
+    std::vector<int> rowlist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      rowlist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &rowlist.front(), &indices.front(), &values.front());
+  }
+
+  void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
+    int tmp1, tmp2, tmp3, length;
+    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
+               &indices.front(), &values.front(),
+               length, &tmp3, i, i);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+  }
+
+  void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
+    std::vector<int> indices;
+    std::vector<int> collist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      collist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &indices.front(), &collist.front(), &values.front());
+  }
+
+  void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
+
+    int tmp1, tmp2, tmp3, length;
+    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
+               &indices.front(), &values.front(),
+               length, &tmp3, i, i);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+
+  }
+
+  void CplexBase::_setCoeff(int row, int col, Value value) {
+    CPXchgcoef(cplexEnv(), _prob, row, col, value);
+  }
+
+  CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
+    CplexBase::Value value;
+    CPXgetcoef(cplexEnv(), _prob, row, col, &value);
+    return value;
+  }
+
+  void CplexBase::_setColLowerBound(int i, Value value) {
+    const char s = 'L';
+    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
+  }
+
+  CplexBase::Value CplexBase::_getColLowerBound(int i) const {
+    CplexBase::Value res;
+    CPXgetlb(cplexEnv(), _prob, &res, i, i);
+    return res <= -CPX_INFBOUND ? -INF : res;
+  }
+
+  void CplexBase::_setColUpperBound(int i, Value value)
+  {
+    const char s = 'U';
+    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
+  }
+
+  CplexBase::Value CplexBase::_getColUpperBound(int i) const {
+    CplexBase::Value res;
+    CPXgetub(cplexEnv(), _prob, &res, i, i);
+    return res >= CPX_INFBOUND ? INF : res;
+  }
+
+  CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
+    char s;
+    CPXgetsense(cplexEnv(), _prob, &s, i, i);
+    CplexBase::Value res;
+
+    switch (s) {
+    case 'G':
+    case 'R':
+    case 'E':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      return res <= -CPX_INFBOUND ? -INF : res;
+    default:
+      return -INF;
+    }
+  }
+
+  CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
+    char s;
+    CPXgetsense(cplexEnv(), _prob, &s, i, i);
+    CplexBase::Value res;
+
+    switch (s) {
+    case 'L':
+    case 'E':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      return res >= CPX_INFBOUND ? INF : res;
+    case 'R':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      {
+        double rng;
+        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
+        res += rng;
+      }
+      return res >= CPX_INFBOUND ? INF : res;
+    default:
+      return INF;
+    }
+  }
+
+  //This is easier to implement
+  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
+    if (lb == -INF) {
+      const char s = 'L';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
+    } else if (ub == INF) {
+      const char s = 'G';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+    } else if (lb == ub){
+      const char s = 'E';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+    } else {
+      const char s = 'R';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+      double len = ub - lb;
+      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
+    }
+  }
+
+  void CplexBase::_setRowLowerBound(int i, Value lb)
+  {
+    LEMON_ASSERT(lb != INF, "Invalid bound");
+    _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
+  }
+
+  void CplexBase::_setRowUpperBound(int i, Value ub)
+  {
+
+    LEMON_ASSERT(ub != -INF, "Invalid bound");
+    _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
+  }
+
+  void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
+  {
+    std::vector<int> indices;
+    std::vector<Value> values;
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+    }
+    CPXchgobj(cplexEnv(), _prob, values.size(),
+              &indices.front(), &values.front());
+
+  }
+
+  void CplexBase::_getObjCoeffs(InsertIterator b) const
+  {
+    int num = CPXgetnumcols(cplexEnv(), _prob);
+    std::vector<Value> x(num);
+
+    CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
+    for (int i = 0; i < num; ++i) {
+      if (x[i] != 0.0) {
+        *b = std::make_pair(i, x[i]);
+        ++b;
+      }
+    }
+  }
+
+  void CplexBase::_setObjCoeff(int i, Value obj_coef)
+  {
+    CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
+  }
+
+  CplexBase::Value CplexBase::_getObjCoeff(int i) const
+  {
+    Value x;
+    CPXgetobj(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  void CplexBase::_setSense(CplexBase::Sense sense) {
+    switch (sense) {
+    case MIN:
+      CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
+      break;
+    case MAX:
+      CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
+      break;
+    }
+  }
+
+  CplexBase::Sense CplexBase::_getSense() const {
+    switch (CPXgetobjsen(cplexEnv(), _prob)) {
+    case CPX_MIN:
+      return MIN;
+    case CPX_MAX:
+      return MAX;
+    default:
+      LEMON_ASSERT(false, "Invalid sense");
+      return CplexBase::Sense();
+    }
+  }
+
+  void CplexBase::_clear() {
+    CPXfreeprob(cplexEnv(),&_prob);
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+  }
+
+  void CplexBase::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _message_enabled = false;
+      break;
+    case MESSAGE_ERROR:
+    case MESSAGE_WARNING:
+    case MESSAGE_NORMAL:
+    case MESSAGE_VERBOSE:
+      _message_enabled = true;
+      break;
+    }
+  }
+
+  void CplexBase::_applyMessageLevel() {
+    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
+                   _message_enabled ? CPX_ON : CPX_OFF);
+  }
+
+  void CplexBase::_write(std::string file, std::string format) const
+  {
+    if(format == "MPS" || format == "LP")
+      CPXwriteprob(cplexEnv(), cplexLp(), file.c_str(), format.c_str());
+    else if(format == "SOL")
+      CPXsolwrite(cplexEnv(), cplexLp(), file.c_str());
+    else throw UnsupportedFormatError(format);
+  }
+
+
+
+  // CplexLp members
+
+  CplexLp::CplexLp()
+    : LpBase(), LpSolver(), CplexBase() {}
+
+  CplexLp::CplexLp(const CplexEnv& env)
+    : LpBase(), LpSolver(), CplexBase(env) {}
+
+  CplexLp::CplexLp(const CplexLp& other)
+    : LpBase(), LpSolver(), CplexBase(other) {}
+
+  CplexLp::~CplexLp() {}
+
+  CplexLp* CplexLp::newSolver() const { return new CplexLp; }
+  CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
+
+  const char* CplexLp::_solverName() const { return "CplexLp"; }
+
+  void CplexLp::_clear_temporals() {
+    _col_status.clear();
+    _row_status.clear();
+    _primal_ray.clear();
+    _dual_ray.clear();
+  }
+
+  // The routine returns zero unless an error occurred during the
+  // optimization. Examples of errors include exhausting available
+  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
+  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
+  // user-specified CPLEX limit, or proving the model infeasible or
+  // unbounded, are not considered errors. Note that a zero return
+  // value does not necessarily mean that a solution exists. Use query
+  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
+  // further information about the status of the optimization.
+  CplexLp::SolveExitStatus CplexLp::convertStatus(int status) {
+#if CPX_VERSION >= 800
+    if (status == 0) {
+      switch (CPXgetstat(cplexEnv(), _prob)) {
+      case CPX_STAT_OPTIMAL:
+      case CPX_STAT_INFEASIBLE:
+      case CPX_STAT_UNBOUNDED:
+        return SOLVED;
+      default:
+        return UNSOLVED;
+      }
+    } else {
+      return UNSOLVED;
+    }
+#else
+    if (status == 0) {
+      //We want to exclude some cases
+      switch (CPXgetstat(cplexEnv(), _prob)) {
+      case CPX_OBJ_LIM:
+      case CPX_IT_LIM_FEAS:
+      case CPX_IT_LIM_INFEAS:
+      case CPX_TIME_LIM_FEAS:
+      case CPX_TIME_LIM_INFEAS:
+        return UNSOLVED;
+      default:
+        return SOLVED;
+      }
+    } else {
+      return UNSOLVED;
+    }
+#endif
+  }
+
+  CplexLp::SolveExitStatus CplexLp::_solve() {
+    _clear_temporals();
+    _applyMessageLevel();
+    return convertStatus(CPXlpopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solvePrimal() {
+    _clear_temporals();
+    _applyMessageLevel();
+    return convertStatus(CPXprimopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solveDual() {
+    _clear_temporals();
+    _applyMessageLevel();
+    return convertStatus(CPXdualopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solveBarrier() {
+    _clear_temporals();
+    _applyMessageLevel();
+    return convertStatus(CPXbaropt(cplexEnv(), _prob));
+  }
+
+  CplexLp::Value CplexLp::_getPrimal(int i) const {
+    Value x;
+    CPXgetx(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  CplexLp::Value CplexLp::_getDual(int i) const {
+    Value y;
+    CPXgetpi(cplexEnv(), _prob, &y, i, i);
+    return y;
+  }
+
+  CplexLp::Value CplexLp::_getPrimalValue() const {
+    Value objval;
+    CPXgetobjval(cplexEnv(), _prob, &objval);
+    return objval;
+  }
+
+  CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
+    if (_col_status.empty()) {
+      _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
+      CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
+    }
+    switch (_col_status[i]) {
+    case CPX_BASIC:
+      return BASIC;
+    case CPX_FREE_SUPER:
+      return FREE;
+    case CPX_AT_LOWER:
+      return LOWER;
+    case CPX_AT_UPPER:
+      return UPPER;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return CplexLp::VarStatus();
+    }
+  }
+
+  CplexLp::VarStatus CplexLp::_getRowStatus(int i) const {
+    if (_row_status.empty()) {
+      _row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
+      CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
+    }
+    switch (_row_status[i]) {
+    case CPX_BASIC:
+      return BASIC;
+    case CPX_AT_LOWER:
+      {
+        char s;
+        CPXgetsense(cplexEnv(), _prob, &s, i, i);
+        return s != 'L' ? LOWER : UPPER;
+      }
+    case CPX_AT_UPPER:
+      return UPPER;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return CplexLp::VarStatus();
+    }
+  }
+
+  CplexLp::Value CplexLp::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
+      CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
+    }
+    return _primal_ray[i];
+  }
+
+  CplexLp::Value CplexLp::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+
+    }
+    return _dual_ray[i];
+  }
+
+  // Cplex 7.0 status values
+  // This table lists the statuses, returned by the CPXgetstat()
+  // routine, for solutions to LP problems or mixed integer problems. If
+  // no solution exists, the return value is zero.
+
+  // For Simplex, Barrier
+  // 1          CPX_OPTIMAL
+  //          Optimal solution found
+  // 2          CPX_INFEASIBLE
+  //          Problem infeasible
+  // 3    CPX_UNBOUNDED
+  //          Problem unbounded
+  // 4          CPX_OBJ_LIM
+  //          Objective limit exceeded in Phase II
+  // 5          CPX_IT_LIM_FEAS
+  //          Iteration limit exceeded in Phase II
+  // 6          CPX_IT_LIM_INFEAS
+  //          Iteration limit exceeded in Phase I
+  // 7          CPX_TIME_LIM_FEAS
+  //          Time limit exceeded in Phase II
+  // 8          CPX_TIME_LIM_INFEAS
+  //          Time limit exceeded in Phase I
+  // 9          CPX_NUM_BEST_FEAS
+  //          Problem non-optimal, singularities in Phase II
+  // 10         CPX_NUM_BEST_INFEAS
+  //          Problem non-optimal, singularities in Phase I
+  // 11         CPX_OPTIMAL_INFEAS
+  //          Optimal solution found, unscaled infeasibilities
+  // 12         CPX_ABORT_FEAS
+  //          Aborted in Phase II
+  // 13         CPX_ABORT_INFEAS
+  //          Aborted in Phase I
+  // 14          CPX_ABORT_DUAL_INFEAS
+  //          Aborted in barrier, dual infeasible
+  // 15          CPX_ABORT_PRIM_INFEAS
+  //          Aborted in barrier, primal infeasible
+  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
+  //          Aborted in barrier, primal and dual infeasible
+  // 17          CPX_ABORT_PRIM_DUAL_FEAS
+  //          Aborted in barrier, primal and dual feasible
+  // 18          CPX_ABORT_CROSSOVER
+  //          Aborted in crossover
+  // 19          CPX_INForUNBD
+  //          Infeasible or unbounded
+  // 20   CPX_PIVOT
+  //       User pivot used
+  //
+  // Pending return values
+  // ??case CPX_ABORT_DUAL_INFEAS
+  // ??case CPX_ABORT_CROSSOVER
+  // ??case CPX_INForUNBD
+  // ??case CPX_PIVOT
+
+  //Some more interesting stuff:
+
+  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
+  // 0 Automatic
+  // 1 Primal Simplex
+  // 2 Dual Simplex
+  // 3 Network Simplex
+  // 4 Standard Barrier
+  // Default: 0
+  // Description: Method for linear optimization.
+  // Determines which algorithm is used when CPXlpopt() (or "optimize"
+  // in the Interactive Optimizer) is called. Currently the behavior of
+  // the "Automatic" setting is that CPLEX simply invokes the dual
+  // simplex method, but this capability may be expanded in the future
+  // so that CPLEX chooses the method based on problem characteristics
+#if CPX_VERSION < 900
+  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
+    int lpmethod;
+    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
+    if (lpmethod==2){
+      if (stat==CPX_UNBOUNDED){
+        stat=CPX_INFEASIBLE;
+      }
+      else{
+        if (stat==CPX_INFEASIBLE)
+          stat=CPX_UNBOUNDED;
+      }
+    }
+  }
+#else
+  void statusSwitch(CPXENVptr,int&){}
+#endif
+
+  CplexLp::ProblemType CplexLp::_getPrimalType() const {
+    // Unboundedness not treated well: the following is from cplex 9.0 doc
+    // About Unboundedness
+
+    // The treatment of models that are unbounded involves a few
+    // subtleties. Specifically, a declaration of unboundedness means that
+    // ILOG CPLEX has determined that the model has an unbounded
+    // ray. Given any feasible solution x with objective z, a multiple of
+    // the unbounded ray can be added to x to give a feasible solution
+    // with objective z-1 (or z+1 for maximization models). Thus, if a
+    // feasible solution exists, then the optimal objective is
+    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
+    // a feasible solution exists. Users can call the routine CPXsolninfo
+    // to determine whether ILOG CPLEX has also concluded that the model
+    // has a feasible solution.
+
+    int stat = CPXgetstat(cplexEnv(), _prob);
+#if CPX_VERSION >= 800
+    switch (stat)
+      {
+      case CPX_STAT_OPTIMAL:
+        return OPTIMAL;
+      case CPX_STAT_UNBOUNDED:
+        return UNBOUNDED;
+      case CPX_STAT_INFEASIBLE:
+        return INFEASIBLE;
+      default:
+        return UNDEFINED;
+      }
+#else
+    statusSwitch(cplexEnv(),stat);
+    //CPXgetstat(cplexEnv(), _prob);
+    switch (stat) {
+    case 0:
+      return UNDEFINED; //Undefined
+    case CPX_OPTIMAL://Optimal
+      return OPTIMAL;
+    case CPX_UNBOUNDED://Unbounded
+      return INFEASIBLE;//In case of dual simplex
+      //return UNBOUNDED;
+    case CPX_INFEASIBLE://Infeasible
+      //    case CPX_IT_LIM_INFEAS:
+      //     case CPX_TIME_LIM_INFEAS:
+      //     case CPX_NUM_BEST_INFEAS:
+      //     case CPX_OPTIMAL_INFEAS:
+      //     case CPX_ABORT_INFEAS:
+      //     case CPX_ABORT_PRIM_INFEAS:
+      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
+      return UNBOUNDED;//In case of dual simplex
+      //return INFEASIBLE;
+      //     case CPX_OBJ_LIM:
+      //     case CPX_IT_LIM_FEAS:
+      //     case CPX_TIME_LIM_FEAS:
+      //     case CPX_NUM_BEST_FEAS:
+      //     case CPX_ABORT_FEAS:
+      //     case CPX_ABORT_PRIM_DUAL_FEAS:
+      //       return FEASIBLE;
+    default:
+      return UNDEFINED; //Everything else comes here
+      //FIXME error
+    }
+#endif
+  }
+
+  // Cplex 9.0 status values
+  // CPX_STAT_ABORT_DUAL_OBJ_LIM
+  // CPX_STAT_ABORT_IT_LIM
+  // CPX_STAT_ABORT_OBJ_LIM
+  // CPX_STAT_ABORT_PRIM_OBJ_LIM
+  // CPX_STAT_ABORT_TIME_LIM
+  // CPX_STAT_ABORT_USER
+  // CPX_STAT_FEASIBLE_RELAXED
+  // CPX_STAT_INFEASIBLE
+  // CPX_STAT_INForUNBD
+  // CPX_STAT_NUM_BEST
+  // CPX_STAT_OPTIMAL
+  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
+  // CPX_STAT_OPTIMAL_INFEAS
+  // CPX_STAT_OPTIMAL_RELAXED
+  // CPX_STAT_UNBOUNDED
+
+  CplexLp::ProblemType CplexLp::_getDualType() const {
+    int stat = CPXgetstat(cplexEnv(), _prob);
+#if CPX_VERSION >= 800
+    switch (stat) {
+    case CPX_STAT_OPTIMAL:
+      return OPTIMAL;
+    case CPX_STAT_UNBOUNDED:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+#else
+    statusSwitch(cplexEnv(),stat);
+    switch (stat) {
+    case 0:
+      return UNDEFINED; //Undefined
+    case CPX_OPTIMAL://Optimal
+      return OPTIMAL;
+    case CPX_UNBOUNDED:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED; //Everything else comes here
+      //FIXME error
+    }
+#endif
+  }
+
+  // CplexMip members
+
+  CplexMip::CplexMip()
+    : LpBase(), MipSolver(), CplexBase() {
+
+#if CPX_VERSION < 800
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
+#else
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
+#endif
+  }
+
+  CplexMip::CplexMip(const CplexEnv& env)
+    : LpBase(), MipSolver(), CplexBase(env) {
+
+#if CPX_VERSION < 800
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
+#else
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
+#endif
+
+  }
+
+  CplexMip::CplexMip(const CplexMip& other)
+    : LpBase(), MipSolver(), CplexBase(other) {}
+
+  CplexMip::~CplexMip() {}
+
+  CplexMip* CplexMip::newSolver() const { return new CplexMip; }
+  CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
+
+  const char* CplexMip::_solverName() const { return "CplexMip"; }
+
+  void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) {
+
+    // Note If a variable is to be changed to binary, a call to CPXchgbds
+    // should also be made to change the bounds to 0 and 1.
+
+    switch (col_type){
+    case INTEGER: {
+      const char t = 'I';
+      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
+    } break;
+    case REAL: {
+      const char t = 'C';
+      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
+    } break;
+    default:
+      break;
+    }
+  }
+
+  CplexMip::ColTypes CplexMip::_getColType(int i) const {
+    char t;
+    CPXgetctype (cplexEnv(), _prob, &t, i, i);
+    switch (t) {
+    case 'I':
+      return INTEGER;
+    case 'C':
+      return REAL;
+    default:
+      LEMON_ASSERT(false, "Invalid column type");
+      return ColTypes();
+    }
+
+  }
+
+  CplexMip::SolveExitStatus CplexMip::_solve() {
+    int status;
+    _applyMessageLevel();
+    status = CPXmipopt (cplexEnv(), _prob);
+    if (status==0)
+      return SOLVED;
+    else
+      return UNSOLVED;
+
+  }
+
+
+  CplexMip::ProblemType CplexMip::_getType() const {
+
+    int stat = CPXgetstat(cplexEnv(), _prob);
+
+    //Fortunately, MIP statuses did not change for cplex 8.0
+    switch (stat) {
+    case CPXMIP_OPTIMAL:
+      // Optimal integer solution has been found.
+    case CPXMIP_OPTIMAL_TOL:
+      // Optimal soluton with the tolerance defined by epgap or epagap has
+      // been found.
+      return OPTIMAL;
+      //This also exists in later issues
+      //    case CPXMIP_UNBOUNDED:
+      //return UNBOUNDED;
+      case CPXMIP_INFEASIBLE:
+        return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+    //Unboundedness not treated well: the following is from cplex 9.0 doc
+    // About Unboundedness
+
+    // The treatment of models that are unbounded involves a few
+    // subtleties. Specifically, a declaration of unboundedness means that
+    // ILOG CPLEX has determined that the model has an unbounded
+    // ray. Given any feasible solution x with objective z, a multiple of
+    // the unbounded ray can be added to x to give a feasible solution
+    // with objective z-1 (or z+1 for maximization models). Thus, if a
+    // feasible solution exists, then the optimal objective is
+    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
+    // a feasible solution exists. Users can call the routine CPXsolninfo
+    // to determine whether ILOG CPLEX has also concluded that the model
+    // has a feasible solution.
+  }
+
+  CplexMip::Value CplexMip::_getSol(int i) const {
+    Value x;
+    CPXgetmipx(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  CplexMip::Value CplexMip::_getSolValue() const {
+    Value objval;
+    CPXgetmipobjval(cplexEnv(), _prob, &objval);
+    return objval;
+  }
+
+} //namespace lemon
+
diff --git a/lemon/cplex.h b/lemon/cplex.h
new file mode 100644
index 0000000..c17e792
--- /dev/null
+++ b/lemon/cplex.h
@@ -0,0 +1,292 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_CPLEX_H
+#define LEMON_CPLEX_H
+
+///\file
+///\brief Header of the LEMON-CPLEX lp solver interface.
+
+#include <lemon/lp_base.h>
+
+struct cpxenv;
+struct cpxlp;
+
+namespace lemon {
+
+  /// \brief Reference counted wrapper around cpxenv pointer
+  ///
+  /// The cplex uses environment object which is responsible for
+  /// checking the proper license usage. This class provides a simple
+  /// interface for share the environment object between different
+  /// problems.
+  class CplexEnv {
+    friend class CplexBase;
+  private:
+    cpxenv* _env;
+    mutable int* _cnt;
+
+  public:
+
+    /// \brief This exception is thrown when the license check is not
+    /// sufficient
+    class LicenseError : public Exception {
+      friend class CplexEnv;
+    private:
+
+      LicenseError(int status);
+      char _message[510];
+
+    public:
+
+      /// The short error message
+      virtual const char* what() const throw() {
+        return _message;
+      }
+    };
+
+    /// Constructor
+    CplexEnv();
+    /// Shallow copy constructor
+    CplexEnv(const CplexEnv&);
+    /// Shallow assignement
+    CplexEnv& operator=(const CplexEnv&);
+    /// Destructor
+    virtual ~CplexEnv();
+
+  protected:
+
+    cpxenv* cplexEnv() { return _env; }
+    const cpxenv* cplexEnv() const { return _env; }
+  };
+
+  /// \brief Base interface for the CPLEX LP and MIP solver
+  ///
+  /// This class implements the common interface of the CPLEX LP and
+  /// MIP solvers.
+  /// \ingroup lp_group
+  class CplexBase : virtual public LpBase {
+  protected:
+
+    CplexEnv _env;
+    cpxlp* _prob;
+
+    CplexBase();
+    CplexBase(const CplexEnv&);
+    CplexBase(const CplexBase &);
+    virtual ~CplexBase();
+
+    virtual int _addCol();
+    virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+  private:
+    void _set_row_bounds(int i, Value lb, Value ub);
+  protected:
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual void _clear();
+
+    virtual void _messageLevel(MessageLevel level);
+    void _applyMessageLevel();
+
+    bool _message_enabled;
+
+    void _write(std::string file, std::string format) const;
+
+  public:
+
+    /// Returns the used \c CplexEnv instance
+    const CplexEnv& env() const { return _env; }
+
+    /// \brief Returns the const cpxenv pointer
+    ///
+    /// \note The cpxenv might be destructed with the solver.
+    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
+
+    /// \brief Returns the const cpxenv pointer
+    ///
+    /// \note The cpxenv might be destructed with the solver.
+    cpxenv* cplexEnv() { return _env.cplexEnv(); }
+
+    /// Returns the cplex problem object
+    cpxlp* cplexLp() { return _prob; }
+    /// Returns the cplex problem object
+    const cpxlp* cplexLp() const { return _prob; }
+
+#ifdef DOXYGEN
+    /// Write the problem or the solution to a file in the given format
+
+    /// This function writes the problem or the solution
+    /// to a file in the given format.
+    /// Trying to write in an unsupported format will trigger
+    /// \ref lemon::LpBase::UnsupportedFormatError "UnsupportedFormatError".
+    /// \param file The file path
+    /// \param format The output file format.
+    /// Supportted formats are "MPS", "LP" and "SOL".
+    void write(std::string file, std::string format = "MPS") const {}
+#endif
+
+  };
+
+  /// \brief Interface for the CPLEX LP solver
+  ///
+  /// This class implements an interface for the CPLEX LP solver.
+  ///\ingroup lp_group
+  class CplexLp : public LpSolver, public CplexBase {
+  public:
+    /// \e
+    CplexLp();
+    /// \e
+    CplexLp(const CplexEnv&);
+    /// \e
+    CplexLp(const CplexLp&);
+    /// \e
+    virtual ~CplexLp();
+
+    /// \e
+    virtual CplexLp* cloneSolver() const;
+    /// \e
+    virtual CplexLp* newSolver() const;
+
+  private:
+
+    // these values cannot retrieved element by element
+    mutable std::vector<int> _col_status;
+    mutable std::vector<int> _row_status;
+
+    mutable std::vector<Value> _primal_ray;
+    mutable std::vector<Value> _dual_ray;
+
+    void _clear_temporals();
+
+    SolveExitStatus convertStatus(int status);
+
+  protected:
+
+    virtual const char* _solverName() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+    virtual Value _getPrimalValue() const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+  public:
+
+    /// Solve with primal simplex method
+    SolveExitStatus solvePrimal();
+
+    /// Solve with dual simplex method
+    SolveExitStatus solveDual();
+
+    /// Solve with barrier method
+    SolveExitStatus solveBarrier();
+
+  };
+
+  /// \brief Interface for the CPLEX MIP solver
+  ///
+  /// This class implements an interface for the CPLEX MIP solver.
+  ///\ingroup lp_group
+  class CplexMip : public MipSolver, public CplexBase {
+  public:
+    /// \e
+    CplexMip();
+    /// \e
+    CplexMip(const CplexEnv&);
+    /// \e
+    CplexMip(const CplexMip&);
+    /// \e
+    virtual ~CplexMip();
+
+    /// \e
+    virtual CplexMip* cloneSolver() const;
+    /// \e
+    virtual CplexMip* newSolver() const;
+
+  protected:
+
+
+    virtual const char* _solverName() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_CPLEX_H
+
diff --git a/lemon/cycle_canceling.h b/lemon/cycle_canceling.h
new file mode 100644
index 0000000..646d299
--- /dev/null
+++ b/lemon/cycle_canceling.h
@@ -0,0 +1,1230 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_CYCLE_CANCELING_H
+#define LEMON_CYCLE_CANCELING_H
+
+/// \ingroup min_cost_flow_algs
+/// \file
+/// \brief Cycle-canceling algorithms for finding a minimum cost flow.
+
+#include <vector>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+#include <lemon/math.h>
+#include <lemon/static_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/circulation.h>
+#include <lemon/bellman_ford.h>
+#include <lemon/howard_mmc.h>
+#include <lemon/hartmann_orlin_mmc.h>
+
+namespace lemon {
+
+  /// \addtogroup min_cost_flow_algs
+  /// @{
+
+  /// \brief Implementation of cycle-canceling algorithms for
+  /// finding a \ref min_cost_flow "minimum cost flow".
+  ///
+  /// \ref CycleCanceling implements three different cycle-canceling
+  /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
+  /// \cite amo93networkflows, \cite klein67primal,
+  /// \cite goldberg89cyclecanceling.
+  /// The most efficent one is the \ref CANCEL_AND_TIGHTEN
+  /// "Cancel-and-Tighten" algorithm, thus it is the default method.
+  /// It runs in strongly polynomial time \f$O(n^2 m^2 \log n)\f$,
+  /// but in practice, it is typically orders of magnitude slower than
+  /// the scaling algorithms and \ref NetworkSimplex.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
+  ///
+  /// 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 \c V and \c C must be signed number types.
+  /// \warning All input data (capacities, supply values, and costs) must
+  /// be integer.
+  /// \warning This algorithm does not support negative costs for
+  /// arcs having 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 is by far the most efficient and the most robust.
+    /// 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 for detecting negative
+      /// cycles in the residual network.
+      /// The number of Bellman-Ford iterations is bounded by a successively
+      /// increased limit.
+      SIMPLE_CYCLE_CANCELING,
+      /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
+      /// well-known strongly polynomial method
+      /// \cite goldberg89cyclecanceling. It improves along a
+      /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
+      /// Its running time complexity is \f$O(n^2 m^3 \log n)\f$.
+      MINIMUM_MEAN_CYCLE_CANCELING,
+      /// The "Cancel-and-Tighten" algorithm, which can be viewed as an
+      /// improved version of the previous method
+      /// \cite goldberg89cyclecanceling.
+      /// It is faster both in theory and in practice, its running time
+      /// complexity is \f$O(n^2 m^2 \log n)\f$.
+      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 _has_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) {
+      _has_lower = true;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _lower[_arc_idf[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 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;
+      }
+      _has_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(m).
+    ///
+    /// \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 Copy the flow values (the primal solution) into the
+    /// given map.
+    ///
+    /// 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 Copy the potential values (the dual solution) into the
+    /// given map.
+    ///
+    /// 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;
+
+      // Check lower and upper bounds
+      LEMON_DEBUG(checkBoundMaps(),
+          "Upper bounds must be greater or equal to the lower bounds");
+
+
+      // 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 (_has_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 (_has_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;
+    }
+
+    // Check if the upper bound is greater than or equal to the lower bound
+    // on each forward arc.
+    bool checkBoundMaps() {
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_forward[j] && _upper[j] < _lower[j]) return false;
+      }
+      return true;
+    }
+
+    // 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 (_has_lower) {
+        int limit = _first_out[_root];
+        for (int j = 0; j != limit; ++j) {
+          if (_forward[j]) _res_cap[_reverse[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 Path<StaticDigraph> SPath;
+      typedef typename SPath::ArcIt SPathArcIt;
+      typedef typename HowardMmc<StaticDigraph, CostArcMap>
+        ::template SetPath<SPath>::Create HwMmc;
+      typedef typename HartmannOrlinMmc<StaticDigraph, CostArcMap>
+        ::template SetPath<SPath>::Create HoMmc;
+
+      const double HW_ITER_LIMIT_FACTOR = 1.0;
+      const int HW_ITER_LIMIT_MIN_VALUE = 5;
+
+      const int hw_iter_limit =
+          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
+                   HW_ITER_LIMIT_MIN_VALUE);
+
+      SPath cycle;
+      HwMmc hw_mmc(_sgr, _cost_map);
+      hw_mmc.cycle(cycle);
+      buildResidualNetwork();
+      while (true) {
+
+        typename HwMmc::TerminationCause hw_tc =
+            hw_mmc.findCycleMean(hw_iter_limit);
+        if (hw_tc == HwMmc::ITERATION_LIMIT) {
+          // Howard's algorithm reached the iteration limit, start a
+          // strongly polynomial algorithm instead
+          HoMmc ho_mmc(_sgr, _cost_map);
+          ho_mmc.cycle(cycle);
+          // Find a minimum mean cycle (Hartmann-Orlin algorithm)
+          if (!(ho_mmc.findCycleMean() && ho_mmc.cycleCost() < 0)) break;
+          ho_mmc.findCycle();
+        } else {
+          // Find a minimum mean cycle (Howard algorithm)
+          if (!(hw_tc == HwMmc::OPTIMAL && hw_mmc.cycleCost() < 0)) break;
+          hw_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;
+      const double HW_ITER_LIMIT_FACTOR = 1.0;
+      const int HW_ITER_LIMIT_MIN_VALUE = 5;
+
+      const int hw_iter_limit =
+          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
+                   HW_ITER_LIMIT_MIN_VALUE);
+
+      // Contruct auxiliary data vectors
+      DoubleVector pi(_res_node_num, 0.0);
+      IntVector level(_res_node_num);
+      BoolVector reached(_res_node_num);
+      BoolVector processed(_res_node_num);
+      IntVector pred_node(_res_node_num);
+      IntVector pred_arc(_res_node_num);
+      std::vector<int> stack(_res_node_num);
+      std::vector<int> proc_vector(_res_node_num);
+
+      // Initialize epsilon
+      double epsilon = 0;
+      for (int a = 0; a != _res_arc_num; ++a) {
+        if (_res_cap[a] > 0 && -_cost[a] > epsilon)
+          epsilon = -_cost[a];
+      }
+
+      // Start phases
+      Tolerance<double> tol;
+      tol.epsilon(1e-6);
+      int limit = int(LIMIT_FACTOR * std::sqrt(double(_res_node_num)));
+      if (limit < MIN_LIMIT) limit = MIN_LIMIT;
+      int iter = limit;
+      while (epsilon * _res_node_num >= 1) {
+        // Find and cancel cycles in the admissible network using DFS
+        for (int u = 0; u != _res_node_num; ++u) {
+          reached[u] = false;
+          processed[u] = false;
+        }
+        int stack_head = -1;
+        int proc_head = -1;
+        for (int start = 0; start != _res_node_num; ++start) {
+          if (reached[start]) continue;
+
+          // New start node
+          reached[start] = true;
+          pred_arc[start] = -1;
+          pred_node[start] = -1;
+
+          // Find the first admissible outgoing arc
+          double p = pi[start];
+          int a = _first_out[start];
+          int last_out = _first_out[start+1];
+          for (; a != last_out && (_res_cap[a] == 0 ||
+               !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
+          if (a == last_out) {
+            processed[start] = true;
+            proc_vector[++proc_head] = start;
+            continue;
+          }
+          stack[++stack_head] = a;
+
+          while (stack_head >= 0) {
+            int sa = stack[stack_head];
+            int u = _source[sa];
+            int v = _target[sa];
+
+            if (!reached[v]) {
+              // A new node is reached
+              reached[v] = true;
+              pred_node[v] = u;
+              pred_arc[v] = sa;
+              p = pi[v];
+              a = _first_out[v];
+              last_out = _first_out[v+1];
+              for (; a != last_out && (_res_cap[a] == 0 ||
+                   !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
+              stack[++stack_head] = a == last_out ? -1 : a;
+            } else {
+              if (!processed[v]) {
+                // A cycle is found
+                int n, w = u;
+                Value d, delta = _res_cap[sa];
+                for (n = u; n != v; n = pred_node[n]) {
+                  d = _res_cap[pred_arc[n]];
+                  if (d <= delta) {
+                    delta = d;
+                    w = pred_node[n];
+                  }
+                }
+
+                // Augment along the cycle
+                _res_cap[sa] -= delta;
+                _res_cap[_reverse[sa]] += delta;
+                for (n = u; n != v; n = pred_node[n]) {
+                  int pa = pred_arc[n];
+                  _res_cap[pa] -= delta;
+                  _res_cap[_reverse[pa]] += delta;
+                }
+                for (n = u; stack_head > 0 && n != w; n = pred_node[n]) {
+                  --stack_head;
+                  reached[n] = false;
+                }
+                u = w;
+              }
+              v = u;
+
+              // Find the next admissible outgoing arc
+              p = pi[v];
+              a = stack[stack_head] + 1;
+              last_out = _first_out[v+1];
+              for (; a != last_out && (_res_cap[a] == 0 ||
+                   !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
+              stack[stack_head] = a == last_out ? -1 : a;
+            }
+
+            while (stack_head >= 0 && stack[stack_head] == -1) {
+              processed[v] = true;
+              proc_vector[++proc_head] = v;
+              if (--stack_head >= 0) {
+                // Find the next admissible outgoing arc
+                v = _source[stack[stack_head]];
+                p = pi[v];
+                a = stack[stack_head] + 1;
+                last_out = _first_out[v+1];
+                for (; a != last_out && (_res_cap[a] == 0 ||
+                     !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
+                stack[stack_head] = a == last_out ? -1 : a;
+              }
+            }
+          }
+        }
+
+        // Tighten potentials and epsilon
+        if (--iter > 0) {
+          for (int u = 0; u != _res_node_num; ++u) {
+            level[u] = 0;
+          }
+          for (int i = proc_head; i > 0; --i) {
+            int u = proc_vector[i];
+            double p = pi[u];
+            int l = level[u] + 1;
+            int last_out = _first_out[u+1];
+            for (int a = _first_out[u]; a != last_out; ++a) {
+              int v = _target[a];
+              if (_res_cap[a] > 0 && tol.negative(_cost[a] + p - pi[v]) &&
+                  l > level[v]) level[v] = l;
+            }
+          }
+
+          // Modify potentials
+          double q = std::numeric_limits<double>::max();
+          for (int u = 0; u != _res_node_num; ++u) {
+            int lu = level[u];
+            double p, pu = pi[u];
+            int last_out = _first_out[u+1];
+            for (int a = _first_out[u]; a != last_out; ++a) {
+              if (_res_cap[a] == 0) continue;
+              int v = _target[a];
+              int ld = lu - level[v];
+              if (ld > 0) {
+                p = (_cost[a] + pu - pi[v] + epsilon) / (ld + 1);
+                if (p < q) q = p;
+              }
+            }
+          }
+          for (int u = 0; u != _res_node_num; ++u) {
+            pi[u] -= q * level[u];
+          }
+
+          // Modify epsilon
+          epsilon = 0;
+          for (int u = 0; u != _res_node_num; ++u) {
+            double curr, pu = pi[u];
+            int last_out = _first_out[u+1];
+            for (int a = _first_out[u]; a != last_out; ++a) {
+              if (_res_cap[a] == 0) continue;
+              curr = _cost[a] + pu - pi[_target[a]];
+              if (-curr > epsilon) epsilon = -curr;
+            }
+          }
+        } else {
+          typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc;
+          typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc;
+          typedef typename BellmanFord<StaticDigraph, CostArcMap>
+            ::template SetDistMap<CostNodeMap>::Create BF;
+
+          // Set epsilon to the minimum cycle mean
+          Cost cycle_cost = 0;
+          int cycle_size = 1;
+          buildResidualNetwork();
+          HwMmc hw_mmc(_sgr, _cost_map);
+          if (hw_mmc.findCycleMean(hw_iter_limit) == HwMmc::ITERATION_LIMIT) {
+            // Howard's algorithm reached the iteration limit, start a
+            // strongly polynomial algorithm instead
+            HoMmc ho_mmc(_sgr, _cost_map);
+            ho_mmc.findCycleMean();
+            epsilon = -ho_mmc.cycleMean();
+            cycle_cost = ho_mmc.cycleCost();
+            cycle_size = ho_mmc.cycleSize();
+          } else {
+            // Set epsilon
+            epsilon = -hw_mmc.cycleMean();
+            cycle_cost = hw_mmc.cycleCost();
+            cycle_size = hw_mmc.cycleSize();
+          }
+
+          // Compute feasible potentials for the current epsilon
+          for (int i = 0; i != int(_cost_vec.size()); ++i) {
+            _cost_vec[i] = cycle_size * _cost_vec[i] - cycle_cost;
+          }
+          BF bf(_sgr, _cost_map);
+          bf.distMap(_pi_map);
+          bf.init(0);
+          bf.start();
+          for (int u = 0; u != _res_node_num; ++u) {
+            pi[u] = static_cast<double>(_pi[u]) / cycle_size;
+          }
+
+          iter = limit;
+        }
+      }
+    }
+
+  }; //class CycleCanceling
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_CYCLE_CANCELING_H
diff --git a/lemon/dfs.h b/lemon/dfs.h
new file mode 100644
index 0000000..6e9e84a
--- /dev/null
+++ b/lemon/dfs.h
@@ -0,0 +1,1637 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_DFS_H
+#define LEMON_DFS_H
+
+///\ingroup search
+///\file
+///\brief DFS algorithm.
+
+#include <lemon/list_graph.h>
+#include <lemon/bits/path_dump.h>
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+
+namespace lemon {
+
+  ///Default traits class of Dfs class.
+
+  ///Default traits class of Dfs class.
+  ///\tparam GR Digraph type.
+  template<class GR>
+  struct DfsDefaultTraits
+  {
+    ///The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    ///\brief The type of the map that stores the predecessor
+    ///arcs of the %DFS paths.
+    ///
+    ///The type of the map that stores the predecessor
+    ///arcs of the %DFS paths.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+    ///Instantiates a \c PredMap.
+
+    ///This function instantiates a \ref PredMap.
+    ///\param g is the digraph, to which we would like to define the
+    ///\ref PredMap.
+    static PredMap *createPredMap(const Digraph &g)
+    {
+      return new PredMap(g);
+    }
+
+    ///The type of the map that indicates which nodes are processed.
+
+    ///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.
+    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
+    ///Instantiates a \c ProcessedMap.
+
+    ///This function instantiates a \ref ProcessedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the \ref ProcessedMap.
+#ifdef DOXYGEN
+    static ProcessedMap *createProcessedMap(const Digraph &g)
+#else
+    static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+    {
+      return new ProcessedMap();
+    }
+
+    ///The type of the map that indicates which nodes are reached.
+
+    ///The type of the map that indicates which nodes are reached.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Digraph::template NodeMap<bool> ReachedMap;
+    ///Instantiates a \c ReachedMap.
+
+    ///This function instantiates a \ref ReachedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the \ref ReachedMap.
+    static ReachedMap *createReachedMap(const Digraph &g)
+    {
+      return new ReachedMap(g);
+    }
+
+    ///The type of the map that stores the distances of the nodes.
+
+    ///The type of the map that stores the distances of the nodes.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<int> DistMap;
+    ///Instantiates a \c DistMap.
+
+    ///This function instantiates a \ref DistMap.
+    ///\param g is the digraph, to which we would like to define the
+    ///\ref DistMap.
+    static DistMap *createDistMap(const Digraph &g)
+    {
+      return new DistMap(g);
+    }
+  };
+
+  ///%DFS algorithm class.
+
+  ///\ingroup search
+  ///This class provides an efficient implementation of the %DFS algorithm.
+  ///
+  ///There is also a \ref dfs() "function-type interface" for the DFS
+  ///algorithm, which is convenient in the simplier cases and it can be
+  ///used easier.
+  ///
+  ///\tparam GR The type of the digraph the algorithm runs on.
+  ///The default type is \ref ListDigraph.
+  ///\tparam 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,
+            typename TR>
+#else
+  template <typename GR=ListDigraph,
+            typename TR=DfsDefaultTraits<GR> >
+#endif
+  class Dfs {
+  public:
+
+    ///The type of the digraph the algorithm runs on.
+    typedef typename TR::Digraph Digraph;
+
+    ///\brief The type of the map that stores the predecessor arcs of the
+    ///DFS paths.
+    typedef typename TR::PredMap PredMap;
+    ///The type of the map that stores the distances of the nodes.
+    typedef typename TR::DistMap DistMap;
+    ///The type of the map that indicates which nodes are reached.
+    typedef typename TR::ReachedMap ReachedMap;
+    ///The type of the map that indicates which nodes are processed.
+    typedef typename TR::ProcessedMap ProcessedMap;
+    ///The type of the paths.
+    typedef PredMapPath<Digraph, PredMap> Path;
+
+    ///The \ref lemon::DfsDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    //Pointer to the underlying digraph.
+    const Digraph *G;
+    //Pointer to the map of predecessor arcs.
+    PredMap *_pred;
+    //Indicates if _pred is locally allocated (true) or not.
+    bool local_pred;
+    //Pointer to the map of distances.
+    DistMap *_dist;
+    //Indicates if _dist is locally allocated (true) or not.
+    bool local_dist;
+    //Pointer to the map of reached status of the nodes.
+    ReachedMap *_reached;
+    //Indicates if _reached is locally allocated (true) or not.
+    bool local_reached;
+    //Pointer to the map of processed status of the nodes.
+    ProcessedMap *_processed;
+    //Indicates if _processed is locally allocated (true) or not.
+    bool local_processed;
+
+    std::vector<typename Digraph::OutArcIt> _stack;
+    int _stack_head;
+
+    //Creates the maps if necessary.
+    void create_maps()
+    {
+      if(!_pred) {
+        local_pred = true;
+        _pred = Traits::createPredMap(*G);
+      }
+      if(!_dist) {
+        local_dist = true;
+        _dist = Traits::createDistMap(*G);
+      }
+      if(!_reached) {
+        local_reached = true;
+        _reached = Traits::createReachedMap(*G);
+      }
+      if(!_processed) {
+        local_processed = true;
+        _processed = Traits::createProcessedMap(*G);
+      }
+    }
+
+  protected:
+
+    Dfs() {}
+
+  public:
+
+    typedef Dfs Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <class T>
+    struct SetPredMapTraits : public Traits {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "PredMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c PredMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c PredMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
+      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetDistMapTraits : public Traits {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "DistMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c DistMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c DistMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
+      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetReachedMapTraits : public Traits {
+      typedef T ReachedMap;
+      static ReachedMap *createReachedMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "ReachedMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c ReachedMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c ReachedMap type.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    template <class T>
+    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
+      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetProcessedMapTraits : public Traits {
+      typedef T ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "ProcessedMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
+      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
+    };
+
+    struct SetStandardProcessedMapTraits : public Traits {
+      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &g)
+      {
+        return new ProcessedMap(g);
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///If you don't set it explicitly, it will be automatically allocated.
+    struct SetStandardProcessedMap :
+      public Dfs< Digraph, SetStandardProcessedMapTraits > {
+      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
+    };
+
+    ///@}
+
+  public:
+
+    ///Constructor.
+
+    ///Constructor.
+    ///\param g The digraph the algorithm runs on.
+    Dfs(const Digraph &g) :
+      G(&g),
+      _pred(NULL), local_pred(false),
+      _dist(NULL), local_dist(false),
+      _reached(NULL), local_reached(false),
+      _processed(NULL), local_processed(false)
+    { }
+
+    ///Destructor.
+    ~Dfs()
+    {
+      if(local_pred) delete _pred;
+      if(local_dist) delete _dist;
+      if(local_reached) delete _reached;
+      if(local_processed) delete _processed;
+    }
+
+    ///Sets the map that stores the predecessor arcs.
+
+    ///Sets the map that stores the predecessor arcs.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Dfs &predMap(PredMap &m)
+    {
+      if(local_pred) {
+        delete _pred;
+        local_pred=false;
+      }
+      _pred = &m;
+      return *this;
+    }
+
+    ///Sets the map that indicates which nodes are reached.
+
+    ///Sets the map that indicates which nodes are reached.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Dfs &reachedMap(ReachedMap &m)
+    {
+      if(local_reached) {
+        delete _reached;
+        local_reached=false;
+      }
+      _reached = &m;
+      return *this;
+    }
+
+    ///Sets the map that indicates which nodes are processed.
+
+    ///Sets the map that indicates which nodes are processed.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Dfs &processedMap(ProcessedMap &m)
+    {
+      if(local_processed) {
+        delete _processed;
+        local_processed=false;
+      }
+      _processed = &m;
+      return *this;
+    }
+
+    ///Sets the map that stores the distances of the nodes.
+
+    ///Sets the map that stores the distances of the nodes calculated by
+    ///the algorithm.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Dfs &distMap(DistMap &m)
+    {
+      if(local_dist) {
+        delete _dist;
+        local_dist=false;
+      }
+      _dist = &m;
+      return *this;
+    }
+
+  public:
+
+    ///\name Execution Control
+    ///The simplest way to execute the DFS algorithm is to use one of the
+    ///member functions called \ref run(Node) "run()".\n
+    ///If you need better control on the execution, you have to call
+    ///\ref init() first, then you can add a source node with \ref addSource()
+    ///and perform the actual computation with \ref start().
+    ///This procedure can be repeated if there are nodes that have not
+    ///been reached.
+
+    ///@{
+
+    ///\brief Initializes the internal data structures.
+    ///
+    ///Initializes the internal data structures.
+    void init()
+    {
+      create_maps();
+      _stack.resize(countNodes(*G));
+      _stack_head=-1;
+      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
+        _pred->set(u,INVALID);
+        _reached->set(u,false);
+        _processed->set(u,false);
+      }
+    }
+
+    ///Adds a new source node.
+
+    ///Adds a new source node to the set of nodes to be processed.
+    ///
+    ///\pre The stack must be empty. Otherwise the algorithm gives
+    ///wrong results. (One of the outgoing arcs of all the source nodes
+    ///except for the last one will not be visited and distances will
+    ///also be wrong.)
+    void addSource(Node s)
+    {
+      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
+      if(!(*_reached)[s])
+        {
+          _reached->set(s,true);
+          _pred->set(s,INVALID);
+          OutArcIt e(*G,s);
+          if(e!=INVALID) {
+            _stack[++_stack_head]=e;
+            _dist->set(s,_stack_head);
+          }
+          else {
+            _processed->set(s,true);
+            _dist->set(s,0);
+          }
+        }
+    }
+
+    ///Processes the next arc.
+
+    ///Processes the next arc.
+    ///
+    ///\return The processed arc.
+    ///
+    ///\pre The stack must not be empty.
+    Arc processNextArc()
+    {
+      Node m;
+      Arc e=_stack[_stack_head];
+      if(!(*_reached)[m=G->target(e)]) {
+        _pred->set(m,e);
+        _reached->set(m,true);
+        ++_stack_head;
+        _stack[_stack_head] = OutArcIt(*G, m);
+        _dist->set(m,_stack_head);
+      }
+      else {
+        m=G->source(e);
+        ++_stack[_stack_head];
+      }
+      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
+        _processed->set(m,true);
+        --_stack_head;
+        if(_stack_head>=0) {
+          m=G->source(_stack[_stack_head]);
+          ++_stack[_stack_head];
+        }
+      }
+      return e;
+    }
+
+    ///Next arc to be processed.
+
+    ///Next arc to be processed.
+    ///
+    ///\return The next arc to be processed or \c INVALID if the stack
+    ///is empty.
+    OutArcIt nextArc() const
+    {
+      return _stack_head>=0?_stack[_stack_head]:INVALID;
+    }
+
+    ///Returns \c false if there are nodes to be processed.
+
+    ///Returns \c false if there are nodes to be processed
+    ///in the queue (stack).
+    bool emptyQueue() const { return _stack_head<0; }
+
+    ///Returns the number of the nodes to be processed.
+
+    ///Returns the number of the nodes to be processed
+    ///in the queue (stack).
+    int queueSize() const { return _stack_head+1; }
+
+    ///Executes the algorithm.
+
+    ///Executes the algorithm.
+    ///
+    ///This method runs the %DFS algorithm from the root node
+    ///in order to compute the DFS path to each node.
+    ///
+    /// The algorithm computes
+    ///- the %DFS tree,
+    ///- the distance of each node from the root in the %DFS tree.
+    ///
+    ///\pre init() must be called and a root node should be
+    ///added with addSource() before using this function.
+    ///
+    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
+    ///\code
+    ///  while ( !d.emptyQueue() ) {
+    ///    d.processNextArc();
+    ///  }
+    ///\endcode
+    void start()
+    {
+      while ( !emptyQueue() ) processNextArc();
+    }
+
+    ///Executes the algorithm until the given target node is reached.
+
+    ///Executes the algorithm until the given target node is reached.
+    ///
+    ///This method runs the %DFS algorithm from the root node
+    ///in order to compute the DFS path to \c t.
+    ///
+    ///The algorithm computes
+    ///- the %DFS path to \c t,
+    ///- the distance of \c t from the root in the %DFS tree.
+    ///
+    ///\pre init() must be called and a root node should be
+    ///added with addSource() before using this function.
+    void start(Node t)
+    {
+      while ( !emptyQueue() && !(*_reached)[t] )
+        processNextArc();
+    }
+
+    ///Executes the algorithm until a condition is met.
+
+    ///Executes the algorithm until a condition is met.
+    ///
+    ///This method runs the %DFS algorithm from the root node
+    ///until an arc \c a with <tt>am[a]</tt> true is found.
+    ///
+    ///\param am A \c bool (or convertible) arc map. The algorithm
+    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
+    ///
+    ///\return The reached arc \c a with <tt>am[a]</tt> true or
+    ///\c INVALID if no such arc was found.
+    ///
+    ///\pre init() must be called and a root node should be
+    ///added with addSource() before using this function.
+    ///
+    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
+    ///not a node map.
+    template<class ArcBoolMap>
+    Arc start(const ArcBoolMap &am)
+    {
+      while ( !emptyQueue() && !am[_stack[_stack_head]] )
+        processNextArc();
+      return emptyQueue() ? INVALID : _stack[_stack_head];
+    }
+
+    ///Runs the algorithm from the given source node.
+
+    ///This method runs the %DFS algorithm from node \c s
+    ///in order to compute the DFS path to each node.
+    ///
+    ///The algorithm computes
+    ///- the %DFS tree,
+    ///- the distance of each node from the root in the %DFS tree.
+    ///
+    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
+    ///\code
+    ///  d.init();
+    ///  d.addSource(s);
+    ///  d.start();
+    ///\endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    ///Finds the %DFS path between \c s and \c t.
+
+    ///This method runs the %DFS algorithm from node \c s
+    ///in order to compute the DFS path to node \c t
+    ///(it stops searching when \c t is processed)
+    ///
+    ///\return \c true if \c t is reachable form \c s.
+    ///
+    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
+    ///just a shortcut of the following code.
+    ///\code
+    ///  d.init();
+    ///  d.addSource(s);
+    ///  d.start(t);
+    ///\endcode
+    bool run(Node s,Node t) {
+      init();
+      addSource(s);
+      start(t);
+      return reached(t);
+    }
+
+    ///Runs the algorithm to visit all nodes in the digraph.
+
+    ///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.
+    ///\code
+    ///  d.init();
+    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
+    ///    if (!d.reached(n)) {
+    ///      d.addSource(n);
+    ///      d.start();
+    ///    }
+    ///  }
+    ///\endcode
+    void run() {
+      init();
+      for (NodeIt it(*G); it != INVALID; ++it) {
+        if (!reached(it)) {
+          addSource(it);
+          start();
+        }
+      }
+    }
+
+    ///@}
+
+    ///\name Query Functions
+    ///The results of the DFS algorithm can be obtained using these
+    ///functions.\n
+    ///Either \ref run(Node) "run()" or \ref start() should be called
+    ///before using them.
+
+    ///@{
+
+    ///The DFS path to the given node.
+
+    ///Returns the DFS path to the given node from the root(s).
+    ///
+    ///\warning \c t should be reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Path path(Node t) const { return Path(*G, *_pred, t); }
+
+    ///The distance of the given node from the root(s).
+
+    ///Returns the distance of the given node from the root(s).
+    ///
+    ///\warning If node \c v is not reached from the root(s), then
+    ///the return value of this function is undefined.
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    int dist(Node v) const { return (*_dist)[v]; }
+
+    ///Returns the 'previous arc' of the %DFS tree for the given node.
+
+    ///This function returns the 'previous arc' of the %DFS tree for the
+    ///node \c v, i.e. it returns the last arc of a %DFS path from a
+    ///root to \c v. It is \c INVALID if \c v is not reached from the
+    ///root(s) or if \c v is a root.
+    ///
+    ///The %DFS tree used here is equal to the %DFS tree used in
+    ///\ref predNode() and \ref predMap().
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Arc predArc(Node v) const { return (*_pred)[v];}
+
+    ///Returns the 'previous node' of the %DFS tree for the given node.
+
+    ///This function returns the 'previous node' of the %DFS
+    ///tree for the node \c v, i.e. it returns the last but one node
+    ///of a %DFS path from a root to \c v. It is \c INVALID
+    ///if \c v is not reached from the root(s) or if \c v is a root.
+    ///
+    ///The %DFS tree used here is equal to the %DFS tree used in
+    ///\ref predArc() and \ref predMap().
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
+                                  G->source((*_pred)[v]); }
+
+    ///\brief Returns a const reference to the node map that stores the
+    ///distances of the nodes.
+    ///
+    ///Returns a const reference to the node map that stores the
+    ///distances of the nodes calculated by the algorithm.
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    const DistMap &distMap() const { return *_dist;}
+
+    ///\brief Returns a const reference to the node map that stores the
+    ///predecessor arcs.
+    ///
+    ///Returns a const reference to the node map that stores the predecessor
+    ///arcs, which form the DFS tree (forest).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    const PredMap &predMap() const { return *_pred;}
+
+    ///Checks if the given node. node is reached from the root(s).
+
+    ///Returns \c true if \c v is reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    bool reached(Node v) const { return (*_reached)[v]; }
+
+    ///@}
+  };
+
+  ///Default traits class of dfs() function.
+
+  ///Default traits class of dfs() function.
+  ///\tparam GR Digraph type.
+  template<class GR>
+  struct DfsWizardDefaultTraits
+  {
+    ///The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    ///\brief The type of the map that stores the predecessor
+    ///arcs of the %DFS paths.
+    ///
+    ///The type of the map that stores the predecessor
+    ///arcs of the %DFS paths.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+    ///Instantiates a PredMap.
+
+    ///This function instantiates a PredMap.
+    ///\param g is the digraph, to which we would like to define the
+    ///PredMap.
+    static PredMap *createPredMap(const Digraph &g)
+    {
+      return new PredMap(g);
+    }
+
+    ///The type of the map that indicates which nodes are processed.
+
+    ///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.
+    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
+    ///Instantiates a ProcessedMap.
+
+    ///This function instantiates a ProcessedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the ProcessedMap.
+#ifdef DOXYGEN
+    static ProcessedMap *createProcessedMap(const Digraph &g)
+#else
+    static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+    {
+      return new ProcessedMap();
+    }
+
+    ///The type of the map that indicates which nodes are reached.
+
+    ///The type of the map that indicates which nodes are reached.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Digraph::template NodeMap<bool> ReachedMap;
+    ///Instantiates a ReachedMap.
+
+    ///This function instantiates a ReachedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the ReachedMap.
+    static ReachedMap *createReachedMap(const Digraph &g)
+    {
+      return new ReachedMap(g);
+    }
+
+    ///The type of the map that stores the distances of the nodes.
+
+    ///The type of the map that stores the distances of the nodes.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<int> DistMap;
+    ///Instantiates a DistMap.
+
+    ///This function instantiates a DistMap.
+    ///\param g is the digraph, to which we would like to define
+    ///the DistMap
+    static DistMap *createDistMap(const Digraph &g)
+    {
+      return new DistMap(g);
+    }
+
+    ///The type of the DFS paths.
+
+    ///The type of the DFS paths.
+    ///It must conform to the \ref concepts::Path "Path" concept.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  /// Default traits class used by DfsWizard
+
+  /// Default traits class used by DfsWizard.
+  /// \tparam GR The type of the digraph.
+  template<class GR>
+  class DfsWizardBase : public DfsWizardDefaultTraits<GR>
+  {
+
+    typedef DfsWizardDefaultTraits<GR> Base;
+  protected:
+    //The type of the nodes in the digraph.
+    typedef typename Base::Digraph::Node Node;
+
+    //Pointer to the digraph the algorithm runs on.
+    void *_g;
+    //Pointer to the map of reached nodes.
+    void *_reached;
+    //Pointer to the map of processed nodes.
+    void *_processed;
+    //Pointer to the map of predecessors arcs.
+    void *_pred;
+    //Pointer to the map of distances.
+    void *_dist;
+    //Pointer to the DFS path to the target node.
+    void *_path;
+    //Pointer to the distance of the target node.
+    int *_di;
+
+    public:
+    /// Constructor.
+
+    /// This constructor does not require parameters, it initiates
+    /// all of the attributes to \c 0.
+    DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
+                      _dist(0), _path(0), _di(0) {}
+
+    /// Constructor.
+
+    /// This constructor requires one parameter,
+    /// others are initiated to \c 0.
+    /// \param g The digraph the algorithm runs on.
+    DfsWizardBase(const GR &g) :
+      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
+      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
+
+  };
+
+  /// Auxiliary class for the function-type interface of DFS algorithm.
+
+  /// This auxiliary class is created to implement the
+  /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
+  /// It does not have own \ref run(Node) "run()" method, it uses the
+  /// functions and features of the plain \ref Dfs.
+  ///
+  /// This class should only be used through the \ref dfs() function,
+  /// 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
+  {
+    typedef TR Base;
+
+    typedef typename TR::Digraph Digraph;
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    typedef typename TR::PredMap PredMap;
+    typedef typename TR::DistMap DistMap;
+    typedef typename TR::ReachedMap ReachedMap;
+    typedef typename TR::ProcessedMap ProcessedMap;
+    typedef typename TR::Path Path;
+
+  public:
+
+    /// Constructor.
+    DfsWizard() : TR() {}
+
+    /// Constructor that requires parameters.
+
+    /// Constructor that requires parameters.
+    /// These parameters will be the default values for the traits class.
+    /// \param g The digraph the algorithm runs on.
+    DfsWizard(const Digraph &g) :
+      TR(g) {}
+
+    ///Copy constructor
+    DfsWizard(const TR &b) : TR(b) {}
+
+    ~DfsWizard() {}
+
+    ///Runs DFS algorithm from the given source node.
+
+    ///This method runs DFS algorithm from node \c s
+    ///in order to compute the DFS path to each node.
+    void run(Node s)
+    {
+      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
+      if (Base::_pred)
+        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist)
+        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      if (Base::_reached)
+        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
+      if (Base::_processed)
+        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+      if (s!=INVALID)
+        alg.run(s);
+      else
+        alg.run();
+    }
+
+    ///Finds the DFS path between \c s and \c t.
+
+    ///This method runs DFS algorithm from node \c s
+    ///in order to compute the DFS path to node \c t
+    ///(it stops searching when \c t is processed).
+    ///
+    ///\return \c true if \c t is reachable form \c s.
+    bool run(Node s, Node t)
+    {
+      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
+      if (Base::_pred)
+        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist)
+        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      if (Base::_reached)
+        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
+      if (Base::_processed)
+        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+      alg.run(s,t);
+      if (Base::_path)
+        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
+      if (Base::_di)
+        *Base::_di = alg.dist(t);
+      return alg.reached(t);
+      }
+
+    ///Runs DFS algorithm to visit all nodes in the digraph.
+
+    ///This method runs DFS algorithm in order to visit all nodes
+    ///in the digraph.
+    void run()
+    {
+      run(INVALID);
+    }
+
+    template<class T>
+    struct SetPredMapBase : public Base {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &) { return 0; };
+      SetPredMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the predecessor map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the predecessor arcs of the nodes.
+    template<class T>
+    DfsWizard<SetPredMapBase<T> > predMap(const T &t)
+    {
+      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DfsWizard<SetPredMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetReachedMapBase : public Base {
+      typedef T ReachedMap;
+      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
+      SetReachedMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the reached map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are reached.
+    template<class T>
+    DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
+    {
+      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DfsWizard<SetReachedMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetDistMapBase : public Base {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph &) { return 0; };
+      SetDistMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the distance map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the distances of the nodes calculated
+    ///by the algorithm.
+    template<class T>
+    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
+    {
+      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DfsWizard<SetDistMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetProcessedMapBase : public Base {
+      typedef T ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
+      SetProcessedMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-func-param "Named parameter" for setting
+    ///the processed map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are processed.
+    template<class T>
+    DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
+    {
+      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DfsWizard<SetProcessedMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetPathBase : public Base {
+      typedef T Path;
+      SetPathBase(const TR &b) : TR(b) {}
+    };
+    ///\brief \ref named-func-param "Named parameter"
+    ///for getting the DFS path to the target node.
+    ///
+    ///\ref named-func-param "Named parameter"
+    ///for getting the DFS path to the target node.
+    template<class T>
+    DfsWizard<SetPathBase<T> > path(const T &t)
+    {
+      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DfsWizard<SetPathBase<T> >(*this);
+    }
+
+    ///\brief \ref named-func-param "Named parameter"
+    ///for getting the distance of the target node.
+    ///
+    ///\ref named-func-param "Named parameter"
+    ///for getting the distance of the target node.
+    DfsWizard dist(const int &d)
+    {
+      Base::_di=const_cast<int*>(&d);
+      return *this;
+    }
+
+  };
+
+  ///Function-type interface for DFS algorithm.
+
+  ///\ingroup search
+  ///Function-type interface for DFS algorithm.
+  ///
+  ///This function also has several \ref named-func-param "named parameters",
+  ///they are declared as the members of class \ref DfsWizard.
+  ///The following examples show how to use these parameters.
+  ///\code
+  ///  // Compute the DFS tree
+  ///  dfs(g).predMap(preds).distMap(dists).run(s);
+  ///
+  ///  // Compute the DFS path from s to t
+  ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
+  ///\endcode
+  ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
+  ///to the end of the parameter list.
+  ///\sa DfsWizard
+  ///\sa Dfs
+  template<class GR>
+  DfsWizard<DfsWizardBase<GR> >
+  dfs(const GR &digraph)
+  {
+    return DfsWizard<DfsWizardBase<GR> >(digraph);
+  }
+
+#ifdef DOXYGEN
+  /// \brief Visitor class for DFS.
+  ///
+  /// This class defines the interface of the DfsVisit events, and
+  /// it could be the base of a real visitor class.
+  template <typename GR>
+  struct DfsVisitor {
+    typedef GR Digraph;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::Node Node;
+    /// \brief Called for the source node of the DFS.
+    ///
+    /// This function is called for the source node of the DFS.
+    void start(const Node& node) {}
+    /// \brief Called when the source node is leaved.
+    ///
+    /// This function is called when the source node is leaved.
+    void stop(const Node& node) {}
+    /// \brief Called when a node is reached first time.
+    ///
+    /// This function is called when a node is reached first time.
+    void reach(const Node& node) {}
+    /// \brief Called when an arc reaches a new node.
+    ///
+    /// This function is called when the DFS finds an arc whose target node
+    /// is not reached yet.
+    void discover(const Arc& arc) {}
+    /// \brief Called when an arc is examined but its target node is
+    /// already discovered.
+    ///
+    /// This function is called when an arc is examined but its target node is
+    /// already discovered.
+    void examine(const Arc& arc) {}
+    /// \brief Called when the DFS steps back from a node.
+    ///
+    /// This function is called when the DFS steps back from a node.
+    void leave(const Node& node) {}
+    /// \brief Called when the DFS steps back on an arc.
+    ///
+    /// This function is called when the DFS steps back on an arc.
+    void backtrack(const Arc& arc) {}
+  };
+#else
+  template <typename GR>
+  struct DfsVisitor {
+    typedef GR Digraph;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::Node Node;
+    void start(const Node&) {}
+    void stop(const Node&) {}
+    void reach(const Node&) {}
+    void discover(const Arc&) {}
+    void examine(const Arc&) {}
+    void leave(const Node&) {}
+    void backtrack(const Arc&) {}
+
+    template <typename _Visitor>
+    struct Constraints {
+      void constraints() {
+        Arc arc;
+        Node node;
+        visitor.start(node);
+        visitor.stop(arc);
+        visitor.reach(node);
+        visitor.discover(arc);
+        visitor.examine(arc);
+        visitor.leave(node);
+        visitor.backtrack(arc);
+      }
+      _Visitor& visitor;
+      Constraints() {}
+    };
+  };
+#endif
+
+  /// \brief Default traits class of DfsVisit class.
+  ///
+  /// Default traits class of DfsVisit class.
+  /// \tparam _Digraph The type of the digraph the algorithm runs on.
+  template<class GR>
+  struct DfsVisitDefaultTraits {
+
+    /// \brief The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that indicates which nodes are reached.
+    ///
+    /// The type of the map that indicates which nodes are reached.
+    /// It must conform to the
+    /// \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Digraph::template NodeMap<bool> ReachedMap;
+
+    /// \brief Instantiates a ReachedMap.
+    ///
+    /// This function instantiates a ReachedMap.
+    /// \param digraph is the digraph, to which
+    /// we would like to define the ReachedMap.
+    static ReachedMap *createReachedMap(const Digraph &digraph) {
+      return new ReachedMap(digraph);
+    }
+
+  };
+
+  /// \ingroup search
+  ///
+  /// \brief DFS algorithm class with visitor interface.
+  ///
+  /// This class provides an efficient implementation of the DFS algorithm
+  /// with visitor interface.
+  ///
+  /// The DfsVisit class provides an alternative interface to the Dfs
+  /// class. It works with callback mechanism, the DfsVisit object calls
+  /// the member functions of the \c Visitor class on every DFS event.
+  ///
+  /// This interface of the DFS algorithm should be used in special cases
+  /// when extra actions have to be performed in connection with certain
+  /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
+  /// instead.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// The default type is \ref ListDigraph.
+  /// The value of GR is not used directly by \ref DfsVisit,
+  /// it is only passed to \ref DfsVisitDefaultTraits.
+  /// \tparam VS The Visitor type that is used by the algorithm.
+  /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
+  /// does not observe the DFS events. If you want to observe the DFS
+  /// events, you should implement your own visitor class.
+  /// \tparam 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>
+#else
+  template <typename GR = ListDigraph,
+            typename VS = DfsVisitor<GR>,
+            typename TR = DfsVisitDefaultTraits<GR> >
+#endif
+  class DfsVisit {
+  public:
+
+    ///The traits class.
+    typedef TR Traits;
+
+    ///The type of the digraph the algorithm runs on.
+    typedef typename Traits::Digraph Digraph;
+
+    ///The visitor type used by the algorithm.
+    typedef VS Visitor;
+
+    ///The type of the map that indicates which nodes are reached.
+    typedef typename Traits::ReachedMap ReachedMap;
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    //Pointer to the underlying digraph.
+    const Digraph *_digraph;
+    //Pointer to the visitor object.
+    Visitor *_visitor;
+    //Pointer to the map of reached status of the nodes.
+    ReachedMap *_reached;
+    //Indicates if _reached is locally allocated (true) or not.
+    bool local_reached;
+
+    std::vector<typename Digraph::Arc> _stack;
+    int _stack_head;
+
+    //Creates the maps if necessary.
+    void create_maps() {
+      if(!_reached) {
+        local_reached = true;
+        _reached = Traits::createReachedMap(*_digraph);
+      }
+    }
+
+  protected:
+
+    DfsVisit() {}
+
+  public:
+
+    typedef DfsVisit Create;
+
+    /// \name Named Template Parameters
+
+    ///@{
+    template <class T>
+    struct SetReachedMapTraits : public Traits {
+      typedef T ReachedMap;
+      static ReachedMap *createReachedMap(const Digraph &digraph) {
+        LEMON_ASSERT(false, "ReachedMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// ReachedMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
+    template <class T>
+    struct SetReachedMap : public DfsVisit< Digraph, Visitor,
+                                            SetReachedMapTraits<T> > {
+      typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
+    };
+    ///@}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param visitor The visitor object of the algorithm.
+    DfsVisit(const Digraph& digraph, Visitor& visitor)
+      : _digraph(&digraph), _visitor(&visitor),
+        _reached(0), local_reached(false) {}
+
+    /// \brief Destructor.
+    ~DfsVisit() {
+      if(local_reached) delete _reached;
+    }
+
+    /// \brief Sets the map that indicates which nodes are reached.
+    ///
+    /// Sets the map that indicates which nodes are reached.
+    /// If you don't use this function before calling \ref run(Node) "run()"
+    /// or \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt> (*this) </tt>
+    DfsVisit &reachedMap(ReachedMap &m) {
+      if(local_reached) {
+        delete _reached;
+        local_reached=false;
+      }
+      _reached = &m;
+      return *this;
+    }
+
+  public:
+
+    /// \name Execution Control
+    /// The simplest way to execute the DFS algorithm is to use one of the
+    /// member functions called \ref run(Node) "run()".\n
+    /// If you need better control on the execution, you have to call
+    /// \ref init() first, then you can add a source node with \ref addSource()
+    /// and perform the actual computation with \ref start().
+    /// This procedure can be repeated if there are nodes that have not
+    /// been reached.
+
+    /// @{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures.
+    void init() {
+      create_maps();
+      _stack.resize(countNodes(*_digraph));
+      _stack_head = -1;
+      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
+        _reached->set(u, false);
+      }
+    }
+
+    /// \brief Adds a new source node.
+    ///
+    /// Adds a new source node to the set of nodes to be processed.
+    ///
+    /// \pre The stack must be empty. Otherwise the algorithm gives
+    /// wrong results. (One of the outgoing arcs of all the source nodes
+    /// except for the last one will not be visited and distances will
+    /// also be wrong.)
+    void addSource(Node s)
+    {
+      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
+      if(!(*_reached)[s]) {
+          _reached->set(s,true);
+          _visitor->start(s);
+          _visitor->reach(s);
+          Arc e;
+          _digraph->firstOut(e, s);
+          if (e != INVALID) {
+            _stack[++_stack_head] = e;
+          } else {
+            _visitor->leave(s);
+            _visitor->stop(s);
+          }
+        }
+    }
+
+    /// \brief Processes the next arc.
+    ///
+    /// Processes the next arc.
+    ///
+    /// \return The processed arc.
+    ///
+    /// \pre The stack must not be empty.
+    Arc processNextArc() {
+      Arc e = _stack[_stack_head];
+      Node m = _digraph->target(e);
+      if(!(*_reached)[m]) {
+        _visitor->discover(e);
+        _visitor->reach(m);
+        _reached->set(m, true);
+        _digraph->firstOut(_stack[++_stack_head], m);
+      } else {
+        _visitor->examine(e);
+        m = _digraph->source(e);
+        _digraph->nextOut(_stack[_stack_head]);
+      }
+      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
+        _visitor->leave(m);
+        --_stack_head;
+        if (_stack_head >= 0) {
+          _visitor->backtrack(_stack[_stack_head]);
+          m = _digraph->source(_stack[_stack_head]);
+          _digraph->nextOut(_stack[_stack_head]);
+        } else {
+          _visitor->stop(m);
+        }
+      }
+      return e;
+    }
+
+    /// \brief Next arc to be processed.
+    ///
+    /// Next arc to be processed.
+    ///
+    /// \return The next arc to be processed or INVALID if the stack is
+    /// empty.
+    Arc nextArc() const {
+      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
+    }
+
+    /// \brief Returns \c false if there are nodes
+    /// to be processed.
+    ///
+    /// Returns \c false if there are nodes
+    /// to be processed in the queue (stack).
+    bool emptyQueue() const { return _stack_head < 0; }
+
+    /// \brief Returns the number of the nodes to be processed.
+    ///
+    /// Returns the number of the nodes to be processed in the queue (stack).
+    int queueSize() const { return _stack_head + 1; }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    /// This method runs the %DFS algorithm from the root node
+    /// in order to compute the %DFS path to each node.
+    ///
+    /// The algorithm computes
+    /// - the %DFS tree,
+    /// - the distance of each node from the root in the %DFS tree.
+    ///
+    /// \pre init() must be called and a root node should be
+    /// added with addSource() before using this function.
+    ///
+    /// \note <tt>d.start()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   while ( !d.emptyQueue() ) {
+    ///     d.processNextArc();
+    ///   }
+    /// \endcode
+    void start() {
+      while ( !emptyQueue() ) processNextArc();
+    }
+
+    /// \brief Executes the algorithm until the given target node is reached.
+    ///
+    /// Executes the algorithm until the given target node is reached.
+    ///
+    /// This method runs the %DFS algorithm from the root node
+    /// in order to compute the DFS path to \c t.
+    ///
+    /// The algorithm computes
+    /// - the %DFS path to \c t,
+    /// - the distance of \c t from the root in the %DFS tree.
+    ///
+    /// \pre init() must be called and a root node should be added
+    /// with addSource() before using this function.
+    void start(Node t) {
+      while ( !emptyQueue() && !(*_reached)[t] )
+        processNextArc();
+    }
+
+    /// \brief Executes the algorithm until a condition is met.
+    ///
+    /// Executes the algorithm until a condition is met.
+    ///
+    /// This method runs the %DFS algorithm from the root node
+    /// until an arc \c a with <tt>am[a]</tt> true is found.
+    ///
+    /// \param am A \c bool (or convertible) arc map. The algorithm
+    /// will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
+    ///
+    /// \return The reached arc \c a with <tt>am[a]</tt> true or
+    /// \c INVALID if no such arc was found.
+    ///
+    /// \pre init() must be called and a root node should be added
+    /// with addSource() before using this function.
+    ///
+    /// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
+    /// not a node map.
+    template <typename AM>
+    Arc start(const AM &am) {
+      while ( !emptyQueue() && !am[_stack[_stack_head]] )
+        processNextArc();
+      return emptyQueue() ? INVALID : _stack[_stack_head];
+    }
+
+    /// \brief Runs the algorithm from the given source node.
+    ///
+    /// This method runs the %DFS algorithm from node \c s.
+    /// in order to compute the DFS path to each node.
+    ///
+    /// The algorithm computes
+    /// - the %DFS tree,
+    /// - the distance of each node from the root in the %DFS tree.
+    ///
+    /// \note <tt>d.run(s)</tt> is just a shortcut of the following code.
+    ///\code
+    ///   d.init();
+    ///   d.addSource(s);
+    ///   d.start();
+    ///\endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    /// \brief Finds the %DFS path between \c s and \c t.
+
+    /// This method runs the %DFS algorithm from node \c s
+    /// in order to compute the DFS path to node \c t
+    /// (it stops searching when \c t is processed).
+    ///
+    /// \return \c true if \c t is reachable form \c s.
+    ///
+    /// \note Apart from the return value, <tt>d.run(s,t)</tt> is
+    /// just a shortcut of the following code.
+    ///\code
+    ///   d.init();
+    ///   d.addSource(s);
+    ///   d.start(t);
+    ///\endcode
+    bool run(Node s,Node t) {
+      init();
+      addSource(s);
+      start(t);
+      return reached(t);
+    }
+
+    /// \brief Runs the algorithm to visit all nodes in the digraph.
+
+    /// 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.
+    ///\code
+    ///   d.init();
+    ///   for (NodeIt n(digraph); n != INVALID; ++n) {
+    ///     if (!d.reached(n)) {
+    ///       d.addSource(n);
+    ///       d.start();
+    ///     }
+    ///   }
+    ///\endcode
+    void run() {
+      init();
+      for (NodeIt it(*_digraph); it != INVALID; ++it) {
+        if (!reached(it)) {
+          addSource(it);
+          start();
+        }
+      }
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    /// The results of the DFS algorithm can be obtained using these
+    /// functions.\n
+    /// Either \ref run(Node) "run()" or \ref start() should be called
+    /// before using them.
+
+    ///@{
+
+    /// \brief Checks if the given node is reached from the root(s).
+    ///
+    /// Returns \c true if \c v is reached from the root(s).
+    ///
+    /// \pre Either \ref run(Node) "run()" or \ref init()
+    /// must be called before using this function.
+    bool reached(Node v) const { return (*_reached)[v]; }
+
+    ///@}
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif
diff --git a/lemon/dheap.h b/lemon/dheap.h
new file mode 100644
index 0000000..a3ab625
--- /dev/null
+++ b/lemon/dheap.h
@@ -0,0 +1,352 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_DHEAP_H
+#define LEMON_DHEAP_H
+
+///\ingroup heaps
+///\file
+///\brief D-ary heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief D-ary heap data structure.
+  ///
+  /// This class implements the \e D-ary \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The \ref DHeap "D-ary heap" is a generalization of the
+  /// \ref BinHeap "binary heap" structure, its nodes have at most
+  /// \c D children, instead of two.
+  /// \ref BinHeap and \ref QuadHeap are specialized implementations
+  /// of this structure for <tt>D=2</tt> and <tt>D=4</tt>, respectively.
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam D The degree of the heap, each node have at most \e D
+  /// children. The default is 16. Powers of two are suggested to use
+  /// so that the multiplications and divisions needed to traverse the
+  /// nodes of the heap could be performed faster.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+  ///
+  ///\sa BinHeap
+  ///\sa FouraryHeap
+#ifdef DOXYGEN
+  template <typename PR, typename IM, int D, typename CMP>
+#else
+  template <typename PR, typename IM, int D = 16,
+            typename CMP = std::less<PR> >
+#endif
+  class DHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    std::vector<Pair> _data;
+    Compare _comp;
+    ItemIntMap &_iim;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit DHeap(ItemIntMap &map) : _iim(map) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    DHeap(ItemIntMap &map, const Compare &comp)
+      : _iim(map), _comp(comp) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() { _data.clear(); }
+
+  private:
+    int parent(int i) { return (i-1)/D; }
+    int firstChild(int i) { return D*i+1; }
+
+    bool less(const Pair &p1, const Pair &p2) const {
+      return _comp(p1.second, p2.second);
+    }
+
+    void bubbleUp(int hole, Pair p) {
+      int par = parent(hole);
+      while( hole>0 && less(p,_data[par]) ) {
+        move(_data[par],hole);
+        hole = par;
+        par = parent(hole);
+      }
+      move(p, hole);
+    }
+
+    void bubbleDown(int hole, Pair p, int length) {
+      if( length>1 ) {
+        int child = firstChild(hole);
+        while( child+D<=length ) {
+          int min=child;
+          for (int i=1; i<D; ++i) {
+            if( less(_data[child+i], _data[min]) )
+              min=child+i;
+          }
+          if( !less(_data[min], p) )
+            goto ok;
+          move(_data[min], hole);
+          hole = min;
+          child = firstChild(hole);
+        }
+        if ( child<length ) {
+          int min = child;
+          while (++child < length) {
+            if( less(_data[child], _data[min]) )
+              min=child;
+          }
+          if( less(_data[min], p) ) {
+            move(_data[min], hole);
+            hole = min;
+          }
+        }
+      }
+    ok:
+      move(p, hole);
+    }
+
+    void move(const Pair &p, int i) {
+      _data[i] = p;
+      _iim.set(p.first, i);
+    }
+
+  public:
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair &p) {
+      int n = _data.size();
+      _data.resize(n+1);
+      bubbleUp(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[0].first; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[0].second; }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      int n = _data.size()-1;
+      _iim.set(_data[0].first, POST_HEAP);
+      if (n>0) bubbleDown(0, _data[n], n);
+      _data.pop_back();
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int h = _iim[i];
+      int n = _data.size()-1;
+      _iim.set(_data[h].first, POST_HEAP);
+      if( h<n ) {
+        if( less(_data[parent(h)], _data[n]) )
+          bubbleDown(h, _data[n], n);
+        else
+          bubbleUp(h, _data[n]);
+      }
+      _data.pop_back();
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].second;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if( idx<0 )
+        push(i,p);
+      else if( _comp(p, _data[idx].second) )
+        bubbleUp(idx, Pair(i,p));
+      else
+        bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleUp(idx, Pair(i,p));
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int s = _iim[i];
+      if (s>=0) s=0;
+      return State(s);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+        case POST_HEAP:
+        case PRE_HEAP:
+          if (state(i) == IN_HEAP) erase(i);
+          _iim[i] = st;
+          break;
+        case IN_HEAP:
+          break;
+      }
+    }
+
+    /// \brief Replace an item in the heap.
+    ///
+    /// This function replaces item \c i with item \c j.
+    /// Item \c i must be in the heap, while \c j must be out of the heap.
+    /// After calling this method, item \c i will be out of the
+    /// heap and \c j will be in the heap with the same prioriority
+    /// as item \c i had before.
+    void replace(const Item& i, const Item& j) {
+      int idx=_iim[i];
+      _iim.set(i, _iim[j]);
+      _iim.set(j, idx);
+      _data[idx].first=j;
+    }
+
+  }; // class DHeap
+
+} // namespace lemon
+
+#endif // LEMON_DHEAP_H
diff --git a/lemon/dijkstra.h b/lemon/dijkstra.h
new file mode 100644
index 0000000..1564a03
--- /dev/null
+++ b/lemon/dijkstra.h
@@ -0,0 +1,1303 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_DIJKSTRA_H
+#define LEMON_DIJKSTRA_H
+
+///\ingroup shortest_path
+///\file
+///\brief Dijkstra algorithm.
+
+#include <limits>
+#include <lemon/list_graph.h>
+#include <lemon/bin_heap.h>
+#include <lemon/bits/path_dump.h>
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+
+namespace lemon {
+
+  /// \brief Default operation traits for the Dijkstra algorithm class.
+  ///
+  /// This operation traits class defines all computational operations and
+  /// constants which are used in the Dijkstra algorithm.
+  template <typename V>
+  struct DijkstraDefaultOperationTraits {
+    /// \e
+    typedef V Value;
+    /// \brief Gives back the zero value of the type.
+    static Value zero() {
+      return static_cast<Value>(0);
+    }
+    /// \brief Gives back the sum of the given two elements.
+    static Value plus(const Value& left, const Value& right) {
+      return left + right;
+    }
+    /// \brief Gives back true only if the first value is less than the second.
+    static bool less(const Value& left, const Value& right) {
+      return left < right;
+    }
+  };
+
+  ///Default traits class of Dijkstra class.
+
+  ///Default traits class of Dijkstra class.
+  ///\tparam GR The type of the digraph.
+  ///\tparam LEN The type of the length map.
+  template<typename GR, typename LEN>
+  struct DijkstraDefaultTraits
+  {
+    ///The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    ///The type of the map that stores the arc lengths.
+
+    ///The type of the map that stores the arc lengths.
+    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LEN LengthMap;
+    ///The type of the arc lengths.
+    typedef typename LEN::Value Value;
+
+    /// Operation traits for %Dijkstra algorithm.
+
+    /// This class defines the operations that are used in the algorithm.
+    /// \see DijkstraDefaultOperationTraits
+    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
+
+    /// The cross reference type used by the heap.
+
+    /// The cross reference type used by the heap.
+    /// Usually it is \c Digraph::NodeMap<int>.
+    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
+    ///Instantiates a \c HeapCrossRef.
+
+    ///This function instantiates a \ref HeapCrossRef.
+    /// \param g is the digraph, to which we would like to define the
+    /// \ref HeapCrossRef.
+    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
+    {
+      return new HeapCrossRef(g);
+    }
+
+    ///The heap type used by the %Dijkstra algorithm.
+
+    ///The heap type used by the Dijkstra algorithm.
+    ///
+    ///\sa BinHeap
+    ///\sa Dijkstra
+    typedef BinHeap<typename LEN::Value, HeapCrossRef, std::less<Value> > Heap;
+    ///Instantiates a \c Heap.
+
+    ///This function instantiates a \ref Heap.
+    static Heap *createHeap(HeapCrossRef& r)
+    {
+      return new Heap(r);
+    }
+
+    ///\brief The type of the map that stores the predecessor
+    ///arcs of the shortest paths.
+    ///
+    ///The type of the map that stores the predecessor
+    ///arcs of the shortest paths.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+    ///Instantiates a \c PredMap.
+
+    ///This function instantiates a \ref PredMap.
+    ///\param g is the digraph, to which we would like to define the
+    ///\ref PredMap.
+    static PredMap *createPredMap(const Digraph &g)
+    {
+      return new PredMap(g);
+    }
+
+    ///The type of the map that indicates which nodes are processed.
+
+    ///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.
+    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
+    ///Instantiates a \c ProcessedMap.
+
+    ///This function instantiates a \ref ProcessedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the \ref ProcessedMap.
+#ifdef DOXYGEN
+    static ProcessedMap *createProcessedMap(const Digraph &g)
+#else
+    static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+    {
+      return new ProcessedMap();
+    }
+
+    ///The type of the map that stores the distances of the nodes.
+
+    ///The type of the map that stores the distances of the nodes.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
+    ///Instantiates a \c DistMap.
+
+    ///This function instantiates a \ref DistMap.
+    ///\param g is the digraph, to which we would like to define
+    ///the \ref DistMap.
+    static DistMap *createDistMap(const Digraph &g)
+    {
+      return new DistMap(g);
+    }
+  };
+
+  ///%Dijkstra algorithm class.
+
+  /// \ingroup shortest_path
+  ///This class provides an efficient implementation of the %Dijkstra algorithm.
+  ///
+  ///The %Dijkstra algorithm solves the single-source shortest path problem
+  ///when all arc lengths are non-negative. If there are negative lengths,
+  ///the BellmanFord algorithm should be used instead.
+  ///
+  ///The arc lengths are passed to the algorithm using a
+  ///\ref concepts::ReadMap "ReadMap",
+  ///so it is easy to change it to any kind of length.
+  ///The type of the length is determined by the
+  ///\ref concepts::ReadMap::Value "Value" of the length map.
+  ///It is also possible to change the underlying priority heap.
+  ///
+  ///There is also a \ref dijkstra() "function-type interface" for the
+  ///%Dijkstra algorithm, which is convenient in the simplier cases and
+  ///it can be used easier.
+  ///
+  ///\tparam GR The type of the digraph the algorithm runs on.
+  ///The default type is \ref ListDigraph.
+  ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
+  ///the lengths of the arcs.
+  ///It is read once for each arc, so the map may involve in
+  ///relatively time consuming process to compute the arc lengths if
+  ///it is necessary. The default map type is \ref
+  ///concepts::Digraph::ArcMap "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>
+#else
+  template <typename GR=ListDigraph,
+            typename LEN=typename GR::template ArcMap<int>,
+            typename TR=DijkstraDefaultTraits<GR,LEN> >
+#endif
+  class Dijkstra {
+  public:
+
+    ///The type of the digraph the algorithm runs on.
+    typedef typename TR::Digraph Digraph;
+
+    ///The type of the arc lengths.
+    typedef typename TR::Value Value;
+    ///The type of the map that stores the arc lengths.
+    typedef typename TR::LengthMap LengthMap;
+    ///\brief The type of the map that stores the predecessor arcs of the
+    ///shortest paths.
+    typedef typename TR::PredMap PredMap;
+    ///The type of the map that stores the distances of the nodes.
+    typedef typename TR::DistMap DistMap;
+    ///The type of the map that indicates which nodes are processed.
+    typedef typename TR::ProcessedMap ProcessedMap;
+    ///The type of the paths.
+    typedef PredMapPath<Digraph, PredMap> Path;
+    ///The cross reference type used for the current heap.
+    typedef typename TR::HeapCrossRef HeapCrossRef;
+    ///The heap type used by the algorithm.
+    typedef typename TR::Heap Heap;
+    /// \brief The \ref lemon::DijkstraDefaultOperationTraits
+    /// "operation traits class" of the algorithm.
+    typedef typename TR::OperationTraits OperationTraits;
+
+    ///The \ref lemon::DijkstraDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    //Pointer to the underlying digraph.
+    const Digraph *G;
+    //Pointer to the length map.
+    const LengthMap *_length;
+    //Pointer to the map of predecessors arcs.
+    PredMap *_pred;
+    //Indicates if _pred is locally allocated (true) or not.
+    bool local_pred;
+    //Pointer to the map of distances.
+    DistMap *_dist;
+    //Indicates if _dist is locally allocated (true) or not.
+    bool local_dist;
+    //Pointer to the map of processed status of the nodes.
+    ProcessedMap *_processed;
+    //Indicates if _processed is locally allocated (true) or not.
+    bool local_processed;
+    //Pointer to the heap cross references.
+    HeapCrossRef *_heap_cross_ref;
+    //Indicates if _heap_cross_ref is locally allocated (true) or not.
+    bool local_heap_cross_ref;
+    //Pointer to the heap.
+    Heap *_heap;
+    //Indicates if _heap is locally allocated (true) or not.
+    bool local_heap;
+
+    //Creates the maps if necessary.
+    void create_maps()
+    {
+      if(!_pred) {
+        local_pred = true;
+        _pred = Traits::createPredMap(*G);
+      }
+      if(!_dist) {
+        local_dist = true;
+        _dist = Traits::createDistMap(*G);
+      }
+      if(!_processed) {
+        local_processed = true;
+        _processed = Traits::createProcessedMap(*G);
+      }
+      if (!_heap_cross_ref) {
+        local_heap_cross_ref = true;
+        _heap_cross_ref = Traits::createHeapCrossRef(*G);
+      }
+      if (!_heap) {
+        local_heap = true;
+        _heap = Traits::createHeap(*_heap_cross_ref);
+      }
+    }
+
+  public:
+
+    typedef Dijkstra Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <class T>
+    struct SetPredMapTraits : public Traits {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "PredMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c PredMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c PredMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetPredMap
+      : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
+      typedef Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetDistMapTraits : public Traits {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "DistMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c DistMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c DistMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetDistMap
+      : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
+      typedef Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetProcessedMapTraits : public Traits {
+      typedef T ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "ProcessedMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetProcessedMap
+      : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
+      typedef Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > Create;
+    };
+
+    struct SetStandardProcessedMapTraits : public Traits {
+      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &g)
+      {
+        return new ProcessedMap(g);
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///If you don't set it explicitly, it will be automatically allocated.
+    struct SetStandardProcessedMap
+      : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
+      typedef Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits >
+      Create;
+    };
+
+    template <class H, class CR>
+    struct SetHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
+        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
+        return 0; // ignore warnings
+      }
+      static Heap *createHeap(HeapCrossRef &)
+      {
+        LEMON_ASSERT(false, "Heap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///heap and cross reference types
+    ///
+    ///\ref named-templ-param "Named parameter" for setting heap and cross
+    ///reference types. If this named parameter is used, then external
+    ///heap and cross reference objects must be passed to the algorithm
+    ///using the \ref heap() function before calling \ref run(Node) "run()"
+    ///or \ref init().
+    ///\sa SetStandardHeap
+    template <class H, class CR = typename Digraph::template NodeMap<int> >
+    struct SetHeap
+      : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
+      typedef Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > Create;
+    };
+
+    template <class H, class CR>
+    struct SetStandardHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Digraph &G) {
+        return new HeapCrossRef(G);
+      }
+      static Heap *createHeap(HeapCrossRef &R)
+      {
+        return new Heap(R);
+      }
+    };
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///heap and cross reference types with automatic allocation
+    ///
+    ///\ref named-templ-param "Named parameter" for setting heap and cross
+    ///reference types with automatic allocation.
+    ///They should have standard constructor interfaces to be able to
+    ///automatically created by the algorithm (i.e. the digraph should be
+    ///passed to the constructor of the cross reference and the cross
+    ///reference should be passed to the constructor of the heap).
+    ///However, external heap and cross reference objects could also be
+    ///passed to the algorithm using the \ref heap() function before
+    ///calling \ref run(Node) "run()" or \ref init().
+    ///\sa SetHeap
+    template <class H, class CR = typename Digraph::template NodeMap<int> >
+    struct SetStandardHeap
+      : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
+      typedef Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> >
+      Create;
+    };
+
+    template <class T>
+    struct SetOperationTraitsTraits : public Traits {
+      typedef T OperationTraits;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    ///\c OperationTraits type
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///\c OperationTraits type.
+    /// For more information, see \ref DijkstraDefaultOperationTraits.
+    template <class T>
+    struct SetOperationTraits
+      : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
+      typedef Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> >
+      Create;
+    };
+
+    ///@}
+
+  protected:
+
+    Dijkstra() {}
+
+  public:
+
+    ///Constructor.
+
+    ///Constructor.
+    ///\param g The digraph the algorithm runs on.
+    ///\param length The length map used by the algorithm.
+    Dijkstra(const Digraph& g, const LengthMap& length) :
+      G(&g), _length(&length),
+      _pred(NULL), local_pred(false),
+      _dist(NULL), local_dist(false),
+      _processed(NULL), local_processed(false),
+      _heap_cross_ref(NULL), local_heap_cross_ref(false),
+      _heap(NULL), local_heap(false)
+    { }
+
+    ///Destructor.
+    ~Dijkstra()
+    {
+      if(local_pred) delete _pred;
+      if(local_dist) delete _dist;
+      if(local_processed) delete _processed;
+      if(local_heap_cross_ref) delete _heap_cross_ref;
+      if(local_heap) delete _heap;
+    }
+
+    ///Sets the length map.
+
+    ///Sets the length map.
+    ///\return <tt> (*this) </tt>
+    Dijkstra &lengthMap(const LengthMap &m)
+    {
+      _length = &m;
+      return *this;
+    }
+
+    ///Sets the map that stores the predecessor arcs.
+
+    ///Sets the map that stores the predecessor arcs.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Dijkstra &predMap(PredMap &m)
+    {
+      if(local_pred) {
+        delete _pred;
+        local_pred=false;
+      }
+      _pred = &m;
+      return *this;
+    }
+
+    ///Sets the map that indicates which nodes are processed.
+
+    ///Sets the map that indicates which nodes are processed.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Dijkstra &processedMap(ProcessedMap &m)
+    {
+      if(local_processed) {
+        delete _processed;
+        local_processed=false;
+      }
+      _processed = &m;
+      return *this;
+    }
+
+    ///Sets the map that stores the distances of the nodes.
+
+    ///Sets the map that stores the distances of the nodes calculated by the
+    ///algorithm.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Dijkstra &distMap(DistMap &m)
+    {
+      if(local_dist) {
+        delete _dist;
+        local_dist=false;
+      }
+      _dist = &m;
+      return *this;
+    }
+
+    ///Sets the heap and the cross reference used by algorithm.
+
+    ///Sets the heap and the cross reference used by algorithm.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), heap and cross reference instances will be
+    ///allocated automatically.
+    ///The destructor deallocates these automatically allocated objects,
+    ///of course.
+    ///\return <tt> (*this) </tt>
+    Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
+    {
+      if(local_heap_cross_ref) {
+        delete _heap_cross_ref;
+        local_heap_cross_ref=false;
+      }
+      _heap_cross_ref = &cr;
+      if(local_heap) {
+        delete _heap;
+        local_heap=false;
+      }
+      _heap = &hp;
+      return *this;
+    }
+
+  private:
+
+    void finalizeNodeData(Node v,Value dst)
+    {
+      _processed->set(v,true);
+      _dist->set(v, dst);
+    }
+
+  public:
+
+    ///\name Execution Control
+    ///The simplest way to execute the %Dijkstra algorithm is to use
+    ///one of the member functions called \ref run(Node) "run()".\n
+    ///If you need better control on the execution, you have to call
+    ///\ref init() first, then you can add several source nodes with
+    ///\ref addSource(). Finally the actual path computation can be
+    ///performed with one of the \ref start() functions.
+
+    ///@{
+
+    ///\brief Initializes the internal data structures.
+    ///
+    ///Initializes the internal data structures.
+    void init()
+    {
+      create_maps();
+      _heap->clear();
+      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
+        _pred->set(u,INVALID);
+        _processed->set(u,false);
+        _heap_cross_ref->set(u,Heap::PRE_HEAP);
+      }
+    }
+
+    ///Adds a new source node.
+
+    ///Adds a new source node to the priority heap.
+    ///The optional second parameter is the initial distance of the node.
+    ///
+    ///The function checks if the node has already been added to the heap and
+    ///it is pushed to the heap only if either it was not in the heap
+    ///or the shortest path found till then is shorter than \c dst.
+    void addSource(Node s,Value dst=OperationTraits::zero())
+    {
+      if(_heap->state(s) != Heap::IN_HEAP) {
+        _heap->push(s,dst);
+      } else if(OperationTraits::less((*_heap)[s], dst)) {
+        _heap->set(s,dst);
+        _pred->set(s,INVALID);
+      }
+    }
+
+    ///Processes the next node in the priority heap
+
+    ///Processes the next node in the priority heap.
+    ///
+    ///\return The processed node.
+    ///
+    ///\warning The priority heap must not be empty.
+    Node processNextNode()
+    {
+      Node v=_heap->top();
+      Value oldvalue=_heap->prio();
+      _heap->pop();
+      finalizeNodeData(v,oldvalue);
+
+      for(OutArcIt e(*G,v); e!=INVALID; ++e) {
+        Node w=G->target(e);
+        switch(_heap->state(w)) {
+        case Heap::PRE_HEAP:
+          _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e]));
+          _pred->set(w,e);
+          break;
+        case Heap::IN_HEAP:
+          {
+            Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]);
+            if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
+              _heap->decrease(w, newvalue);
+              _pred->set(w,e);
+            }
+          }
+          break;
+        case Heap::POST_HEAP:
+          break;
+        }
+      }
+      return v;
+    }
+
+    ///The next node to be processed.
+
+    ///Returns the next node to be processed or \c INVALID if the
+    ///priority heap is empty.
+    Node nextNode() const
+    {
+      return !_heap->empty()?_heap->top():INVALID;
+    }
+
+    ///Returns \c false if there are nodes to be processed.
+
+    ///Returns \c false if there are nodes to be processed
+    ///in the priority heap.
+    bool emptyQueue() const { return _heap->empty(); }
+
+    ///Returns the number of the nodes to be processed.
+
+    ///Returns the number of the nodes to be processed
+    ///in the priority heap.
+    int queueSize() const { return _heap->size(); }
+
+    ///Executes the algorithm.
+
+    ///Executes the algorithm.
+    ///
+    ///This method runs the %Dijkstra algorithm from the root node(s)
+    ///in order to compute the shortest path to each node.
+    ///
+    ///The algorithm computes
+    ///- the shortest path tree (forest),
+    ///- the distance of each node from the root(s).
+    ///
+    ///\pre init() must be called and at least one root node should be
+    ///added with addSource() before using this function.
+    ///
+    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
+    ///\code
+    ///  while ( !d.emptyQueue() ) {
+    ///    d.processNextNode();
+    ///  }
+    ///\endcode
+    void start()
+    {
+      while ( !emptyQueue() ) processNextNode();
+    }
+
+    ///Executes the algorithm until the given target node is processed.
+
+    ///Executes the algorithm until the given target node is processed.
+    ///
+    ///This method runs the %Dijkstra algorithm from the root node(s)
+    ///in order to compute the shortest path to \c t.
+    ///
+    ///The algorithm computes
+    ///- the shortest path to \c t,
+    ///- the distance of \c t from the root(s).
+    ///
+    ///\pre init() must be called and at least one root node should be
+    ///added with addSource() before using this function.
+    void start(Node t)
+    {
+      while ( !_heap->empty() && _heap->top()!=t ) processNextNode();
+      if ( !_heap->empty() ) {
+        finalizeNodeData(_heap->top(),_heap->prio());
+        _heap->pop();
+      }
+    }
+
+    ///Executes the algorithm until a condition is met.
+
+    ///Executes the algorithm until a condition is met.
+    ///
+    ///This method runs the %Dijkstra algorithm from the root node(s) in
+    ///order to compute the shortest path to a node \c v with
+    /// <tt>nm[v]</tt> true, if such a node can be found.
+    ///
+    ///\param nm A \c bool (or convertible) node map. The algorithm
+    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
+    ///
+    ///\return The reached node \c v with <tt>nm[v]</tt> true or
+    ///\c INVALID if no such node was found.
+    ///
+    ///\pre init() must be called and at least one root node should be
+    ///added with addSource() before using this function.
+    template<class NodeBoolMap>
+    Node start(const NodeBoolMap &nm)
+    {
+      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
+      if ( _heap->empty() ) return INVALID;
+      finalizeNodeData(_heap->top(),_heap->prio());
+      return _heap->top();
+    }
+
+    ///Runs the algorithm from the given source node.
+
+    ///This method runs the %Dijkstra algorithm from node \c s
+    ///in order to compute the shortest path to each node.
+    ///
+    ///The algorithm computes
+    ///- the shortest path tree,
+    ///- the distance of each node from the root.
+    ///
+    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
+    ///\code
+    ///  d.init();
+    ///  d.addSource(s);
+    ///  d.start();
+    ///\endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    ///Finds the shortest path between \c s and \c t.
+
+    ///This method runs the %Dijkstra algorithm from node \c s
+    ///in order to compute the shortest path to node \c t
+    ///(it stops searching when \c t is processed).
+    ///
+    ///\return \c true if \c t is reachable form \c s.
+    ///
+    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is just a
+    ///shortcut of the following code.
+    ///\code
+    ///  d.init();
+    ///  d.addSource(s);
+    ///  d.start(t);
+    ///\endcode
+    bool run(Node s,Node t) {
+      init();
+      addSource(s);
+      start(t);
+      return (*_heap_cross_ref)[t] == Heap::POST_HEAP;
+    }
+
+    ///@}
+
+    ///\name Query Functions
+    ///The results of the %Dijkstra algorithm can be obtained using these
+    ///functions.\n
+    ///Either \ref run(Node) "run()" or \ref init() should be called
+    ///before using them.
+
+    ///@{
+
+    ///The shortest path to the given node.
+
+    ///Returns the shortest path to the given node from the root(s).
+    ///
+    ///\warning \c t should be reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Path path(Node t) const { return Path(*G, *_pred, t); }
+
+    ///The distance of the given node from the root(s).
+
+    ///Returns the distance of the given node from the root(s).
+    ///
+    ///\warning If node \c v is not reached from the root(s), then
+    ///the return value of this function is undefined.
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Value dist(Node v) const { return (*_dist)[v]; }
+
+    ///\brief Returns the 'previous arc' of the shortest path tree for
+    ///the given node.
+    ///
+    ///This function returns the 'previous arc' of the shortest path
+    ///tree for the node \c v, i.e. it returns the last arc of a
+    ///shortest path from a root to \c v. It is \c INVALID if \c v
+    ///is not reached from the root(s) or if \c v is a root.
+    ///
+    ///The shortest path tree used here is equal to the shortest path
+    ///tree used in \ref predNode() and \ref predMap().
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Arc predArc(Node v) const { return (*_pred)[v]; }
+
+    ///\brief Returns the 'previous node' of the shortest path tree for
+    ///the given node.
+    ///
+    ///This function returns the 'previous node' of the shortest path
+    ///tree for the node \c v, i.e. it returns the last but one node
+    ///of a shortest path from a root to \c v. It is \c INVALID
+    ///if \c v is not reached from the root(s) or if \c v is a root.
+    ///
+    ///The shortest path tree used here is equal to the shortest path
+    ///tree used in \ref predArc() and \ref predMap().
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
+                                  G->source((*_pred)[v]); }
+
+    ///\brief Returns a const reference to the node map that stores the
+    ///distances of the nodes.
+    ///
+    ///Returns a const reference to the node map that stores the distances
+    ///of the nodes calculated by the algorithm.
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    const DistMap &distMap() const { return *_dist;}
+
+    ///\brief Returns a const reference to the node map that stores the
+    ///predecessor arcs.
+    ///
+    ///Returns a const reference to the node map that stores the predecessor
+    ///arcs, which form the shortest path tree (forest).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    const PredMap &predMap() const { return *_pred;}
+
+    ///Checks if the given node is reached from the root(s).
+
+    ///Returns \c true if \c v is reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    bool reached(Node v) const { return (*_heap_cross_ref)[v] !=
+                                        Heap::PRE_HEAP; }
+
+    ///Checks if a node is processed.
+
+    ///Returns \c true if \c v is processed, i.e. the shortest
+    ///path to \c v has already found.
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
+    bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
+                                          Heap::POST_HEAP; }
+
+    ///The current distance of the given node from the root(s).
+
+    ///Returns the current distance of the given node from the root(s).
+    ///It may be decreased in the following processes.
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function and
+    ///node \c v must be reached but not necessarily processed.
+    Value currentDist(Node v) const {
+      return processed(v) ? (*_dist)[v] : (*_heap)[v];
+    }
+
+    ///@}
+  };
+
+
+  ///Default traits class of dijkstra() function.
+
+  ///Default traits class of dijkstra() function.
+  ///\tparam GR The type of the digraph.
+  ///\tparam LEN The type of the length map.
+  template<class GR, class LEN>
+  struct DijkstraWizardDefaultTraits
+  {
+    ///The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+    ///The type of the map that stores the arc lengths.
+
+    ///The type of the map that stores the arc lengths.
+    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LEN LengthMap;
+    ///The type of the arc lengths.
+    typedef typename LEN::Value Value;
+
+    /// Operation traits for Dijkstra algorithm.
+
+    /// This class defines the operations that are used in the algorithm.
+    /// \see DijkstraDefaultOperationTraits
+    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
+
+    /// The cross reference type used by the heap.
+
+    /// The cross reference type used by the heap.
+    /// Usually it is \c Digraph::NodeMap<int>.
+    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
+    ///Instantiates a \ref HeapCrossRef.
+
+    ///This function instantiates a \ref HeapCrossRef.
+    /// \param g is the digraph, to which we would like to define the
+    /// HeapCrossRef.
+    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
+    {
+      return new HeapCrossRef(g);
+    }
+
+    ///The heap type used by the Dijkstra algorithm.
+
+    ///The heap type used by the Dijkstra algorithm.
+    ///
+    ///\sa BinHeap
+    ///\sa Dijkstra
+    typedef BinHeap<Value, typename Digraph::template NodeMap<int>,
+                    std::less<Value> > Heap;
+
+    ///Instantiates a \ref Heap.
+
+    ///This function instantiates a \ref Heap.
+    /// \param r is the HeapCrossRef which is used.
+    static Heap *createHeap(HeapCrossRef& r)
+    {
+      return new Heap(r);
+    }
+
+    ///\brief The type of the map that stores the predecessor
+    ///arcs of the shortest paths.
+    ///
+    ///The type of the map that stores the predecessor
+    ///arcs of the shortest paths.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+    ///Instantiates a PredMap.
+
+    ///This function instantiates a PredMap.
+    ///\param g is the digraph, to which we would like to define the
+    ///PredMap.
+    static PredMap *createPredMap(const Digraph &g)
+    {
+      return new PredMap(g);
+    }
+
+    ///The type of the map that indicates which nodes are processed.
+
+    ///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.
+    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
+    ///Instantiates a ProcessedMap.
+
+    ///This function instantiates a ProcessedMap.
+    ///\param g is the digraph, to which
+    ///we would like to define the ProcessedMap.
+#ifdef DOXYGEN
+    static ProcessedMap *createProcessedMap(const Digraph &g)
+#else
+    static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+    {
+      return new ProcessedMap();
+    }
+
+    ///The type of the map that stores the distances of the nodes.
+
+    ///The type of the map that stores the distances of the nodes.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
+    ///Instantiates a DistMap.
+
+    ///This function instantiates a DistMap.
+    ///\param g is the digraph, to which we would like to define
+    ///the DistMap
+    static DistMap *createDistMap(const Digraph &g)
+    {
+      return new DistMap(g);
+    }
+
+    ///The type of the shortest paths.
+
+    ///The type of the shortest paths.
+    ///It must conform to the \ref concepts::Path "Path" concept.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  /// Default traits class used by DijkstraWizard
+
+  /// Default traits class used by DijkstraWizard.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
+  template<typename GR, typename LEN>
+  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
+  {
+    typedef DijkstraWizardDefaultTraits<GR,LEN> Base;
+  protected:
+    //The type of the nodes in the digraph.
+    typedef typename Base::Digraph::Node Node;
+
+    //Pointer to the digraph the algorithm runs on.
+    void *_g;
+    //Pointer to the length map.
+    void *_length;
+    //Pointer to the map of processed nodes.
+    void *_processed;
+    //Pointer to the map of predecessors arcs.
+    void *_pred;
+    //Pointer to the map of distances.
+    void *_dist;
+    //Pointer to the shortest path to the target node.
+    void *_path;
+    //Pointer to the distance of the target node.
+    void *_di;
+
+  public:
+    /// Constructor.
+
+    /// This constructor does not require parameters, therefore it initiates
+    /// all of the attributes to \c 0.
+    DijkstraWizardBase() : _g(0), _length(0), _processed(0), _pred(0),
+                           _dist(0), _path(0), _di(0) {}
+
+    /// Constructor.
+
+    /// This constructor requires two parameters,
+    /// others are initiated to \c 0.
+    /// \param g The digraph the algorithm runs on.
+    /// \param l The length map.
+    DijkstraWizardBase(const GR &g,const LEN &l) :
+      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
+      _length(reinterpret_cast<void*>(const_cast<LEN*>(&l))),
+      _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
+
+  };
+
+  /// Auxiliary class for the function-type interface of Dijkstra algorithm.
+
+  /// This auxiliary class is created to implement the
+  /// \ref dijkstra() "function-type interface" of \ref Dijkstra algorithm.
+  /// It does not have own \ref run(Node) "run()" method, it uses the
+  /// functions and features of the plain \ref Dijkstra.
+  ///
+  /// This class should only be used through the \ref dijkstra() function,
+  /// 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
+  {
+    typedef TR Base;
+
+    typedef typename TR::Digraph Digraph;
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    typedef typename TR::LengthMap LengthMap;
+    typedef typename LengthMap::Value Value;
+    typedef typename TR::PredMap PredMap;
+    typedef typename TR::DistMap DistMap;
+    typedef typename TR::ProcessedMap ProcessedMap;
+    typedef typename TR::Path Path;
+    typedef typename TR::Heap Heap;
+
+  public:
+
+    /// Constructor.
+    DijkstraWizard() : TR() {}
+
+    /// Constructor that requires parameters.
+
+    /// Constructor that requires parameters.
+    /// These parameters will be the default values for the traits class.
+    /// \param g The digraph the algorithm runs on.
+    /// \param l The length map.
+    DijkstraWizard(const Digraph &g, const LengthMap &l) :
+      TR(g,l) {}
+
+    ///Copy constructor
+    DijkstraWizard(const TR &b) : TR(b) {}
+
+    ~DijkstraWizard() {}
+
+    ///Runs Dijkstra algorithm from the given source node.
+
+    ///This method runs %Dijkstra algorithm from the given source node
+    ///in order to compute the shortest path to each node.
+    void run(Node s)
+    {
+      Dijkstra<Digraph,LengthMap,TR>
+        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
+             *reinterpret_cast<const LengthMap*>(Base::_length));
+      if (Base::_pred)
+        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist)
+        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      if (Base::_processed)
+        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+      dijk.run(s);
+    }
+
+    ///Finds the shortest path between \c s and \c t.
+
+    ///This method runs the %Dijkstra algorithm from node \c s
+    ///in order to compute the shortest path to node \c t
+    ///(it stops searching when \c t is processed).
+    ///
+    ///\return \c true if \c t is reachable form \c s.
+    bool run(Node s, Node t)
+    {
+      Dijkstra<Digraph,LengthMap,TR>
+        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
+             *reinterpret_cast<const LengthMap*>(Base::_length));
+      if (Base::_pred)
+        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist)
+        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      if (Base::_processed)
+        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+      dijk.run(s,t);
+      if (Base::_path)
+        *reinterpret_cast<Path*>(Base::_path) = dijk.path(t);
+      if (Base::_di)
+        *reinterpret_cast<Value*>(Base::_di) = dijk.dist(t);
+      return dijk.reached(t);
+    }
+
+    template<class T>
+    struct SetPredMapBase : public Base {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &) { return 0; };
+      SetPredMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the predecessor map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the predecessor arcs of the nodes.
+    template<class T>
+    DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
+    {
+      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DijkstraWizard<SetPredMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetDistMapBase : public Base {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph &) { return 0; };
+      SetDistMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the distance map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the distances of the nodes calculated
+    ///by the algorithm.
+    template<class T>
+    DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
+    {
+      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DijkstraWizard<SetDistMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetProcessedMapBase : public Base {
+      typedef T ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
+      SetProcessedMapBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-func-param "Named parameter" for setting
+    ///the processed map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are processed.
+    template<class T>
+    DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
+    {
+      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DijkstraWizard<SetProcessedMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetPathBase : public Base {
+      typedef T Path;
+      SetPathBase(const TR &b) : TR(b) {}
+    };
+
+    ///\brief \ref named-func-param "Named parameter"
+    ///for getting the shortest path to the target node.
+    ///
+    ///\ref named-func-param "Named parameter"
+    ///for getting the shortest path to the target node.
+    template<class T>
+    DijkstraWizard<SetPathBase<T> > path(const T &t)
+    {
+      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return DijkstraWizard<SetPathBase<T> >(*this);
+    }
+
+    ///\brief \ref named-func-param "Named parameter"
+    ///for getting the distance of the target node.
+    ///
+    ///\ref named-func-param "Named parameter"
+    ///for getting the distance of the target node.
+    DijkstraWizard dist(const Value &d)
+    {
+      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
+      return *this;
+    }
+
+  };
+
+  ///Function-type interface for Dijkstra algorithm.
+
+  /// \ingroup shortest_path
+  ///Function-type interface for Dijkstra algorithm.
+  ///
+  ///This function also has several \ref named-func-param "named parameters",
+  ///they are declared as the members of class \ref DijkstraWizard.
+  ///The following examples show how to use these parameters.
+  ///\code
+  ///  // Compute shortest path from node s to each node
+  ///  dijkstra(g,length).predMap(preds).distMap(dists).run(s);
+  ///
+  ///  // Compute shortest path from s to t
+  ///  bool reached = dijkstra(g,length).path(p).dist(d).run(s,t);
+  ///\endcode
+  ///\warning Don't forget to put the \ref DijkstraWizard::run(Node) "run()"
+  ///to the end of the parameter list.
+  ///\sa DijkstraWizard
+  ///\sa Dijkstra
+  template<typename GR, typename LEN>
+  DijkstraWizard<DijkstraWizardBase<GR,LEN> >
+  dijkstra(const GR &digraph, const LEN &length)
+  {
+    return DijkstraWizard<DijkstraWizardBase<GR,LEN> >(digraph,length);
+  }
+
+} //END OF NAMESPACE LEMON
+
+#endif
diff --git a/lemon/dim2.h b/lemon/dim2.h
new file mode 100644
index 0000000..0b14221
--- /dev/null
+++ b/lemon/dim2.h
@@ -0,0 +1,726 @@
+/* -*- 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_DIM2_H
+#define LEMON_DIM2_H
+
+#include <iostream>
+#include <algorithm>
+
+///\ingroup geomdat
+///\file
+///\brief A simple two dimensional vector and a bounding box implementation
+
+namespace lemon {
+
+  ///Tools for handling two dimensional coordinates
+
+  ///This namespace is a storage of several
+  ///tools for handling two dimensional coordinates
+  namespace dim2 {
+
+  /// \addtogroup geomdat
+  /// @{
+
+  /// Two dimensional vector (plain vector)
+
+  /// A simple two dimensional vector (plain vector) implementation
+  /// with the usual vector operations.
+  template<typename T>
+    class Point {
+
+    public:
+
+      typedef T Value;
+
+      ///First coordinate
+      T x;
+      ///Second coordinate
+      T y;
+
+      ///Default constructor
+      Point() {}
+
+      ///Construct an instance from coordinates
+      Point(T a, T b) : x(a), y(b) { }
+
+      ///Returns the dimension of the vector (i.e. returns 2).
+
+      ///The dimension of the vector.
+      ///This function always returns 2.
+      int size() const { return 2; }
+
+      ///Subscripting operator
+
+      ///\c p[0] is \c p.x and \c p[1] is \c p.y
+      ///
+      T& operator[](int idx) { return idx == 0 ? x : y; }
+
+      ///Const subscripting operator
+
+      ///\c p[0] is \c p.x and \c p[1] is \c p.y
+      ///
+      const T& operator[](int idx) const { return idx == 0 ? x : y; }
+
+      ///Conversion constructor
+      template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
+
+      ///Give back the square of the norm of the vector
+      T normSquare() const {
+        return x*x+y*y;
+      }
+
+      ///Increment the left hand side by \c u
+      Point<T>& operator +=(const Point<T>& u) {
+        x += u.x;
+        y += u.y;
+        return *this;
+      }
+
+      ///Decrement the left hand side by \c u
+      Point<T>& operator -=(const Point<T>& u) {
+        x -= u.x;
+        y -= u.y;
+        return *this;
+      }
+
+      ///Multiply the left hand side with a scalar
+      Point<T>& operator *=(const T &u) {
+        x *= u;
+        y *= u;
+        return *this;
+      }
+
+      ///Divide the left hand side by a scalar
+      Point<T>& operator /=(const T &u) {
+        x /= u;
+        y /= u;
+        return *this;
+      }
+
+      ///Return the scalar product of two vectors
+      T operator *(const Point<T>& u) const {
+        return x*u.x+y*u.y;
+      }
+
+      ///Return the sum of two vectors
+      Point<T> operator+(const Point<T> &u) const {
+        Point<T> b=*this;
+        return b+=u;
+      }
+
+      ///Return the negative of the vector
+      Point<T> operator-() const {
+        Point<T> b=*this;
+        b.x=-b.x; b.y=-b.y;
+        return b;
+      }
+
+      ///Return the difference of two vectors
+      Point<T> operator-(const Point<T> &u) const {
+        Point<T> b=*this;
+        return b-=u;
+      }
+
+      ///Return a vector multiplied by a scalar
+      Point<T> operator*(const T &u) const {
+        Point<T> b=*this;
+        return b*=u;
+      }
+
+      ///Return a vector divided by a scalar
+      Point<T> operator/(const T &u) const {
+        Point<T> b=*this;
+        return b/=u;
+      }
+
+      ///Test equality
+      bool operator==(const Point<T> &u) const {
+        return (x==u.x) && (y==u.y);
+      }
+
+      ///Test inequality
+      bool operator!=(Point u) const {
+        return  (x!=u.x) || (y!=u.y);
+      }
+
+    };
+
+  ///Return a Point
+
+  ///Return a Point.
+  ///\relates Point
+  template <typename T>
+  inline Point<T> makePoint(const T& x, const T& y) {
+    return Point<T>(x, y);
+  }
+
+  ///Return a vector multiplied by a scalar
+
+  ///Return a vector multiplied by a scalar.
+  ///\relates Point
+  template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
+    return x*u;
+  }
+
+  ///Read a plain vector from a stream
+
+  ///Read a plain vector from a stream.
+  ///\relates Point
+  ///
+  template<typename T>
+  inline std::istream& operator>>(std::istream &is, Point<T> &z) {
+    char c;
+    if (is >> c) {
+      if (c != '(') is.putback(c);
+    } else {
+      is.clear();
+    }
+    if (!(is >> z.x)) return is;
+    if (is >> c) {
+      if (c != ',') is.putback(c);
+    } else {
+      is.clear();
+    }
+    if (!(is >> z.y)) return is;
+    if (is >> c) {
+      if (c != ')') is.putback(c);
+    } else {
+      is.clear();
+    }
+    return is;
+  }
+
+  ///Write a plain vector to a stream
+
+  ///Write a plain vector to a stream.
+  ///\relates Point
+  ///
+  template<typename T>
+  inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
+  {
+    os << "(" << z.x << "," << z.y << ")";
+    return os;
+  }
+
+  ///Rotate by 90 degrees
+
+  ///Returns the parameter rotated by 90 degrees in positive direction.
+  ///\relates Point
+  ///
+  template<typename T>
+  inline Point<T> rot90(const Point<T> &z)
+  {
+    return Point<T>(-z.y,z.x);
+  }
+
+  ///Rotate by 180 degrees
+
+  ///Returns the parameter rotated by 180 degrees.
+  ///\relates Point
+  ///
+  template<typename T>
+  inline Point<T> rot180(const Point<T> &z)
+  {
+    return Point<T>(-z.x,-z.y);
+  }
+
+  ///Rotate by 270 degrees
+
+  ///Returns the parameter rotated by 90 degrees in negative direction.
+  ///\relates Point
+  ///
+  template<typename T>
+  inline Point<T> rot270(const Point<T> &z)
+  {
+    return Point<T>(z.y,-z.x);
+  }
+
+
+
+  /// Bounding box of plain vectors (points).
+
+  /// A class to calculate or store the bounding box of plain vectors
+  /// (\ref Point "points").
+  template<typename T>
+  class Box {
+      Point<T> _bottom_left, _top_right;
+      bool _empty;
+    public:
+
+      ///Default constructor: creates an empty box
+      Box() { _empty = true; }
+
+      ///Construct a box from one point
+      Box(Point<T> a) {
+        _bottom_left = _top_right = a;
+        _empty = false;
+      }
+
+      ///Construct a box from two points
+
+      ///Construct a box from two points.
+      ///\param a The bottom left corner.
+      ///\param b The top right corner.
+      ///\warning The coordinates of the bottom left corner must be no more
+      ///than those of the top right one.
+      Box(Point<T> a,Point<T> b)
+      {
+        _bottom_left = a;
+        _top_right = b;
+        _empty = false;
+      }
+
+      ///Construct a box from four numbers
+
+      ///Construct a box from four numbers.
+      ///\param l The left side of the box.
+      ///\param b The bottom of the box.
+      ///\param r The right side of the box.
+      ///\param t The top of the box.
+      ///\warning The left side must be no more than the right side and
+      ///bottom must be no more than the top.
+      Box(T l,T b,T r,T t)
+      {
+        _bottom_left=Point<T>(l,b);
+        _top_right=Point<T>(r,t);
+        _empty = false;
+      }
+
+      ///Return \c true if the box is empty.
+
+      ///Return \c true if the box is empty (i.e. return \c false
+      ///if at least one point was added to the box or the coordinates of
+      ///the box were set).
+      ///
+      ///The coordinates of an empty box are not defined.
+      bool empty() const {
+        return _empty;
+      }
+
+      ///Make the box empty
+      void clear() {
+        _empty = true;
+      }
+
+      ///Give back the bottom left corner of the box
+
+      ///Give back the bottom left corner of the box.
+      ///If the box is empty, then the return value is not defined.
+      Point<T> bottomLeft() const {
+        return _bottom_left;
+      }
+
+      ///Set the bottom left corner of the box
+
+      ///Set the bottom left corner of the box.
+      ///\pre The box must not be empty.
+      void bottomLeft(Point<T> p) {
+        _bottom_left = p;
+      }
+
+      ///Give back the top right corner of the box
+
+      ///Give back the top right corner of the box.
+      ///If the box is empty, then the return value is not defined.
+      Point<T> topRight() const {
+        return _top_right;
+      }
+
+      ///Set the top right corner of the box
+
+      ///Set the top right corner of the box.
+      ///\pre The box must not be empty.
+      void topRight(Point<T> p) {
+        _top_right = p;
+      }
+
+      ///Give back the bottom right corner of the box
+
+      ///Give back the bottom right corner of the box.
+      ///If the box is empty, then the return value is not defined.
+      Point<T> bottomRight() const {
+        return Point<T>(_top_right.x,_bottom_left.y);
+      }
+
+      ///Set the bottom right corner of the box
+
+      ///Set the bottom right corner of the box.
+      ///\pre The box must not be empty.
+      void bottomRight(Point<T> p) {
+        _top_right.x = p.x;
+        _bottom_left.y = p.y;
+      }
+
+      ///Give back the top left corner of the box
+
+      ///Give back the top left corner of the box.
+      ///If the box is empty, then the return value is not defined.
+      Point<T> topLeft() const {
+        return Point<T>(_bottom_left.x,_top_right.y);
+      }
+
+      ///Set the top left corner of the box
+
+      ///Set the top left corner of the box.
+      ///\pre The box must not be empty.
+      void topLeft(Point<T> p) {
+        _top_right.y = p.y;
+        _bottom_left.x = p.x;
+      }
+
+      ///Give back the bottom of the box
+
+      ///Give back the bottom of the box.
+      ///If the box is empty, then the return value is not defined.
+      T bottom() const {
+        return _bottom_left.y;
+      }
+
+      ///Set the bottom of the box
+
+      ///Set the bottom of the box.
+      ///\pre The box must not be empty.
+      void bottom(T t) {
+        _bottom_left.y = t;
+      }
+
+      ///Give back the top of the box
+
+      ///Give back the top of the box.
+      ///If the box is empty, then the return value is not defined.
+      T top() const {
+        return _top_right.y;
+      }
+
+      ///Set the top of the box
+
+      ///Set the top of the box.
+      ///\pre The box must not be empty.
+      void top(T t) {
+        _top_right.y = t;
+      }
+
+      ///Give back the left side of the box
+
+      ///Give back the left side of the box.
+      ///If the box is empty, then the return value is not defined.
+      T left() const {
+        return _bottom_left.x;
+      }
+
+      ///Set the left side of the box
+
+      ///Set the left side of the box.
+      ///\pre The box must not be empty.
+      void left(T t) {
+        _bottom_left.x = t;
+      }
+
+      /// Give back the right side of the box
+
+      /// Give back the right side of the box.
+      ///If the box is empty, then the return value is not defined.
+      T right() const {
+        return _top_right.x;
+      }
+
+      ///Set the right side of the box
+
+      ///Set the right side of the box.
+      ///\pre The box must not be empty.
+      void right(T t) {
+        _top_right.x = t;
+      }
+
+      ///Give back the height of the box
+
+      ///Give back the height of the box.
+      ///If the box is empty, then the return value is not defined.
+      T height() const {
+        return _top_right.y-_bottom_left.y;
+      }
+
+      ///Give back the width of the box
+
+      ///Give back the width of the box.
+      ///If the box is empty, then the return value is not defined.
+      T width() const {
+        return _top_right.x-_bottom_left.x;
+      }
+
+      ///Checks whether a point is inside the box
+      bool inside(const Point<T>& u) const {
+        if (_empty)
+          return false;
+        else {
+          return ( (u.x-_bottom_left.x)*(_top_right.x-u.x) >= 0 &&
+                   (u.y-_bottom_left.y)*(_top_right.y-u.y) >= 0 );
+        }
+      }
+
+      ///Increments the box with a point
+
+      ///Increments the box with a point.
+      ///
+      Box& add(const Point<T>& u){
+        if (_empty) {
+          _bottom_left = _top_right = u;
+          _empty = false;
+        }
+        else {
+          if (_bottom_left.x > u.x) _bottom_left.x = u.x;
+          if (_bottom_left.y > u.y) _bottom_left.y = u.y;
+          if (_top_right.x < u.x) _top_right.x = u.x;
+          if (_top_right.y < u.y) _top_right.y = u.y;
+        }
+        return *this;
+      }
+
+      ///Increments the box to contain another box
+
+      ///Increments the box to contain another box.
+      ///
+      Box& add(const Box &u){
+        if ( !u.empty() ){
+          add(u._bottom_left);
+          add(u._top_right);
+        }
+        return *this;
+      }
+
+      ///Intersection of two boxes
+
+      ///Intersection of two boxes.
+      ///
+      Box operator&(const Box& u) const {
+        Box b;
+        if (_empty || u._empty) {
+          b._empty = true;
+        } else {
+          b._bottom_left.x = std::max(_bottom_left.x, u._bottom_left.x);
+          b._bottom_left.y = std::max(_bottom_left.y, u._bottom_left.y);
+          b._top_right.x = std::min(_top_right.x, u._top_right.x);
+          b._top_right.y = std::min(_top_right.y, u._top_right.y);
+          b._empty = b._bottom_left.x > b._top_right.x ||
+                     b._bottom_left.y > b._top_right.y;
+        }
+        return b;
+      }
+
+  };//class Box
+
+
+  ///Read a box from a stream
+
+  ///Read a box from a stream.
+  ///\relates Box
+  template<typename T>
+  inline std::istream& operator>>(std::istream &is, Box<T>& b) {
+    char c;
+    Point<T> p;
+    if (is >> c) {
+      if (c != '(') is.putback(c);
+    } else {
+      is.clear();
+    }
+    if (!(is >> p)) return is;
+    b.bottomLeft(p);
+    if (is >> c) {
+      if (c != ',') is.putback(c);
+    } else {
+      is.clear();
+    }
+    if (!(is >> p)) return is;
+    b.topRight(p);
+    if (is >> c) {
+      if (c != ')') is.putback(c);
+    } else {
+      is.clear();
+    }
+    return is;
+  }
+
+  ///Write a box to a stream
+
+  ///Write a box to a stream.
+  ///\relates Box
+  template<typename T>
+  inline std::ostream& operator<<(std::ostream &os, const Box<T>& b)
+  {
+    os << "(" << b.bottomLeft() << "," << b.topRight() << ")";
+    return os;
+  }
+
+  ///Map of x-coordinates of a <tt>Point</tt>-map
+
+  ///Map of x-coordinates of a \ref Point "Point"-map.
+  ///
+  template<class M>
+  class XMap
+  {
+    M& _map;
+  public:
+
+    typedef typename M::Value::Value Value;
+    typedef typename M::Key Key;
+    ///\e
+    XMap(M& map) : _map(map) {}
+    Value operator[](Key k) const {return _map[k].x;}
+    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
+  };
+
+  ///Returns an XMap class
+
+  ///This function just returns an XMap class.
+  ///\relates XMap
+  template<class M>
+  inline XMap<M> xMap(M &m)
+  {
+    return XMap<M>(m);
+  }
+
+  template<class M>
+  inline XMap<M> xMap(const M &m)
+  {
+    return XMap<M>(m);
+  }
+
+  ///Constant (read only) version of XMap
+
+  ///Constant (read only) version of XMap.
+  ///
+  template<class M>
+  class ConstXMap
+  {
+    const M& _map;
+  public:
+
+    typedef typename M::Value::Value Value;
+    typedef typename M::Key Key;
+    ///\e
+    ConstXMap(const M &map) : _map(map) {}
+    Value operator[](Key k) const {return _map[k].x;}
+  };
+
+  ///Returns a ConstXMap class
+
+  ///This function just returns a ConstXMap class.
+  ///\relates ConstXMap
+  template<class M>
+  inline ConstXMap<M> xMap(const M &m)
+  {
+    return ConstXMap<M>(m);
+  }
+
+  ///Map of y-coordinates of a <tt>Point</tt>-map
+
+  ///Map of y-coordinates of a \ref Point "Point"-map.
+  ///
+  template<class M>
+  class YMap
+  {
+    M& _map;
+  public:
+
+    typedef typename M::Value::Value Value;
+    typedef typename M::Key Key;
+    ///\e
+    YMap(M& map) : _map(map) {}
+    Value operator[](Key k) const {return _map[k].y;}
+    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
+  };
+
+  ///Returns a YMap class
+
+  ///This function just returns a YMap class.
+  ///\relates YMap
+  template<class M>
+  inline YMap<M> yMap(M &m)
+  {
+    return YMap<M>(m);
+  }
+
+  template<class M>
+  inline YMap<M> yMap(const M &m)
+  {
+    return YMap<M>(m);
+  }
+
+  ///Constant (read only) version of YMap
+
+  ///Constant (read only) version of YMap.
+  ///
+  template<class M>
+  class ConstYMap
+  {
+    const M& _map;
+  public:
+
+    typedef typename M::Value::Value Value;
+    typedef typename M::Key Key;
+    ///\e
+    ConstYMap(const M &map) : _map(map) {}
+    Value operator[](Key k) const {return _map[k].y;}
+  };
+
+  ///Returns a ConstYMap class
+
+  ///This function just returns a ConstYMap class.
+  ///\relates ConstYMap
+  template<class M>
+  inline ConstYMap<M> yMap(const M &m)
+  {
+    return ConstYMap<M>(m);
+  }
+
+
+  ///\brief Map of the normSquare() of a <tt>Point</tt>-map
+  ///
+  ///Map of the \ref Point::normSquare() "normSquare()"
+  ///of a \ref Point "Point"-map.
+  template<class M>
+  class NormSquareMap
+  {
+    const M& _map;
+  public:
+
+    typedef typename M::Value::Value Value;
+    typedef typename M::Key Key;
+    ///\e
+    NormSquareMap(const M &map) : _map(map) {}
+    Value operator[](Key k) const {return _map[k].normSquare();}
+  };
+
+  ///Returns a NormSquareMap class
+
+  ///This function just returns a NormSquareMap class.
+  ///\relates NormSquareMap
+  template<class M>
+  inline NormSquareMap<M> normSquareMap(const M &m)
+  {
+    return NormSquareMap<M>(m);
+  }
+
+  /// @}
+
+  } //namespce dim2
+
+} //namespace lemon
+
+#endif //LEMON_DIM2_H
diff --git a/lemon/dimacs.h b/lemon/dimacs.h
new file mode 100644
index 0000000..616879f
--- /dev/null
+++ b/lemon/dimacs.h
@@ -0,0 +1,448 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_DIMACS_H
+#define LEMON_DIMACS_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <limits>
+#include <lemon/maps.h>
+#include <lemon/error.h>
+/// \ingroup dimacs_group
+/// \file
+/// \brief DIMACS file format reader.
+
+namespace lemon {
+
+  /// \addtogroup dimacs_group
+  /// @{
+
+  /// DIMACS file type descriptor.
+  struct DimacsDescriptor
+  {
+    ///\brief DIMACS file type enum
+    ///
+    ///DIMACS file type enum.
+    enum Type {
+      NONE,  ///< Undefined type.
+      MIN,   ///< DIMACS file type for minimum cost flow problems.
+      MAX,   ///< DIMACS file type for maximum flow problems.
+      SP,    ///< DIMACS file type for shostest path problems.
+      MAT    ///< DIMACS file type for plain graphs and matching problems.
+    };
+    ///The file type
+    Type type;
+    ///The number of nodes in the graph
+    int nodeNum;
+    ///The number of edges in the graph
+    int edgeNum;
+    int lineShift;
+    ///Constructor. It sets the type to \c NONE.
+    DimacsDescriptor() : type(NONE) {}
+  };
+
+  ///Discover the type of a DIMACS file
+
+  ///This function starts seeking the beginning of the given file for the
+  ///problem type and size info.
+  ///The found data is returned in a special struct that can be evaluated
+  ///and passed to the appropriate reader function.
+  DimacsDescriptor dimacsType(std::istream& is)
+  {
+    DimacsDescriptor r;
+    std::string problem,str;
+    char c;
+    r.lineShift=0;
+    while (is >> c)
+      switch(c)
+        {
+        case 'p':
+          if(is >> problem >> r.nodeNum >> r.edgeNum)
+            {
+              getline(is, str);
+              r.lineShift++;
+              if(problem=="min") r.type=DimacsDescriptor::MIN;
+              else if(problem=="max") r.type=DimacsDescriptor::MAX;
+              else if(problem=="sp") r.type=DimacsDescriptor::SP;
+              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
+              else throw FormatError("Unknown problem type");
+              return r;
+            }
+          else
+            {
+              throw FormatError("Missing or wrong problem type declaration.");
+            }
+          break;
+        case 'c':
+          getline(is, str);
+          r.lineShift++;
+          break;
+        default:
+          throw FormatError("Unknown DIMACS declaration.");
+        }
+    throw FormatError("Missing problem type declaration.");
+  }
+
+
+  /// \brief DIMACS minimum cost flow reader function.
+  ///
+  /// This function reads a minimum cost flow instance from DIMACS format,
+  /// i.e. from a DIMACS file having a line starting with
+  /// \code
+  ///   p min
+  /// \endcode
+  /// At the beginning, \c g is cleared by \c g.clear(). The supply
+  /// amount of the nodes are written to the \c supply node map
+  /// (they are signed values). The lower bounds, capacities and costs
+  /// of the arcs are written to the \c lower, \c capacity and \c cost
+  /// arc maps.
+  ///
+  /// If the capacity of an arc is less than the lower bound, it will
+  /// be set to "infinite" instead. The actual value of "infinite" is
+  /// contolled by the \c infty parameter. If it is 0 (the default value),
+  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
+  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
+  /// a non-zero value, that value will be used as "infinite".
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template <typename Digraph, typename LowerMap,
+            typename CapacityMap, typename CostMap,
+            typename SupplyMap>
+  void readDimacsMin(std::istream& is,
+                     Digraph &g,
+                     LowerMap& lower,
+                     CapacityMap& capacity,
+                     CostMap& cost,
+                     SupplyMap& supply,
+                     typename CapacityMap::Value infty = 0,
+                     DimacsDescriptor desc=DimacsDescriptor())
+  {
+    g.clear();
+    std::vector<typename Digraph::Node> nodes;
+    typename Digraph::Arc e;
+    std::string problem, str;
+    char c;
+    int i, j;
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::MIN)
+      throw FormatError("Problem type mismatch");
+
+    nodes.resize(desc.nodeNum + 1);
+    for (int k = 1; k <= desc.nodeNum; ++k) {
+      nodes[k] = g.addNode();
+      supply.set(nodes[k], 0);
+    }
+
+    typename SupplyMap::Value sup;
+    typename CapacityMap::Value low;
+    typename CapacityMap::Value cap;
+    typename CostMap::Value co;
+    typedef typename CapacityMap::Value Capacity;
+    if(infty==0)
+      infty = std::numeric_limits<Capacity>::has_infinity ?
+        std::numeric_limits<Capacity>::infinity() :
+        std::numeric_limits<Capacity>::max();
+
+    while (is >> c) {
+      switch (c) {
+      case 'c': // comment line
+        getline(is, str);
+        break;
+      case 'n': // node definition line
+        is >> i >> sup;
+        getline(is, str);
+        supply.set(nodes[i], sup);
+        break;
+      case 'a': // arc definition line
+        is >> i >> j >> low >> cap >> co;
+        getline(is, str);
+        e = g.addArc(nodes[i], nodes[j]);
+        lower.set(e, low);
+        if (cap >= low)
+          capacity.set(e, cap);
+        else
+          capacity.set(e, infty);
+        cost.set(e, co);
+        break;
+      }
+    }
+  }
+
+  template<typename Digraph, typename CapacityMap>
+  void _readDimacs(std::istream& is,
+                   Digraph &g,
+                   CapacityMap& capacity,
+                   typename Digraph::Node &s,
+                   typename Digraph::Node &t,
+                   typename CapacityMap::Value infty = 0,
+                   DimacsDescriptor desc=DimacsDescriptor()) {
+    g.clear();
+    s=t=INVALID;
+    std::vector<typename Digraph::Node> nodes;
+    typename Digraph::Arc e;
+    char c, d;
+    int i, j;
+    typename CapacityMap::Value _cap;
+    std::string str;
+    nodes.resize(desc.nodeNum + 1);
+    for (int k = 1; k <= desc.nodeNum; ++k) {
+      nodes[k] = g.addNode();
+    }
+    typedef typename CapacityMap::Value Capacity;
+
+    if(infty==0)
+      infty = std::numeric_limits<Capacity>::has_infinity ?
+        std::numeric_limits<Capacity>::infinity() :
+        std::numeric_limits<Capacity>::max();
+
+    while (is >> c) {
+      switch (c) {
+      case 'c': // comment line
+        getline(is, str);
+        break;
+      case 'n': // node definition line
+        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
+          is >> i;
+          getline(is, str);
+          s = nodes[i];
+        }
+        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
+          is >> i >> d;
+          getline(is, str);
+          if (d == 's') s = nodes[i];
+          if (d == 't') t = nodes[i];
+        }
+        break;
+      case 'a': // arc definition line
+        if (desc.type==DimacsDescriptor::SP) {
+          is >> i >> j >> _cap;
+          getline(is, str);
+          e = g.addArc(nodes[i], nodes[j]);
+          capacity.set(e, _cap);
+        }
+        else if (desc.type==DimacsDescriptor::MAX) {
+          is >> i >> j >> _cap;
+          getline(is, str);
+          e = g.addArc(nodes[i], nodes[j]);
+          if (_cap >= 0)
+            capacity.set(e, _cap);
+          else
+            capacity.set(e, infty);
+        }
+        else {
+          is >> i >> j;
+          getline(is, str);
+          g.addArc(nodes[i], nodes[j]);
+        }
+        break;
+      }
+    }
+  }
+
+  /// \brief DIMACS maximum flow reader function.
+  ///
+  /// This function reads a maximum flow instance from DIMACS format,
+  /// i.e. from a DIMACS file having a line starting with
+  /// \code
+  ///   p max
+  /// \endcode
+  /// At the beginning, \c g is cleared by \c g.clear(). The arc
+  /// capacities are written to the \c capacity arc map and \c s and
+  /// \c t are set to the source and the target nodes.
+  ///
+  /// If the capacity of an arc is negative, it will
+  /// be set to "infinite" instead. The actual value of "infinite" is
+  /// contolled by the \c infty parameter. If it is 0 (the default value),
+  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
+  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
+  /// a non-zero value, that value will be used as "infinite".
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template<typename Digraph, typename CapacityMap>
+  void readDimacsMax(std::istream& is,
+                     Digraph &g,
+                     CapacityMap& capacity,
+                     typename Digraph::Node &s,
+                     typename Digraph::Node &t,
+                     typename CapacityMap::Value infty = 0,
+                     DimacsDescriptor desc=DimacsDescriptor()) {
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::MAX)
+      throw FormatError("Problem type mismatch");
+    _readDimacs(is,g,capacity,s,t,infty,desc);
+  }
+
+  /// \brief DIMACS shortest path reader function.
+  ///
+  /// This function reads a shortest path instance from DIMACS format,
+  /// i.e. from a DIMACS file having a line starting with
+  /// \code
+  ///   p sp
+  /// \endcode
+  /// At the beginning, \c g is cleared by \c g.clear(). The arc
+  /// lengths are written to the \c length arc map and \c s is set to the
+  /// source node.
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template<typename Digraph, typename LengthMap>
+  void readDimacsSp(std::istream& is,
+                    Digraph &g,
+                    LengthMap& length,
+                    typename Digraph::Node &s,
+                    DimacsDescriptor desc=DimacsDescriptor()) {
+    typename Digraph::Node t;
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::SP)
+      throw FormatError("Problem type mismatch");
+    _readDimacs(is, g, length, s, t, 0, desc);
+  }
+
+  /// \brief DIMACS capacitated digraph reader function.
+  ///
+  /// This function reads an arc capacitated digraph instance from
+  /// DIMACS 'max' or 'sp' format.
+  /// At the beginning, \c g is cleared by \c g.clear()
+  /// and the arc capacities/lengths are written to the \c capacity
+  /// arc map.
+  ///
+  /// In case of the 'max' format, if the capacity of an arc is negative,
+  /// it will
+  /// be set to "infinite" instead. The actual value of "infinite" is
+  /// contolled by the \c infty parameter. If it is 0 (the default value),
+  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
+  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
+  /// a non-zero value, that value will be used as "infinite".
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template<typename Digraph, typename CapacityMap>
+  void readDimacsCap(std::istream& is,
+                     Digraph &g,
+                     CapacityMap& capacity,
+                     typename CapacityMap::Value infty = 0,
+                     DimacsDescriptor desc=DimacsDescriptor()) {
+    typename Digraph::Node u,v;
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
+      throw FormatError("Problem type mismatch");
+    _readDimacs(is, g, capacity, u, v, infty, desc);
+  }
+
+  template<typename Graph>
+  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
+  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
+              dummy<0> = 0)
+  {
+    g.addEdge(s,t);
+  }
+  template<typename Graph>
+  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
+  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
+              dummy<1> = 1)
+  {
+    g.addArc(s,t);
+  }
+
+  /// \brief DIMACS plain (di)graph reader function.
+  ///
+  /// This function reads a plain (di)graph without any designated nodes
+  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
+  /// DIMACS files having a line starting with
+  /// \code
+  ///   p mat
+  /// \endcode
+  /// At the beginning, \c g is cleared by \c g.clear().
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template<typename Graph>
+  void readDimacsMat(std::istream& is, Graph &g,
+                     DimacsDescriptor desc=DimacsDescriptor())
+  {
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::MAT)
+      throw FormatError("Problem type mismatch");
+
+    g.clear();
+    std::vector<typename Graph::Node> nodes;
+    char c;
+    int i, j;
+    std::string str;
+    nodes.resize(desc.nodeNum + 1);
+    for (int k = 1; k <= desc.nodeNum; ++k) {
+      nodes[k] = g.addNode();
+    }
+
+    while (is >> c) {
+      switch (c) {
+      case 'c': // comment line
+        getline(is, str);
+        break;
+      case 'n': // node definition line
+        break;
+      case 'a': // arc definition line
+        is >> i >> j;
+        getline(is, str);
+        _addArcEdge(g,nodes[i], nodes[j]);
+        break;
+      }
+    }
+  }
+
+  /// DIMACS plain digraph writer function.
+  ///
+  /// This function writes a digraph without any designated nodes and
+  /// maps into DIMACS format, i.e. into DIMACS file having a line
+  /// starting with
+  /// \code
+  ///   p mat
+  /// \endcode
+  /// If \c comment is not empty, then it will be printed in the first line
+  /// prefixed by 'c'.
+  template<typename Digraph>
+  void writeDimacsMat(std::ostream& os, const Digraph &g,
+                      std::string comment="") {
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::ArcIt ArcIt;
+
+    if(!comment.empty())
+      os << "c " << comment << std::endl;
+    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
+
+    typename Digraph::template NodeMap<int> nodes(g);
+    int i = 1;
+    for(NodeIt v(g); v != INVALID; ++v) {
+      nodes.set(v, i);
+      ++i;
+    }
+    for(ArcIt e(g); e != INVALID; ++e) {
+      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
+         << std::endl;
+    }
+  }
+
+  /// @}
+
+} //namespace lemon
+
+#endif //LEMON_DIMACS_H
diff --git a/lemon/edge_set.h b/lemon/edge_set.h
new file mode 100644
index 0000000..399b7a2
--- /dev/null
+++ b/lemon/edge_set.h
@@ -0,0 +1,1420 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_EDGE_SET_H
+#define LEMON_EDGE_SET_H
+
+#include <lemon/core.h>
+#include <lemon/bits/edge_set_extender.h>
+
+/// \ingroup graphs
+/// \file
+/// \brief ArcSet and EdgeSet classes.
+///
+/// Graphs which use another graph's node-set as own.
+namespace lemon {
+
+  template <typename GR>
+  class ListArcSetBase {
+  public:
+
+    typedef typename GR::Node Node;
+    typedef typename GR::NodeIt NodeIt;
+
+  protected:
+
+    struct NodeT {
+      int first_out, first_in;
+      NodeT() : first_out(-1), first_in(-1) {}
+    };
+
+    typedef typename ItemSetTraits<GR, Node>::
+    template Map<NodeT>::Type NodesImplBase;
+
+    NodesImplBase* _nodes;
+
+    struct ArcT {
+      Node source, target;
+      int next_out, next_in;
+      int prev_out, prev_in;
+      ArcT() : prev_out(-1), prev_in(-1) {}
+    };
+
+    std::vector<ArcT> arcs;
+
+    int first_arc;
+    int first_free_arc;
+
+    const GR* _graph;
+
+    void initalize(const GR& graph, NodesImplBase& nodes) {
+      _graph = &graph;
+      _nodes = &nodes;
+    }
+
+  public:
+
+    class Arc {
+      friend class ListArcSetBase<GR>;
+    protected:
+      Arc(int _id) : id(_id) {}
+      int 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; }
+    };
+
+    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
+
+    Node addNode() {
+      LEMON_ASSERT(false,
+        "This graph structure does not support node insertion");
+      return INVALID; // avoid warning
+    }
+
+    Arc addArc(const Node& u, const Node& v) {
+      int n;
+      if (first_free_arc == -1) {
+        n = arcs.size();
+        arcs.push_back(ArcT());
+      } else {
+        n = first_free_arc;
+        first_free_arc = arcs[first_free_arc].next_in;
+      }
+      arcs[n].next_in = (*_nodes)[v].first_in;
+      if ((*_nodes)[v].first_in != -1) {
+        arcs[(*_nodes)[v].first_in].prev_in = n;
+      }
+      (*_nodes)[v].first_in = n;
+      arcs[n].next_out = (*_nodes)[u].first_out;
+      if ((*_nodes)[u].first_out != -1) {
+        arcs[(*_nodes)[u].first_out].prev_out = n;
+      }
+      (*_nodes)[u].first_out = n;
+      arcs[n].source = u;
+      arcs[n].target = v;
+      return Arc(n);
+    }
+
+    void erase(const Arc& arc) {
+      int n = arc.id;
+      if (arcs[n].prev_in != -1) {
+        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
+      } else {
+        (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
+      }
+      if (arcs[n].next_in != -1) {
+        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
+      }
+
+      if (arcs[n].prev_out != -1) {
+        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
+      } else {
+        (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
+      }
+      if (arcs[n].next_out != -1) {
+        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
+      }
+
+    }
+
+    void clear() {
+      Node node;
+      for (first(node); node != INVALID; next(node)) {
+        (*_nodes)[node].first_in = -1;
+        (*_nodes)[node].first_out = -1;
+      }
+      arcs.clear();
+      first_arc = -1;
+      first_free_arc = -1;
+    }
+
+    void first(Node& node) const {
+      _graph->first(node);
+    }
+
+    void next(Node& node) const {
+      _graph->next(node);
+    }
+
+    void first(Arc& arc) const {
+      Node node;
+      first(node);
+      while (node != INVALID && (*_nodes)[node].first_in == -1) {
+        next(node);
+      }
+      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
+    }
+
+    void next(Arc& arc) const {
+      if (arcs[arc.id].next_in != -1) {
+        arc.id = arcs[arc.id].next_in;
+      } else {
+        Node node = arcs[arc.id].target;
+        next(node);
+        while (node != INVALID && (*_nodes)[node].first_in == -1) {
+          next(node);
+        }
+        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
+      }
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc.id = (*_nodes)[node].first_out;
+    }
+
+    void nextOut(Arc& arc) const {
+      arc.id = arcs[arc.id].next_out;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc.id = (*_nodes)[node].first_in;
+    }
+
+    void nextIn(Arc& arc) const {
+      arc.id = arcs[arc.id].next_in;
+    }
+
+    int id(const Node& node) const { return _graph->id(node); }
+    int id(const Arc& arc) const { return arc.id; }
+
+    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
+    Arc arcFromId(int ix) const { return Arc(ix); }
+
+    int maxNodeId() const { return _graph->maxNodeId(); };
+    int maxArcId() const { return arcs.size() - 1; }
+
+    Node source(const Arc& arc) const { return arcs[arc.id].source;}
+    Node target(const Arc& arc) const { return arcs[arc.id].target;}
+
+    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
+
+    NodeNotifier& notifier(Node) const {
+      return _graph->notifier(Node());
+    }
+
+    template <typename V>
+    class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
+    public:
+
+      explicit NodeMap(const ListArcSetBase<GR>& arcset)
+        : Parent(*arcset._graph) {}
+
+      NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
+        : Parent(*arcset._graph, value) {}
+
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  /// \ingroup graphs
+  ///
+  /// \brief Digraph using a node set of another digraph or graph and
+  /// an own arc set.
+  ///
+  /// This structure can be used to establish another directed graph
+  /// over a node set of an existing one. This class uses the same
+  /// Node type as the underlying graph, and each valid node of the
+  /// original graph is valid in this arc set, therefore the node
+  /// objects of the original graph can be used directly with this
+  /// class. The node handling functions (id handling, observing, and
+  /// iterators) works equivalently as in the original graph.
+  ///
+  /// This implementation is based on doubly-linked lists, from each
+  /// node the outgoing and the incoming arcs make up lists, therefore
+  /// one arc can be erased in constant time. It also makes possible,
+  /// that node can be removed from the underlying graph, in this case
+  /// 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.
+  template <typename GR>
+  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
+    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    typedef typename Parent::NodesImplBase NodesImplBase;
+
+    void eraseNode(const Node& node) {
+      Arc arc;
+      Parent::firstOut(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstOut(arc, node);
+      }
+
+      Parent::firstIn(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstIn(arc, node);
+      }
+    }
+
+    void clearNodes() {
+      Parent::clear();
+    }
+
+    class NodesImpl : public NodesImplBase {
+      typedef NodesImplBase Parent;
+
+    public:
+      NodesImpl(const GR& graph, ListArcSet& arcset)
+        : Parent(graph), _arcset(arcset) {}
+
+      virtual ~NodesImpl() {}
+
+    protected:
+
+      virtual void erase(const Node& node) {
+        _arcset.eraseNode(node);
+        Parent::erase(node);
+      }
+      virtual void erase(const std::vector<Node>& nodes) {
+        for (int i = 0; i < int(nodes.size()); ++i) {
+          _arcset.eraseNode(nodes[i]);
+        }
+        Parent::erase(nodes);
+      }
+      virtual void clear() {
+        _arcset.clearNodes();
+        Parent::clear();
+      }
+
+    private:
+      ListArcSet& _arcset;
+    };
+
+    NodesImpl _nodes;
+
+  public:
+
+    /// \brief Constructor of the ArcSet.
+    ///
+    /// Constructor of the ArcSet.
+    ListArcSet(const GR& graph) : _nodes(graph, *this) {
+      Parent::initalize(graph, _nodes);
+    }
+
+    /// \brief Add a new arc to the digraph.
+    ///
+    /// Add 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) {
+      return Parent::addArc(s, t);
+    }
+
+    /// \brief Erase an arc from the digraph.
+    ///
+    /// Erase an arc \c a from the digraph.
+    void erase(const Arc& a) {
+      return Parent::erase(a);
+    }
+
+  };
+
+  template <typename GR>
+  class ListEdgeSetBase {
+  public:
+
+    typedef typename GR::Node Node;
+    typedef typename GR::NodeIt NodeIt;
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      NodeT() : first_out(-1) {}
+    };
+
+    typedef typename ItemSetTraits<GR, Node>::
+    template Map<NodeT>::Type NodesImplBase;
+
+    NodesImplBase* _nodes;
+
+    struct ArcT {
+      Node target;
+      int prev_out, next_out;
+      ArcT() : prev_out(-1), next_out(-1) {}
+    };
+
+    std::vector<ArcT> arcs;
+
+    int first_arc;
+    int first_free_arc;
+
+    const GR* _graph;
+
+    void initalize(const GR& graph, NodesImplBase& nodes) {
+      _graph = &graph;
+      _nodes = &nodes;
+    }
+
+  public:
+
+    class Edge {
+      friend class ListEdgeSetBase;
+    protected:
+
+      int id;
+      explicit Edge(int _id) { id = _id;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { id = -1; }
+      bool operator==(const Edge& arc) const {return id == arc.id;}
+      bool operator!=(const Edge& arc) const {return id != arc.id;}
+      bool operator<(const Edge& arc) const {return id < arc.id;}
+    };
+
+    class Arc {
+      friend class ListEdgeSetBase;
+    protected:
+      Arc(int _id) : id(_id) {}
+      int id;
+    public:
+      operator Edge() const { return edgeFromId(id / 2); }
+
+      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; }
+    };
+
+    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
+
+    Node addNode() {
+      LEMON_ASSERT(false,
+        "This graph structure does not support node insertion");
+      return INVALID; // avoid warning
+    }
+
+    Edge addEdge(const Node& u, const Node& v) {
+      int n;
+
+      if (first_free_arc == -1) {
+        n = arcs.size();
+        arcs.push_back(ArcT());
+        arcs.push_back(ArcT());
+      } else {
+        n = first_free_arc;
+        first_free_arc = arcs[n].next_out;
+      }
+
+      arcs[n].target = u;
+      arcs[n | 1].target = v;
+
+      arcs[n].next_out = (*_nodes)[v].first_out;
+      if ((*_nodes)[v].first_out != -1) {
+        arcs[(*_nodes)[v].first_out].prev_out = n;
+      }
+      (*_nodes)[v].first_out = n;
+      arcs[n].prev_out = -1;
+
+      if ((*_nodes)[u].first_out != -1) {
+        arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
+      }
+      arcs[n | 1].next_out = (*_nodes)[u].first_out;
+      (*_nodes)[u].first_out = (n | 1);
+      arcs[n | 1].prev_out = -1;
+
+      return Edge(n / 2);
+    }
+
+    void erase(const Edge& arc) {
+      int n = arc.id * 2;
+
+      if (arcs[n].next_out != -1) {
+        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
+      }
+
+      if (arcs[n].prev_out != -1) {
+        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
+      } else {
+        (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
+      }
+
+      if (arcs[n | 1].next_out != -1) {
+        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
+      }
+
+      if (arcs[n | 1].prev_out != -1) {
+        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
+      } else {
+        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
+      }
+
+      arcs[n].next_out = first_free_arc;
+      first_free_arc = n;
+
+    }
+
+    void clear() {
+      Node node;
+      for (first(node); node != INVALID; next(node)) {
+        (*_nodes)[node].first_out = -1;
+      }
+      arcs.clear();
+      first_arc = -1;
+      first_free_arc = -1;
+    }
+
+    void first(Node& node) const {
+      _graph->first(node);
+    }
+
+    void next(Node& node) const {
+      _graph->next(node);
+    }
+
+    void first(Arc& arc) const {
+      Node node;
+      first(node);
+      while (node != INVALID && (*_nodes)[node].first_out == -1) {
+        next(node);
+      }
+      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
+    }
+
+    void next(Arc& arc) const {
+      if (arcs[arc.id].next_out != -1) {
+        arc.id = arcs[arc.id].next_out;
+      } else {
+        Node node = arcs[arc.id ^ 1].target;
+        next(node);
+        while(node != INVALID && (*_nodes)[node].first_out == -1) {
+          next(node);
+        }
+        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
+      }
+    }
+
+    void first(Edge& edge) const {
+      Node node;
+      first(node);
+      while (node != INVALID) {
+        edge.id = (*_nodes)[node].first_out;
+        while ((edge.id & 1) != 1) {
+          edge.id = arcs[edge.id].next_out;
+        }
+        if (edge.id != -1) {
+          edge.id /= 2;
+          return;
+        }
+        next(node);
+      }
+      edge.id = -1;
+    }
+
+    void next(Edge& edge) const {
+      Node node = arcs[edge.id * 2].target;
+      edge.id = arcs[(edge.id * 2) | 1].next_out;
+      while ((edge.id & 1) != 1) {
+        edge.id = arcs[edge.id].next_out;
+      }
+      if (edge.id != -1) {
+        edge.id /= 2;
+        return;
+      }
+      next(node);
+      while (node != INVALID) {
+        edge.id = (*_nodes)[node].first_out;
+        while ((edge.id & 1) != 1) {
+          edge.id = arcs[edge.id].next_out;
+        }
+        if (edge.id != -1) {
+          edge.id /= 2;
+          return;
+        }
+        next(node);
+      }
+      edge.id = -1;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc.id = (*_nodes)[node].first_out;
+    }
+
+    void nextOut(Arc& arc) const {
+      arc.id = arcs[arc.id].next_out;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc.id = (((*_nodes)[node].first_out) ^ 1);
+      if (arc.id == -2) arc.id = -1;
+    }
+
+    void nextIn(Arc& arc) const {
+      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
+      if (arc.id == -2) arc.id = -1;
+    }
+
+    void firstInc(Edge &arc, bool& dir, const Node& node) const {
+      int de = (*_nodes)[node].first_out;
+      if (de != -1 ) {
+        arc.id = de / 2;
+        dir = ((de & 1) == 1);
+      } else {
+        arc.id = -1;
+        dir = true;
+      }
+    }
+    void nextInc(Edge &arc, bool& dir) const {
+      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
+      if (de != -1 ) {
+        arc.id = de / 2;
+        dir = ((de & 1) == 1);
+      } else {
+        arc.id = -1;
+        dir = true;
+      }
+    }
+
+    static bool direction(Arc arc) {
+      return (arc.id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc(edge.id * 2 + (dir ? 1 : 0));
+    }
+
+    int id(const Node& node) const { return _graph->id(node); }
+    static int id(Arc e) { return e.id; }
+    static int id(Edge e) { return e.id; }
+
+    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    int maxNodeId() const { return _graph->maxNodeId(); };
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
+    Node target(Arc e) const { return arcs[e.id].target; }
+
+    Node u(Edge e) const { return arcs[2 * e.id].target; }
+    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
+
+    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
+
+    NodeNotifier& notifier(Node) const {
+      return _graph->notifier(Node());
+    }
+
+    template <typename V>
+    class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
+    public:
+
+      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
+        : Parent(*arcset._graph) {}
+
+      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
+        : Parent(*arcset._graph, value) {}
+
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  /// \ingroup graphs
+  ///
+  /// \brief Graph using a node set of another digraph or graph and an
+  /// own edge set.
+  ///
+  /// This structure can be used to establish another graph over a
+  /// node set of an existing one. This class uses the same Node type
+  /// as the underlying graph, and each valid node of the original
+  /// graph is valid in this arc set, therefore the node objects of
+  /// the original graph can be used directly with this class. The
+  /// node handling functions (id handling, observing, and iterators)
+  /// works equivalently as in the original graph.
+  ///
+  /// This implementation is based on doubly-linked lists, from each
+  /// node the incident edges make up lists, therefore one edge can be
+  /// erased in constant time. It also makes possible, that node can
+  /// be removed from the underlying graph, in this case all edges
+  /// 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.
+  template <typename GR>
+  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
+    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    typedef typename Parent::NodesImplBase NodesImplBase;
+
+    void eraseNode(const Node& node) {
+      Arc arc;
+      Parent::firstOut(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstOut(arc, node);
+      }
+
+    }
+
+    void clearNodes() {
+      Parent::clear();
+    }
+
+    class NodesImpl : public NodesImplBase {
+      typedef NodesImplBase Parent;
+
+    public:
+      NodesImpl(const GR& graph, ListEdgeSet& arcset)
+        : Parent(graph), _arcset(arcset) {}
+
+      virtual ~NodesImpl() {}
+
+    protected:
+
+      virtual void erase(const Node& node) {
+        _arcset.eraseNode(node);
+        Parent::erase(node);
+      }
+      virtual void erase(const std::vector<Node>& nodes) {
+        for (int i = 0; i < int(nodes.size()); ++i) {
+          _arcset.eraseNode(nodes[i]);
+        }
+        Parent::erase(nodes);
+      }
+      virtual void clear() {
+        _arcset.clearNodes();
+        Parent::clear();
+      }
+
+    private:
+      ListEdgeSet& _arcset;
+    };
+
+    NodesImpl _nodes;
+
+  public:
+
+    /// \brief Constructor of the EdgeSet.
+    ///
+    /// Constructor of the EdgeSet.
+    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
+      Parent::initalize(graph, _nodes);
+    }
+
+    /// \brief Add a new edge to the graph.
+    ///
+    /// Add a new edge to the graph with node \c u
+    /// and node \c v endpoints.
+    /// \return The new edge.
+    Edge addEdge(const Node& u, const Node& v) {
+      return Parent::addEdge(u, v);
+    }
+
+    /// \brief Erase an edge from the graph.
+    ///
+    /// Erase the edge \c e from the graph.
+    void erase(const Edge& e) {
+      return Parent::erase(e);
+    }
+
+  };
+
+  template <typename GR>
+  class SmartArcSetBase {
+  public:
+
+    typedef typename GR::Node Node;
+    typedef typename GR::NodeIt NodeIt;
+
+  protected:
+
+    struct NodeT {
+      int first_out, first_in;
+      NodeT() : first_out(-1), first_in(-1) {}
+    };
+
+    typedef typename ItemSetTraits<GR, Node>::
+    template Map<NodeT>::Type NodesImplBase;
+
+    NodesImplBase* _nodes;
+
+    struct ArcT {
+      Node source, target;
+      int next_out, next_in;
+      ArcT() {}
+    };
+
+    std::vector<ArcT> arcs;
+
+    const GR* _graph;
+
+    void initalize(const GR& graph, NodesImplBase& nodes) {
+      _graph = &graph;
+      _nodes = &nodes;
+    }
+
+  public:
+
+    class Arc {
+      friend class SmartArcSetBase<GR>;
+    protected:
+      Arc(int _id) : id(_id) {}
+      int 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; }
+    };
+
+    SmartArcSetBase() {}
+
+    Node addNode() {
+      LEMON_ASSERT(false,
+        "This graph structure does not support node insertion");
+      return INVALID; // avoid warning
+    }
+
+    Arc addArc(const Node& u, const Node& v) {
+      int n = arcs.size();
+      arcs.push_back(ArcT());
+      arcs[n].next_in = (*_nodes)[v].first_in;
+      (*_nodes)[v].first_in = n;
+      arcs[n].next_out = (*_nodes)[u].first_out;
+      (*_nodes)[u].first_out = n;
+      arcs[n].source = u;
+      arcs[n].target = v;
+      return Arc(n);
+    }
+
+    void clear() {
+      Node node;
+      for (first(node); node != INVALID; next(node)) {
+        (*_nodes)[node].first_in = -1;
+        (*_nodes)[node].first_out = -1;
+      }
+      arcs.clear();
+    }
+
+    void first(Node& node) const {
+      _graph->first(node);
+    }
+
+    void next(Node& node) const {
+      _graph->next(node);
+    }
+
+    void first(Arc& arc) const {
+      arc.id = arcs.size() - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc.id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc.id = (*_nodes)[node].first_out;
+    }
+
+    void nextOut(Arc& arc) const {
+      arc.id = arcs[arc.id].next_out;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc.id = (*_nodes)[node].first_in;
+    }
+
+    void nextIn(Arc& arc) const {
+      arc.id = arcs[arc.id].next_in;
+    }
+
+    int id(const Node& node) const { return _graph->id(node); }
+    int id(const Arc& arc) const { return arc.id; }
+
+    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
+    Arc arcFromId(int ix) const { return Arc(ix); }
+
+    int maxNodeId() const { return _graph->maxNodeId(); };
+    int maxArcId() const { return arcs.size() - 1; }
+
+    Node source(const Arc& arc) const { return arcs[arc.id].source;}
+    Node target(const Arc& arc) const { return arcs[arc.id].target;}
+
+    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
+
+    NodeNotifier& notifier(Node) const {
+      return _graph->notifier(Node());
+    }
+
+    template <typename V>
+    class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
+    public:
+
+      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
+        : Parent(*arcset._graph) { }
+
+      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
+        : Parent(*arcset._graph, value) { }
+
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+
+  /// \ingroup graphs
+  ///
+  /// \brief Digraph using a node set of another digraph or graph and
+  /// an own arc set.
+  ///
+  /// This structure can be used to establish another directed graph
+  /// over a node set of an existing one. This class uses the same
+  /// Node type as the underlying graph, and each valid node of the
+  /// original graph is valid in this arc set, therefore the node
+  /// objects of the original graph can be used directly with this
+  /// class. The node handling functions (id handling, observing, and
+  /// iterators) works equivalently as in the original graph.
+  ///
+  /// \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 implementation is slightly faster than the \c ListArcSet,
+  /// because it uses continuous storage for arcs and it uses just
+  /// single-linked lists for enumerate outgoing and incoming
+  /// 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.
+  template <typename GR>
+  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
+    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+  protected:
+
+    typedef typename Parent::NodesImplBase NodesImplBase;
+
+    void eraseNode(const Node& node) {
+      if (typename Parent::InArcIt(*this, node) == INVALID &&
+          typename Parent::OutArcIt(*this, node) == INVALID) {
+        return;
+      }
+      throw typename NodesImplBase::Notifier::ImmediateDetach();
+    }
+
+    void clearNodes() {
+      Parent::clear();
+    }
+
+    class NodesImpl : public NodesImplBase {
+      typedef NodesImplBase Parent;
+
+    public:
+      NodesImpl(const GR& graph, SmartArcSet& arcset)
+        : Parent(graph), _arcset(arcset) {}
+
+      virtual ~NodesImpl() {}
+
+      bool attached() const {
+        return Parent::attached();
+      }
+
+    protected:
+
+      virtual void erase(const Node& node) {
+        try {
+          _arcset.eraseNode(node);
+          Parent::erase(node);
+        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
+          Parent::clear();
+          throw;
+        }
+      }
+      virtual void erase(const std::vector<Node>& nodes) {
+        try {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            _arcset.eraseNode(nodes[i]);
+          }
+          Parent::erase(nodes);
+        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
+          Parent::clear();
+          throw;
+        }
+      }
+      virtual void clear() {
+        _arcset.clearNodes();
+        Parent::clear();
+      }
+
+    private:
+      SmartArcSet& _arcset;
+    };
+
+    NodesImpl _nodes;
+
+  public:
+
+    /// \brief Constructor of the ArcSet.
+    ///
+    /// Constructor of the ArcSet.
+    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
+      Parent::initalize(graph, _nodes);
+    }
+
+    /// \brief Add a new arc to the digraph.
+    ///
+    /// Add 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) {
+      return Parent::addArc(s, t);
+    }
+
+    /// \brief Validity check
+    ///
+    /// This functions gives back false if the ArcSet is
+    /// invalidated. It occurs when a node in the underlying graph is
+    /// erased and it is not isolated in the ArcSet.
+    bool valid() const {
+      return _nodes.attached();
+    }
+
+  };
+
+
+  template <typename GR>
+  class SmartEdgeSetBase {
+  public:
+
+    typedef typename GR::Node Node;
+    typedef typename GR::NodeIt NodeIt;
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      NodeT() : first_out(-1) {}
+    };
+
+    typedef typename ItemSetTraits<GR, Node>::
+    template Map<NodeT>::Type NodesImplBase;
+
+    NodesImplBase* _nodes;
+
+    struct ArcT {
+      Node target;
+      int next_out;
+      ArcT() {}
+    };
+
+    std::vector<ArcT> arcs;
+
+    const GR* _graph;
+
+    void initalize(const GR& graph, NodesImplBase& nodes) {
+      _graph = &graph;
+      _nodes = &nodes;
+    }
+
+  public:
+
+    class Edge {
+      friend class SmartEdgeSetBase;
+    protected:
+
+      int id;
+      explicit Edge(int _id) { id = _id;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { id = -1; }
+      bool operator==(const Edge& arc) const {return id == arc.id;}
+      bool operator!=(const Edge& arc) const {return id != arc.id;}
+      bool operator<(const Edge& arc) const {return id < arc.id;}
+    };
+
+    class Arc {
+      friend class SmartEdgeSetBase;
+    protected:
+      Arc(int _id) : id(_id) {}
+      int id;
+    public:
+      operator Edge() const { return edgeFromId(id / 2); }
+
+      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; }
+    };
+
+    SmartEdgeSetBase() {}
+
+    Node addNode() {
+      LEMON_ASSERT(false,
+        "This graph structure does not support node insertion");
+      return INVALID; // avoid warning
+    }
+
+    Edge addEdge(const Node& u, const Node& v) {
+      int n = arcs.size();
+      arcs.push_back(ArcT());
+      arcs.push_back(ArcT());
+
+      arcs[n].target = u;
+      arcs[n | 1].target = v;
+
+      arcs[n].next_out = (*_nodes)[v].first_out;
+      (*_nodes)[v].first_out = n;
+
+      arcs[n | 1].next_out = (*_nodes)[u].first_out;
+      (*_nodes)[u].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+
+    void clear() {
+      Node node;
+      for (first(node); node != INVALID; next(node)) {
+        (*_nodes)[node].first_out = -1;
+      }
+      arcs.clear();
+    }
+
+    void first(Node& node) const {
+      _graph->first(node);
+    }
+
+    void next(Node& node) const {
+      _graph->next(node);
+    }
+
+    void first(Arc& arc) const {
+      arc.id = arcs.size() - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc.id;
+    }
+
+    void first(Edge& arc) const {
+      arc.id = arcs.size() / 2 - 1;
+    }
+
+    static void next(Edge& arc) {
+      --arc.id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc.id = (*_nodes)[node].first_out;
+    }
+
+    void nextOut(Arc& arc) const {
+      arc.id = arcs[arc.id].next_out;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc.id = (((*_nodes)[node].first_out) ^ 1);
+      if (arc.id == -2) arc.id = -1;
+    }
+
+    void nextIn(Arc& arc) const {
+      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
+      if (arc.id == -2) arc.id = -1;
+    }
+
+    void firstInc(Edge &arc, bool& dir, const Node& node) const {
+      int de = (*_nodes)[node].first_out;
+      if (de != -1 ) {
+        arc.id = de / 2;
+        dir = ((de & 1) == 1);
+      } else {
+        arc.id = -1;
+        dir = true;
+      }
+    }
+    void nextInc(Edge &arc, bool& dir) const {
+      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
+      if (de != -1 ) {
+        arc.id = de / 2;
+        dir = ((de & 1) == 1);
+      } else {
+        arc.id = -1;
+        dir = true;
+      }
+    }
+
+    static bool direction(Arc arc) {
+      return (arc.id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc(edge.id * 2 + (dir ? 1 : 0));
+    }
+
+    int id(Node node) const { return _graph->id(node); }
+    static int id(Arc arc) { return arc.id; }
+    static int id(Edge arc) { return arc.id; }
+
+    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
+    static Arc arcFromId(int id) { return Arc(id); }
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    int maxNodeId() const { return _graph->maxNodeId(); };
+    int maxArcId() const { return arcs.size() - 1; }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+
+    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
+    Node target(Arc e) const { return arcs[e.id].target; }
+
+    Node u(Edge e) const { return arcs[2 * e.id].target; }
+    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
+
+    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
+
+    NodeNotifier& notifier(Node) const {
+      return _graph->notifier(Node());
+    }
+
+    template <typename V>
+    class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
+    public:
+
+      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
+        : Parent(*arcset._graph) { }
+
+      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
+        : Parent(*arcset._graph, value) { }
+
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  /// \ingroup graphs
+  ///
+  /// \brief Graph using a node set of another digraph or graph and an
+  /// own edge set.
+  ///
+  /// This structure can be used to establish another graph over a
+  /// node set of an existing one. This class uses the same Node type
+  /// as the underlying graph, and each valid node of the original
+  /// graph is valid in this arc set, therefore the node objects of
+  /// the original graph can be used directly with this class. The
+  /// node handling functions (id handling, observing, and iterators)
+  /// works equivalently as in the original graph.
+  ///
+  /// \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 implementation is slightly faster than the \c ListEdgeSet,
+  /// because it uses continuous storage for edges and it uses just
+  /// single-linked lists for enumerate incident edges. Therefore the
+  /// 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.
+  template <typename GR>
+  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
+    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+  protected:
+
+    typedef typename Parent::NodesImplBase NodesImplBase;
+
+    void eraseNode(const Node& node) {
+      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
+        return;
+      }
+      throw typename NodesImplBase::Notifier::ImmediateDetach();
+    }
+
+    void clearNodes() {
+      Parent::clear();
+    }
+
+    class NodesImpl : public NodesImplBase {
+      typedef NodesImplBase Parent;
+
+    public:
+      NodesImpl(const GR& graph, SmartEdgeSet& arcset)
+        : Parent(graph), _arcset(arcset) {}
+
+      virtual ~NodesImpl() {}
+
+      bool attached() const {
+        return Parent::attached();
+      }
+
+    protected:
+
+      virtual void erase(const Node& node) {
+        try {
+          _arcset.eraseNode(node);
+          Parent::erase(node);
+        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
+          Parent::clear();
+          throw;
+        }
+      }
+      virtual void erase(const std::vector<Node>& nodes) {
+        try {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            _arcset.eraseNode(nodes[i]);
+          }
+          Parent::erase(nodes);
+        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
+          Parent::clear();
+          throw;
+        }
+      }
+      virtual void clear() {
+        _arcset.clearNodes();
+        Parent::clear();
+      }
+
+    private:
+      SmartEdgeSet& _arcset;
+    };
+
+    NodesImpl _nodes;
+
+  public:
+
+    /// \brief Constructor of the EdgeSet.
+    ///
+    /// Constructor of the EdgeSet.
+    SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
+      Parent::initalize(graph, _nodes);
+    }
+
+    /// \brief Add a new edge to the graph.
+    ///
+    /// Add a new edge to the graph with node \c u
+    /// and node \c v endpoints.
+    /// \return The new edge.
+    Edge addEdge(const Node& u, const Node& v) {
+      return Parent::addEdge(u, v);
+    }
+
+    /// \brief Validity check
+    ///
+    /// This functions gives back false if the EdgeSet is
+    /// invalidated. It occurs when a node in the underlying graph is
+    /// erased and it is not isolated in the EdgeSet.
+    bool valid() const {
+      return _nodes.attached();
+    }
+
+  };
+
+}
+
+#endif
diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
new file mode 100644
index 0000000..92af3cb
--- /dev/null
+++ b/lemon/edmonds_karp.h
@@ -0,0 +1,556 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_EDMONDS_KARP_H
+#define LEMON_EDMONDS_KARP_H
+
+/// \file
+/// \ingroup max_flow
+/// \brief Implementation of the Edmonds-Karp algorithm.
+
+#include <lemon/tolerance.h>
+#include <vector>
+
+namespace lemon {
+
+  /// \brief Default traits class of EdmondsKarp class.
+  ///
+  /// Default traits class of EdmondsKarp class.
+  /// \param GR Digraph type.
+  /// \param CAP Type of capacity map.
+  template <typename GR, typename CAP>
+  struct EdmondsKarpDefaultTraits {
+
+    /// \brief The digraph type the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc capacities.
+    ///
+    /// The type of the map that stores the arc capacities.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef CAP CapacityMap;
+
+    /// \brief The type of the flow values.
+    typedef typename CapacityMap::Value Value;
+
+    /// \brief The type of the map that stores the flow values.
+    ///
+    /// The type of the map that stores the flow values.
+    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+#ifdef DOXYGEN
+    typedef GR::ArcMap<Value> FlowMap;
+#else
+    typedef typename Digraph::template ArcMap<Value> FlowMap;
+#endif
+
+    /// \brief Instantiates a FlowMap.
+    ///
+    /// This function instantiates a \ref FlowMap.
+    /// \param digraph The digraph for which we would like to define
+    /// the flow map.
+    static FlowMap* createFlowMap(const Digraph& digraph) {
+      return new FlowMap(digraph);
+    }
+
+    /// \brief The tolerance used by the algorithm
+    ///
+    /// The tolerance used by the algorithm to handle inexact computation.
+    typedef lemon::Tolerance<Value> Tolerance;
+
+  };
+
+  /// \ingroup max_flow
+  ///
+  /// \brief Edmonds-Karp algorithms class.
+  ///
+  /// This class provides an implementation of the \e Edmonds-Karp \e
+  /// algorithm producing a \ref max_flow "flow of maximum value" in a
+  /// digraph \cite clrs01algorithms, \cite amo93networkflows,
+  /// \cite edmondskarp72theoretical.
+  /// The Edmonds-Karp algorithm is slower than the Preflow
+  /// algorithm, but it has an advantage of the step-by-step execution
+  /// control with feasible flow solutions. The \e source node, the \e
+  /// target node, the \e capacity of the arcs and the \e starting \e
+  /// flow value of the arcs should be passed to the algorithm
+  /// through the constructor.
+  ///
+  /// The time complexity of the algorithm is \f$ O(nm^2) \f$ in
+  /// worst case. Always try the Preflow algorithm instead of this if
+  /// you just want to compute the optimal flow.
+  ///
+  /// \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 EdmondsKarpDefaultTraits
+  /// "EdmondsKarpDefaultTraits<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>
+#else
+  template <typename GR,
+            typename CAP = typename GR::template ArcMap<int>,
+            typename TR = EdmondsKarpDefaultTraits<GR, CAP> >
+#endif
+  class EdmondsKarp {
+  public:
+
+    /// \brief The \ref lemon::EdmondsKarpDefaultTraits "traits class"
+    /// of the algorithm.
+    typedef TR Traits;
+    /// The type of the digraph the algorithm runs on.
+    typedef typename Traits::Digraph Digraph;
+    /// The type of the capacity map.
+    typedef typename Traits::CapacityMap CapacityMap;
+    /// The type of the flow values.
+    typedef typename Traits::Value Value;
+
+    /// The type of the flow map.
+    typedef typename Traits::FlowMap FlowMap;
+    /// The type of the tolerance.
+    typedef typename Traits::Tolerance Tolerance;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+    typedef typename Digraph::template NodeMap<Arc> PredMap;
+
+    const Digraph& _graph;
+    const CapacityMap* _capacity;
+
+    Node _source, _target;
+
+    FlowMap* _flow;
+    bool _local_flow;
+
+    PredMap* _pred;
+    std::vector<Node> _queue;
+
+    Tolerance _tolerance;
+    Value _flow_value;
+
+    void createStructures() {
+      if (!_flow) {
+        _flow = Traits::createFlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_pred) {
+        _pred = new PredMap(_graph);
+      }
+      _queue.resize(countNodes(_graph));
+    }
+
+    void destroyStructures() {
+      if (_local_flow) {
+        delete _flow;
+      }
+      if (_pred) {
+        delete _pred;
+      }
+    }
+
+  public:
+
+    typedef EdmondsKarp Create;
+
+    ///\name Named template parameters
+
+    ///@{
+
+    template <typename T>
+    struct SetFlowMapTraits : public Traits {
+      typedef T FlowMap;
+      static FlowMap *createFlowMap(const Digraph&) {
+        LEMON_ASSERT(false, "FlowMap is not initialized");
+        return 0;
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// FlowMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting FlowMap
+    /// type
+    template <typename T>
+    struct SetFlowMap
+      : public EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > {
+      typedef EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    EdmondsKarp() {}
+
+  public:
+
+    /// \brief The constructor of the class.
+    ///
+    /// The constructor of the class.
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param capacity The capacity of the arcs.
+    /// \param source The source node.
+    /// \param target The target node.
+    EdmondsKarp(const Digraph& digraph, const CapacityMap& capacity,
+                Node source, Node target)
+      : _graph(digraph), _capacity(&capacity), _source(source), _target(target),
+        _flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value()
+    {
+      LEMON_ASSERT(_source != _target,
+                   "Flow source and target are the same nodes.");
+    }
+
+    /// \brief Destructor.
+    ///
+    /// Destructor.
+    ~EdmondsKarp() {
+      destroyStructures();
+    }
+
+    /// \brief Sets the capacity map.
+    ///
+    /// Sets the capacity map.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& capacityMap(const CapacityMap& map) {
+      _capacity = ↦
+      return *this;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& flowMap(FlowMap& map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = ↦
+      return *this;
+    }
+
+    /// \brief Sets the source node.
+    ///
+    /// Sets the source node.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& source(const Node& node) {
+      _source = node;
+      return *this;
+    }
+
+    /// \brief Sets the target node.
+    ///
+    /// Sets the target node.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& target(const Node& node) {
+      _target = node;
+      return *this;
+    }
+
+    /// \brief Sets the tolerance used by algorithm.
+    ///
+    /// Sets the tolerance used by algorithm.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// Returns a const reference to the tolerance object used by
+    /// the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use \ref run().\n
+    /// If you need better control on the initial solution or the execution,
+    /// you have to call one of the \ref init() functions first, then
+    /// \ref start() or multiple times the \ref augment() function.
+
+    ///@{
+
+    /// \brief Initializes the algorithm.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to zero on each arc.
+    void init() {
+      createStructures();
+      for (ArcIt it(_graph); it != INVALID; ++it) {
+        _flow->set(it, 0);
+      }
+      _flow_value = 0;
+    }
+
+    /// \brief Initializes the algorithm using the given flow map.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to the given \c flowMap. The \c flowMap should
+    /// contain a feasible flow, i.e. at each node excluding the source
+    /// and the target, the incoming flow should be equal to the
+    /// outgoing flow.
+    template <typename FlowMap>
+    void init(const FlowMap& flowMap) {
+      createStructures();
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _flow->set(e, flowMap[e]);
+      }
+      _flow_value = 0;
+      for (OutArcIt jt(_graph, _source); jt != INVALID; ++jt) {
+        _flow_value += (*_flow)[jt];
+      }
+      for (InArcIt jt(_graph, _source); jt != INVALID; ++jt) {
+        _flow_value -= (*_flow)[jt];
+      }
+    }
+
+    /// \brief Initializes the algorithm using the given flow map.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to the given \c flowMap. The \c flowMap should
+    /// contain a feasible flow, i.e. at each node excluding the source
+    /// and the target, the incoming flow should be equal to the
+    /// outgoing flow.
+    /// \return \c false when the given \c flowMap does not contain a
+    /// feasible flow.
+    template <typename FlowMap>
+    bool checkedInit(const FlowMap& flowMap) {
+      createStructures();
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _flow->set(e, flowMap[e]);
+      }
+      for (NodeIt it(_graph); it != INVALID; ++it) {
+        if (it == _source || it == _target) continue;
+        Value outFlow = 0;
+        for (OutArcIt jt(_graph, it); jt != INVALID; ++jt) {
+          outFlow += (*_flow)[jt];
+        }
+        Value inFlow = 0;
+        for (InArcIt jt(_graph, it); jt != INVALID; ++jt) {
+          inFlow += (*_flow)[jt];
+        }
+        if (_tolerance.different(outFlow, inFlow)) {
+          return false;
+        }
+      }
+      for (ArcIt it(_graph); it != INVALID; ++it) {
+        if (_tolerance.less((*_flow)[it], 0)) return false;
+        if (_tolerance.less((*_capacity)[it], (*_flow)[it])) return false;
+      }
+      _flow_value = 0;
+      for (OutArcIt jt(_graph, _source); jt != INVALID; ++jt) {
+        _flow_value += (*_flow)[jt];
+      }
+      for (InArcIt jt(_graph, _source); jt != INVALID; ++jt) {
+        _flow_value -= (*_flow)[jt];
+      }
+      return true;
+    }
+
+    /// \brief Augments the solution along a shortest path.
+    ///
+    /// Augments the solution along a shortest path. This function searches a
+    /// shortest path between the source and the target
+    /// in the residual digraph by the Bfs algoritm.
+    /// Then it increases the flow on this path with the minimal residual
+    /// capacity on the path. If there is no such path, it gives back
+    /// false.
+    /// \return \c false when the augmenting did not success, i.e. the
+    /// current flow is a feasible and optimal solution.
+    bool augment() {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _pred->set(n, INVALID);
+      }
+
+      int first = 0, last = 1;
+
+      _queue[0] = _source;
+      _pred->set(_source, OutArcIt(_graph, _source));
+
+      while (first != last && (*_pred)[_target] == INVALID) {
+        Node n = _queue[first++];
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Value rem = (*_capacity)[e] - (*_flow)[e];
+          Node t = _graph.target(e);
+          if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
+            _pred->set(t, e);
+            _queue[last++] = t;
+          }
+        }
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Value rem = (*_flow)[e];
+          Node t = _graph.source(e);
+          if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
+            _pred->set(t, e);
+            _queue[last++] = t;
+          }
+        }
+      }
+
+      if ((*_pred)[_target] != INVALID) {
+        Node n = _target;
+        Arc e = (*_pred)[n];
+
+        Value prem = (*_capacity)[e] - (*_flow)[e];
+        n = _graph.source(e);
+        while (n != _source) {
+          e = (*_pred)[n];
+          if (_graph.target(e) == n) {
+            Value rem = (*_capacity)[e] - (*_flow)[e];
+            if (rem < prem) prem = rem;
+            n = _graph.source(e);
+          } else {
+            Value rem = (*_flow)[e];
+            if (rem < prem) prem = rem;
+            n = _graph.target(e);
+          }
+        }
+
+        n = _target;
+        e = (*_pred)[n];
+
+        _flow->set(e, (*_flow)[e] + prem);
+        n = _graph.source(e);
+        while (n != _source) {
+          e = (*_pred)[n];
+          if (_graph.target(e) == n) {
+            _flow->set(e, (*_flow)[e] + prem);
+            n = _graph.source(e);
+          } else {
+            _flow->set(e, (*_flow)[e] - prem);
+            n = _graph.target(e);
+          }
+        }
+
+        _flow_value += prem;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    /// \brief Executes the algorithm
+    ///
+    /// Executes the algorithm by performing augmenting phases until the
+    /// optimal solution is reached.
+    /// \pre One of the \ref init() functions must be called before
+    /// using this function.
+    void start() {
+      while (augment()) {}
+    }
+
+    /// \brief Runs the algorithm.
+    ///
+    /// Runs the Edmonds-Karp algorithm.
+    /// \note ek.run() is just a shortcut of the following code.
+    ///\code
+    /// ek.init();
+    /// ek.start();
+    ///\endcode
+    void run() {
+      init();
+      start();
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The result of the Edmonds-Karp algorithm can be obtained using these
+    /// functions.\n
+    /// Either \ref run() or \ref start() should be called before using them.
+
+    ///@{
+
+    /// \brief Returns the value of the maximum flow.
+    ///
+    /// Returns the value of the maximum flow found by the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flowValue() const {
+      return _flow_value;
+    }
+
+    /// \brief Returns the flow value on the given arc.
+    ///
+    /// Returns the flow value on the given arc.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flow(const Arc& arc) const {
+      return (*_flow)[arc];
+    }
+
+    /// \brief Returns a const reference to the flow map.
+    ///
+    /// Returns a const reference to the arc map storing the found flow.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const FlowMap& flowMap() const {
+      return *_flow;
+    }
+
+    /// \brief Returns \c true when the node is on the source side of the
+    /// minimum cut.
+    ///
+    /// Returns true when the node is on the source side of the found
+    /// minimum cut.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    bool minCut(const Node& node) const {
+      return ((*_pred)[node] != INVALID) || node == _source;
+    }
+
+    /// \brief Gives back a minimum value cut.
+    ///
+    /// Sets \c cutMap to the characteristic vector of a minimum value
+    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
+    /// node map with \c bool (or convertible) value type.
+    ///
+    /// \note This function calls \ref minCut() for each node, so it runs in
+    /// O(n) time.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    template <typename CutMap>
+    void minCutMap(CutMap& cutMap) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        cutMap.set(n, (*_pred)[n] != INVALID);
+      }
+      cutMap.set(_source, true);
+    }
+
+    /// @}
+
+  };
+
+}
+
+#endif
diff --git a/lemon/elevator.h b/lemon/elevator.h
new file mode 100644
index 0000000..e4adcd5
--- /dev/null
+++ b/lemon/elevator.h
@@ -0,0 +1,982 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_ELEVATOR_H
+#define LEMON_ELEVATOR_H
+
+///\ingroup auxdat
+///\file
+///\brief Elevator class
+///
+///Elevator class implements an efficient data structure
+///for labeling items in push-relabel type algorithms.
+///
+
+#include <lemon/core.h>
+#include <lemon/bits/traits.h>
+
+namespace lemon {
+
+  ///Class for handling "labels" in push-relabel type algorithms.
+
+  ///A class for handling "labels" in push-relabel type algorithms.
+  ///
+  ///\ingroup auxdat
+  ///Using this class you can assign "labels" (nonnegative integer numbers)
+  ///to the edges or nodes of a graph, manipulate and query them through
+  ///operations typically arising in "push-relabel" type algorithms.
+  ///
+  ///Each item is either \em active or not, and you can also choose a
+  ///highest level active item.
+  ///
+  ///\sa LinkedElevator
+  ///
+  ///\param GR Type of the underlying graph.
+  ///\param Item Type of the items the data is assigned to (\c GR::Node,
+  ///\c GR::Arc or \c GR::Edge).
+  template<class GR, class Item>
+  class Elevator
+  {
+  public:
+
+    typedef Item Key;
+    typedef int Value;
+
+  private:
+
+    typedef Item *Vit;
+    typedef typename ItemSetTraits<GR,Item>::template Map<Vit>::Type VitMap;
+    typedef typename ItemSetTraits<GR,Item>::template Map<int>::Type IntMap;
+
+    const GR &_g;
+    int _max_level;
+    int _item_num;
+    VitMap _where;
+    IntMap _level;
+    std::vector<Item> _items;
+    std::vector<Vit> _first;
+    std::vector<Vit> _last_active;
+
+    int _highest_active;
+
+    void copy(Item i, Vit p)
+    {
+      _where[*p=i] = p;
+    }
+    void copy(Vit s, Vit p)
+    {
+      if(s!=p)
+        {
+          Item i=*s;
+          *p=i;
+          _where[i] = p;
+        }
+    }
+    void swap(Vit i, Vit j)
+    {
+      Item ti=*i;
+      Vit ct = _where[ti];
+      _where[ti] = _where[*i=*j];
+      _where[*j] = ct;
+      *j=ti;
+    }
+
+  public:
+
+    ///Constructor with given maximum level.
+
+    ///Constructor with given maximum level.
+    ///
+    ///\param graph The underlying graph.
+    ///\param max_level The maximum allowed level.
+    ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
+    Elevator(const GR &graph,int max_level) :
+      _g(graph),
+      _max_level(max_level),
+      _item_num(_max_level),
+      _where(graph),
+      _level(graph,0),
+      _items(_max_level),
+      _first(_max_level+2),
+      _last_active(_max_level+2),
+      _highest_active(-1) {}
+    ///Constructor.
+
+    ///Constructor.
+    ///
+    ///\param graph The underlying graph.
+    ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
+    ///where \c max_level is equal to the number of labeled items in the graph.
+    Elevator(const GR &graph) :
+      _g(graph),
+      _max_level(countItems<GR, Item>(graph)),
+      _item_num(_max_level),
+      _where(graph),
+      _level(graph,0),
+      _items(_max_level),
+      _first(_max_level+2),
+      _last_active(_max_level+2),
+      _highest_active(-1)
+    {
+    }
+
+    ///Activate item \c i.
+
+    ///Activate item \c i.
+    ///\pre Item \c i shouldn't be active before.
+    void activate(Item i)
+    {
+      const int l=_level[i];
+      swap(_where[i],++_last_active[l]);
+      if(l>_highest_active) _highest_active=l;
+    }
+
+    ///Deactivate item \c i.
+
+    ///Deactivate item \c i.
+    ///\pre Item \c i must be active before.
+    void deactivate(Item i)
+    {
+      swap(_where[i],_last_active[_level[i]]--);
+      while(_highest_active>=0 &&
+            _last_active[_highest_active]<_first[_highest_active])
+        _highest_active--;
+    }
+
+    ///Query whether item \c i is active
+    bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
+
+    ///Return the level of item \c i.
+    int operator[](Item i) const { return _level[i]; }
+
+    ///Return the number of items on level \c l.
+    int onLevel(int l) const
+    {
+      return _first[l+1]-_first[l];
+    }
+    ///Return true if level \c l is empty.
+    bool emptyLevel(int l) const
+    {
+      return _first[l+1]-_first[l]==0;
+    }
+    ///Return the number of items above level \c l.
+    int aboveLevel(int l) const
+    {
+      return _first[_max_level+1]-_first[l+1];
+    }
+    ///Return the number of active items on level \c l.
+    int activesOnLevel(int l) const
+    {
+      return _last_active[l]-_first[l]+1;
+    }
+    ///Return true if there is no active item on level \c l.
+    bool activeFree(int l) const
+    {
+      return _last_active[l]<_first[l];
+    }
+    ///Return the maximum allowed level.
+    int maxLevel() const
+    {
+      return _max_level;
+    }
+
+    ///\name Highest Active Item
+    ///Functions for working with the highest level
+    ///active item.
+
+    ///@{
+
+    ///Return a highest level active item.
+
+    ///Return a highest level active item or INVALID if there is no active
+    ///item.
+    Item highestActive() const
+    {
+      return _highest_active>=0?*_last_active[_highest_active]:INVALID;
+    }
+
+    ///Return the highest active level.
+
+    ///Return the level of the highest active item or -1 if there is no active
+    ///item.
+    int highestActiveLevel() const
+    {
+      return _highest_active;
+    }
+
+    ///Lift the highest active item by one.
+
+    ///Lift the item returned by highestActive() by one.
+    ///
+    void liftHighestActive()
+    {
+      Item it = *_last_active[_highest_active];
+      ++_level[it];
+      swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
+      --_first[++_highest_active];
+    }
+
+    ///Lift the highest active item to the given level.
+
+    ///Lift the item returned by highestActive() to level \c new_level.
+    ///
+    ///\warning \c new_level must be strictly higher
+    ///than the current level.
+    ///
+    void liftHighestActive(int new_level)
+    {
+      const Item li = *_last_active[_highest_active];
+
+      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
+      for(int l=_highest_active+1;l<new_level;l++)
+        {
+          copy(--_first[l+1],_first[l]);
+          --_last_active[l];
+        }
+      copy(li,_first[new_level]);
+      _level[li] = new_level;
+      _highest_active=new_level;
+    }
+
+    ///Lift the highest active item to the top level.
+
+    ///Lift the item returned by highestActive() to the top level and
+    ///deactivate it.
+    void liftHighestActiveToTop()
+    {
+      const Item li = *_last_active[_highest_active];
+
+      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
+      for(int l=_highest_active+1;l<_max_level;l++)
+        {
+          copy(--_first[l+1],_first[l]);
+          --_last_active[l];
+        }
+      copy(li,_first[_max_level]);
+      --_last_active[_max_level];
+      _level[li] = _max_level;
+
+      while(_highest_active>=0 &&
+            _last_active[_highest_active]<_first[_highest_active])
+        _highest_active--;
+    }
+
+    ///@}
+
+    ///\name Active Item on Certain Level
+    ///Functions for working with the active items.
+
+    ///@{
+
+    ///Return an active item on level \c l.
+
+    ///Return an active item on level \c l or \ref INVALID if there is no such
+    ///an item. (\c l must be from the range [0...\c max_level].
+    Item activeOn(int l) const
+    {
+      return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
+    }
+
+    ///Lift the active item returned by \c activeOn(level) by one.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
+    ///by one.
+    Item liftActiveOn(int level)
+    {
+      Item it =*_last_active[level];
+      ++_level[it];
+      swap(_last_active[level]--, --_first[level+1]);
+      if (level+1>_highest_active) ++_highest_active;
+    }
+
+    ///Lift the active item returned by \c activeOn(level) to the given level.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
+    ///to the given level.
+    void liftActiveOn(int level, int new_level)
+    {
+      const Item ai = *_last_active[level];
+
+      copy(--_first[level+1], _last_active[level]--);
+      for(int l=level+1;l<new_level;l++)
+        {
+          copy(_last_active[l],_first[l]);
+          copy(--_first[l+1], _last_active[l]--);
+        }
+      copy(ai,_first[new_level]);
+      _level[ai] = new_level;
+      if (new_level>_highest_active) _highest_active=new_level;
+    }
+
+    ///Lift the active item returned by \c activeOn(level) to the top level.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
+    ///to the top level and deactivate it.
+    void liftActiveToTop(int level)
+    {
+      const Item ai = *_last_active[level];
+
+      copy(--_first[level+1],_last_active[level]--);
+      for(int l=level+1;l<_max_level;l++)
+        {
+          copy(_last_active[l],_first[l]);
+          copy(--_first[l+1], _last_active[l]--);
+        }
+      copy(ai,_first[_max_level]);
+      --_last_active[_max_level];
+      _level[ai] = _max_level;
+
+      if (_highest_active==level) {
+        while(_highest_active>=0 &&
+              _last_active[_highest_active]<_first[_highest_active])
+          _highest_active--;
+      }
+    }
+
+    ///@}
+
+    ///Lift an active item to a higher level.
+
+    ///Lift an active item to a higher level.
+    ///\param i The item to be lifted. It must be active.
+    ///\param new_level The new level of \c i. It must be strictly higher
+    ///than the current level.
+    ///
+    void lift(Item i, int new_level)
+    {
+      const int lo = _level[i];
+      const Vit w = _where[i];
+
+      copy(_last_active[lo],w);
+      copy(--_first[lo+1],_last_active[lo]--);
+      for(int l=lo+1;l<new_level;l++)
+        {
+          copy(_last_active[l],_first[l]);
+          copy(--_first[l+1],_last_active[l]--);
+        }
+      copy(i,_first[new_level]);
+      _level[i] = new_level;
+      if(new_level>_highest_active) _highest_active=new_level;
+    }
+
+    ///Move an inactive item to the top but one level (in a dirty way).
+
+    ///This function moves an inactive item from the top level to the top
+    ///but one level (in a dirty way).
+    ///\warning It makes the underlying datastructure corrupt, so use it
+    ///only if you really know what it is for.
+    ///\pre The item is on the top level.
+    void dirtyTopButOne(Item i) {
+      _level[i] = _max_level - 1;
+    }
+
+    ///Lift all items on and above the given level to the top level.
+
+    ///This function lifts all items on and above level \c l to the top
+    ///level and deactivates them.
+    void liftToTop(int l)
+    {
+      const Vit f=_first[l];
+      const Vit tl=_first[_max_level];
+      for(Vit i=f;i!=tl;++i)
+        _level[*i] = _max_level;
+      for(int i=l;i<=_max_level;i++)
+        {
+          _first[i]=f;
+          _last_active[i]=f-1;
+        }
+      for(_highest_active=l-1;
+          _highest_active>=0 &&
+            _last_active[_highest_active]<_first[_highest_active];
+          _highest_active--) ;
+    }
+
+  private:
+    int _init_lev;
+    Vit _init_num;
+
+  public:
+
+    ///\name Initialization
+    ///Using these functions you can initialize the levels of the items.
+    ///\n
+    ///The initialization must be started with calling \c initStart().
+    ///Then the items should be listed level by level starting with the
+    ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
+    ///Finally \c initFinish() must be called.
+    ///The items not listed are put on the highest level.
+    ///@{
+
+    ///Start the initialization process.
+    void initStart()
+    {
+      _init_lev=0;
+      _init_num=&_items[0];
+      _first[0]=&_items[0];
+      _last_active[0]=&_items[0]-1;
+      Vit n=&_items[0];
+      for(typename ItemSetTraits<GR,Item>::ItemIt i(_g);i!=INVALID;++i)
+        {
+          *n=i;
+          _where[i] = n;
+          _level[i] = _max_level;
+          ++n;
+        }
+    }
+
+    ///Add an item to the current level.
+    void initAddItem(Item i)
+    {
+      swap(_where[i],_init_num);
+      _level[i] = _init_lev;
+      ++_init_num;
+    }
+
+    ///Start a new level.
+
+    ///Start a new level.
+    ///It shouldn't be used before the items on level 0 are listed.
+    void initNewLevel()
+    {
+      _init_lev++;
+      _first[_init_lev]=_init_num;
+      _last_active[_init_lev]=_init_num-1;
+    }
+
+    ///Finalize the initialization process.
+    void initFinish()
+    {
+      for(_init_lev++;_init_lev<=_max_level;_init_lev++)
+        {
+          _first[_init_lev]=_init_num;
+          _last_active[_init_lev]=_init_num-1;
+        }
+      _first[_max_level+1]=&_items[0]+_item_num;
+      _last_active[_max_level+1]=&_items[0]+_item_num-1;
+      _highest_active = -1;
+    }
+
+    ///@}
+
+  };
+
+  ///Class for handling "labels" in push-relabel type algorithms.
+
+  ///A class for handling "labels" in push-relabel type algorithms.
+  ///
+  ///\ingroup auxdat
+  ///Using this class you can assign "labels" (nonnegative integer numbers)
+  ///to the edges or nodes of a graph, manipulate and query them through
+  ///operations typically arising in "push-relabel" type algorithms.
+  ///
+  ///Each item is either \em active or not, and you can also choose a
+  ///highest level active item.
+  ///
+  ///\sa Elevator
+  ///
+  ///\param GR Type of the underlying graph.
+  ///\param Item Type of the items the data is assigned to (\c GR::Node,
+  ///\c GR::Arc or \c GR::Edge).
+  template <class GR, class Item>
+  class LinkedElevator {
+  public:
+
+    typedef Item Key;
+    typedef int Value;
+
+  private:
+
+    typedef typename ItemSetTraits<GR,Item>::
+    template Map<Item>::Type ItemMap;
+    typedef typename ItemSetTraits<GR,Item>::
+    template Map<int>::Type IntMap;
+    typedef typename ItemSetTraits<GR,Item>::
+    template Map<bool>::Type BoolMap;
+
+    const GR &_graph;
+    int _max_level;
+    int _item_num;
+    std::vector<Item> _first, _last;
+    ItemMap _prev, _next;
+    int _highest_active;
+    IntMap _level;
+    BoolMap _active;
+
+  public:
+    ///Constructor with given maximum level.
+
+    ///Constructor with given maximum level.
+    ///
+    ///\param graph The underlying graph.
+    ///\param max_level The maximum allowed level.
+    ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
+    LinkedElevator(const GR& graph, int max_level)
+      : _graph(graph), _max_level(max_level), _item_num(_max_level),
+        _first(_max_level + 1), _last(_max_level + 1),
+        _prev(graph), _next(graph),
+        _highest_active(-1), _level(graph), _active(graph) {}
+
+    ///Constructor.
+
+    ///Constructor.
+    ///
+    ///\param graph The underlying graph.
+    ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
+    ///where \c max_level is equal to the number of labeled items in the graph.
+    LinkedElevator(const GR& graph)
+      : _graph(graph), _max_level(countItems<GR, Item>(graph)),
+        _item_num(_max_level),
+        _first(_max_level + 1), _last(_max_level + 1),
+        _prev(graph, INVALID), _next(graph, INVALID),
+        _highest_active(-1), _level(graph), _active(graph) {}
+
+
+    ///Activate item \c i.
+
+    ///Activate item \c i.
+    ///\pre Item \c i shouldn't be active before.
+    void activate(Item i) {
+      _active[i] = true;
+
+      int level = _level[i];
+      if (level > _highest_active) {
+        _highest_active = level;
+      }
+
+      if (_prev[i] == INVALID || _active[_prev[i]]) return;
+      //unlace
+      _next[_prev[i]] = _next[i];
+      if (_next[i] != INVALID) {
+        _prev[_next[i]] = _prev[i];
+      } else {
+        _last[level] = _prev[i];
+      }
+      //lace
+      _next[i] = _first[level];
+      _prev[_first[level]] = i;
+      _prev[i] = INVALID;
+      _first[level] = i;
+
+    }
+
+    ///Deactivate item \c i.
+
+    ///Deactivate item \c i.
+    ///\pre Item \c i must be active before.
+    void deactivate(Item i) {
+      _active[i] = false;
+      int level = _level[i];
+
+      if (_next[i] == INVALID || !_active[_next[i]])
+        goto find_highest_level;
+
+      //unlace
+      _prev[_next[i]] = _prev[i];
+      if (_prev[i] != INVALID) {
+        _next[_prev[i]] = _next[i];
+      } else {
+        _first[_level[i]] = _next[i];
+      }
+      //lace
+      _prev[i] = _last[level];
+      _next[_last[level]] = i;
+      _next[i] = INVALID;
+      _last[level] = i;
+
+    find_highest_level:
+      if (level == _highest_active) {
+        while (_highest_active >= 0 && activeFree(_highest_active))
+          --_highest_active;
+      }
+    }
+
+    ///Query whether item \c i is active
+    bool active(Item i) const { return _active[i]; }
+
+    ///Return the level of item \c i.
+    int operator[](Item i) const { return _level[i]; }
+
+    ///Return the number of items on level \c l.
+    int onLevel(int l) const {
+      int num = 0;
+      Item n = _first[l];
+      while (n != INVALID) {
+        ++num;
+        n = _next[n];
+      }
+      return num;
+    }
+
+    ///Return true if the level is empty.
+    bool emptyLevel(int l) const {
+      return _first[l] == INVALID;
+    }
+
+    ///Return the number of items above level \c l.
+    int aboveLevel(int l) const {
+      int num = 0;
+      for (int level = l + 1; level < _max_level; ++level)
+        num += onLevel(level);
+      return num;
+    }
+
+    ///Return the number of active items on level \c l.
+    int activesOnLevel(int l) const {
+      int num = 0;
+      Item n = _first[l];
+      while (n != INVALID && _active[n]) {
+        ++num;
+        n = _next[n];
+      }
+      return num;
+    }
+
+    ///Return true if there is no active item on level \c l.
+    bool activeFree(int l) const {
+      return _first[l] == INVALID || !_active[_first[l]];
+    }
+
+    ///Return the maximum allowed level.
+    int maxLevel() const {
+      return _max_level;
+    }
+
+    ///\name Highest Active Item
+    ///Functions for working with the highest level
+    ///active item.
+
+    ///@{
+
+    ///Return a highest level active item.
+
+    ///Return a highest level active item or INVALID if there is no active
+    ///item.
+    Item highestActive() const {
+      return _highest_active >= 0 ? _first[_highest_active] : INVALID;
+    }
+
+    ///Return the highest active level.
+
+    ///Return the level of the highest active item or -1 if there is no active
+    ///item.
+    int highestActiveLevel() const {
+      return _highest_active;
+    }
+
+    ///Lift the highest active item by one.
+
+    ///Lift the item returned by highestActive() by one.
+    ///
+    void liftHighestActive() {
+      Item i = _first[_highest_active];
+      if (_next[i] != INVALID) {
+        _prev[_next[i]] = INVALID;
+        _first[_highest_active] = _next[i];
+      } else {
+        _first[_highest_active] = INVALID;
+        _last[_highest_active] = INVALID;
+      }
+      _level[i] = ++_highest_active;
+      if (_first[_highest_active] == INVALID) {
+        _first[_highest_active] = i;
+        _last[_highest_active] = i;
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[_highest_active]] = i;
+        _next[i] = _first[_highest_active];
+        _first[_highest_active] = i;
+      }
+    }
+
+    ///Lift the highest active item to the given level.
+
+    ///Lift the item returned by highestActive() to level \c new_level.
+    ///
+    ///\warning \c new_level must be strictly higher
+    ///than the current level.
+    ///
+    void liftHighestActive(int new_level) {
+      Item i = _first[_highest_active];
+      if (_next[i] != INVALID) {
+        _prev[_next[i]] = INVALID;
+        _first[_highest_active] = _next[i];
+      } else {
+        _first[_highest_active] = INVALID;
+        _last[_highest_active] = INVALID;
+      }
+      _level[i] = _highest_active = new_level;
+      if (_first[_highest_active] == INVALID) {
+        _first[_highest_active] = _last[_highest_active] = i;
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[_highest_active]] = i;
+        _next[i] = _first[_highest_active];
+        _first[_highest_active] = i;
+      }
+    }
+
+    ///Lift the highest active item to the top level.
+
+    ///Lift the item returned by highestActive() to the top level and
+    ///deactivate it.
+    void liftHighestActiveToTop() {
+      Item i = _first[_highest_active];
+      _level[i] = _max_level;
+      if (_next[i] != INVALID) {
+        _prev[_next[i]] = INVALID;
+        _first[_highest_active] = _next[i];
+      } else {
+        _first[_highest_active] = INVALID;
+        _last[_highest_active] = INVALID;
+      }
+      while (_highest_active >= 0 && activeFree(_highest_active))
+        --_highest_active;
+    }
+
+    ///@}
+
+    ///\name Active Item on Certain Level
+    ///Functions for working with the active items.
+
+    ///@{
+
+    ///Return an active item on level \c l.
+
+    ///Return an active item on level \c l or \ref INVALID if there is no such
+    ///an item. (\c l must be from the range [0...\c max_level].
+    Item activeOn(int l) const
+    {
+      return _active[_first[l]] ? _first[l] : INVALID;
+    }
+
+    ///Lift the active item returned by \c activeOn(l) by one.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
+    ///by one.
+    Item liftActiveOn(int l)
+    {
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+        _prev[_next[i]] = INVALID;
+        _first[l] = _next[i];
+      } else {
+        _first[l] = INVALID;
+        _last[l] = INVALID;
+      }
+      _level[i] = ++l;
+      if (_first[l] == INVALID) {
+        _first[l] = _last[l] = i;
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[l]] = i;
+        _next[i] = _first[l];
+        _first[l] = i;
+      }
+      if (_highest_active < l) {
+        _highest_active = l;
+      }
+    }
+
+    ///Lift the active item returned by \c activeOn(l) to the given level.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
+    ///to the given level.
+    void liftActiveOn(int l, int new_level)
+    {
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+        _prev[_next[i]] = INVALID;
+        _first[l] = _next[i];
+      } else {
+        _first[l] = INVALID;
+        _last[l] = INVALID;
+      }
+      _level[i] = l = new_level;
+      if (_first[l] == INVALID) {
+        _first[l] = _last[l] = i;
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[l]] = i;
+        _next[i] = _first[l];
+        _first[l] = i;
+      }
+      if (_highest_active < l) {
+        _highest_active = l;
+      }
+    }
+
+    ///Lift the active item returned by \c activeOn(l) to the top level.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
+    ///to the top level and deactivate it.
+    void liftActiveToTop(int l)
+    {
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+        _prev[_next[i]] = INVALID;
+        _first[l] = _next[i];
+      } else {
+        _first[l] = INVALID;
+        _last[l] = INVALID;
+      }
+      _level[i] = _max_level;
+      if (l == _highest_active) {
+        while (_highest_active >= 0 && activeFree(_highest_active))
+          --_highest_active;
+      }
+    }
+
+    ///@}
+
+    /// \brief Lift an active item to a higher level.
+    ///
+    /// Lift an active item to a higher level.
+    /// \param i The item to be lifted. It must be active.
+    /// \param new_level The new level of \c i. It must be strictly higher
+    /// than the current level.
+    ///
+    void lift(Item i, int new_level) {
+      if (_next[i] != INVALID) {
+        _prev[_next[i]] = _prev[i];
+      } else {
+        _last[new_level] = _prev[i];
+      }
+      if (_prev[i] != INVALID) {
+        _next[_prev[i]] = _next[i];
+      } else {
+        _first[new_level] = _next[i];
+      }
+      _level[i] = new_level;
+      if (_first[new_level] == INVALID) {
+        _first[new_level] = _last[new_level] = i;
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[new_level]] = i;
+        _next[i] = _first[new_level];
+        _first[new_level] = i;
+      }
+      if (_highest_active < new_level) {
+        _highest_active = new_level;
+      }
+    }
+
+    ///Move an inactive item to the top but one level (in a dirty way).
+
+    ///This function moves an inactive item from the top level to the top
+    ///but one level (in a dirty way).
+    ///\warning It makes the underlying datastructure corrupt, so use it
+    ///only if you really know what it is for.
+    ///\pre The item is on the top level.
+    void dirtyTopButOne(Item i) {
+      _level[i] = _max_level - 1;
+    }
+
+    ///Lift all items on and above the given level to the top level.
+
+    ///This function lifts all items on and above level \c l to the top
+    ///level and deactivates them.
+    void liftToTop(int l)  {
+      for (int i = l + 1; _first[i] != INVALID; ++i) {
+        Item n = _first[i];
+        while (n != INVALID) {
+          _level[n] = _max_level;
+          n = _next[n];
+        }
+        _first[i] = INVALID;
+        _last[i] = INVALID;
+      }
+      if (_highest_active > l - 1) {
+        _highest_active = l - 1;
+        while (_highest_active >= 0 && activeFree(_highest_active))
+          --_highest_active;
+      }
+    }
+
+  private:
+
+    int _init_level;
+
+  public:
+
+    ///\name Initialization
+    ///Using these functions you can initialize the levels of the items.
+    ///\n
+    ///The initialization must be started with calling \c initStart().
+    ///Then the items should be listed level by level starting with the
+    ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
+    ///Finally \c initFinish() must be called.
+    ///The items not listed are put on the highest level.
+    ///@{
+
+    ///Start the initialization process.
+    void initStart() {
+
+      for (int i = 0; i <= _max_level; ++i) {
+        _first[i] = _last[i] = INVALID;
+      }
+      _init_level = 0;
+      for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
+          i != INVALID; ++i) {
+        _level[i] = _max_level;
+        _active[i] = false;
+      }
+    }
+
+    ///Add an item to the current level.
+    void initAddItem(Item i) {
+      _level[i] = _init_level;
+      if (_last[_init_level] == INVALID) {
+        _first[_init_level] = i;
+        _last[_init_level] = i;
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[i] = _last[_init_level];
+        _next[i] = INVALID;
+        _next[_last[_init_level]] = i;
+        _last[_init_level] = i;
+      }
+    }
+
+    ///Start a new level.
+
+    ///Start a new level.
+    ///It shouldn't be used before the items on level 0 are listed.
+    void initNewLevel() {
+      ++_init_level;
+    }
+
+    ///Finalize the initialization process.
+    void initFinish() {
+      _highest_active = -1;
+    }
+
+    ///@}
+
+  };
+
+
+} //END OF NAMESPACE LEMON
+
+#endif
+
diff --git a/lemon/error.h b/lemon/error.h
new file mode 100644
index 0000000..f937704
--- /dev/null
+++ b/lemon/error.h
@@ -0,0 +1,276 @@
+/* -*- 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_ERROR_H
+#define LEMON_ERROR_H
+
+/// \ingroup exceptions
+/// \file
+/// \brief Basic exception classes and error handling.
+
+#include <exception>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <cstdlib>
+#include <memory>
+
+namespace lemon {
+
+  /// \addtogroup exceptions
+  /// @{
+
+  /// \brief Generic exception class.
+  ///
+  /// Base class for exceptions used in LEMON.
+  ///
+  class Exception : public std::exception {
+  public:
+    ///Constructor
+    Exception() throw() {}
+    ///Virtual destructor
+    virtual ~Exception() throw() {}
+    ///A short description of the exception
+    virtual const char* what() const throw() {
+      return "lemon::Exception";
+    }
+  };
+
+  /// \brief Input-Output error
+  ///
+  /// This exception is thrown when a file operation cannot be
+  /// succeeded.
+  class IoError : public Exception {
+  protected:
+    std::string _message;
+    std::string _file;
+
+    mutable std::string _what;
+  public:
+
+    /// Copy constructor
+    IoError(const IoError &error) throw() : Exception() {
+      message(error._message);
+      file(error._file);
+    }
+
+    /// Constructor
+    explicit IoError(const char *message) throw() {
+      IoError::message(message);
+    }
+
+    /// Constructor
+    explicit IoError(const std::string &message) throw() {
+      IoError::message(message);
+    }
+
+    /// Constructor
+    explicit IoError(const char *message,
+                     const std::string &file) throw() {
+      IoError::message(message);
+      IoError::file(file);
+    }
+
+    /// Constructor
+    explicit IoError(const std::string &message,
+                     const std::string &file) throw() {
+      IoError::message(message);
+      IoError::file(file);
+    }
+
+    /// Virtual destructor
+    virtual ~IoError() throw() {}
+
+    /// Set the error message
+    void message(const char *message) throw() {
+      try {
+        _message = message;
+      } catch (...) {}
+    }
+
+    /// Set the error message
+    void message(const std::string& message) throw() {
+      try {
+        _message = message;
+      } catch (...) {}
+    }
+
+    /// Set the file name
+    void file(const std::string &file) throw() {
+      try {
+        _file = file;
+      } catch (...) {}
+    }
+
+    /// Returns the error message
+    const std::string& message() const throw() {
+      return _message;
+    }
+
+    /// \brief Returns the filename
+    ///
+    /// Returns the filename or an empty string if it was not specified.
+    const std::string& file() const throw() {
+      return _file;
+    }
+
+    /// \brief Returns a short error message
+    ///
+    /// Returns a short error message which contains the message and the
+    /// file name.
+    virtual const char* what() const throw() {
+      try {
+        _what.clear();
+        std::ostringstream oss;
+        oss << "lemon:IoError" << ": ";
+        oss << _message;
+        if (!_file.empty()) {
+          oss << " ('" << _file << "')";
+        }
+        _what = oss.str();
+      }
+      catch (...) {}
+      if (!_what.empty()) return _what.c_str();
+      else return "lemon:IoError";
+    }
+
+  };
+
+  /// \brief Format error
+  ///
+  /// This exception is thrown when an input file has wrong
+  /// format or a data representation is not legal.
+  class FormatError : public Exception {
+  protected:
+    std::string _message;
+    std::string _file;
+    int _line;
+
+    mutable std::string _what;
+  public:
+
+    /// Copy constructor
+    FormatError(const FormatError &error) throw() : Exception() {
+      message(error._message);
+      file(error._file);
+      line(error._line);
+    }
+
+    /// Constructor
+    explicit FormatError(const char *message) throw() {
+      FormatError::message(message);
+      _line = 0;
+    }
+
+    /// Constructor
+    explicit FormatError(const std::string &message) throw() {
+      FormatError::message(message);
+      _line = 0;
+    }
+
+    /// Constructor
+    explicit FormatError(const char *message,
+                         const std::string &file, int line = 0) throw() {
+      FormatError::message(message);
+      FormatError::file(file);
+      FormatError::line(line);
+    }
+
+    /// Constructor
+    explicit FormatError(const std::string &message,
+                         const std::string &file, int line = 0) throw() {
+      FormatError::message(message);
+      FormatError::file(file);
+      FormatError::line(line);
+    }
+
+    /// Virtual destructor
+    virtual ~FormatError() throw() {}
+
+    /// Set the line number
+    void line(int line) throw() { _line = line; }
+
+    /// Set the error message
+    void message(const char *message) throw() {
+      try {
+        _message = message;
+      } catch (...) {}
+    }
+
+    /// Set the error message
+    void message(const std::string& message) throw() {
+      try {
+        _message = message;
+      } catch (...) {}
+    }
+
+    /// Set the file name
+    void file(const std::string &file) throw() {
+      try {
+        _file = file;
+      } catch (...) {}
+    }
+
+    /// \brief Returns the line number
+    ///
+    /// Returns the line number or zero if it was not specified.
+    int line() const throw() { return _line; }
+
+    /// Returns the error message
+    const std::string& message() const throw() {
+      return _message;
+    }
+
+    /// \brief Returns the filename
+    ///
+    /// Returns the filename or an empty string if it was not specified.
+    const std::string& file() const throw() {
+      return _file;
+    }
+
+    /// \brief Returns a short error message
+    ///
+    /// Returns a short error message which contains the message, the
+    /// file name and the line number.
+    virtual const char* what() const throw() {
+      try {
+        _what.clear();
+        std::ostringstream oss;
+        oss << "lemon:FormatError" << ": ";
+        oss << _message;
+        if (!_file.empty() || _line != 0) {
+          oss << " (";
+          if (!_file.empty()) oss << "in file '" << _file << "'";
+          if (!_file.empty() && _line != 0) oss << " ";
+          if (_line != 0) oss << "at line " << _line;
+          oss << ")";
+        }
+        _what = oss.str();
+      }
+      catch (...) {}
+      if (!_what.empty()) return _what.c_str();
+      else return "lemon:FormatError";
+    }
+
+  };
+
+  /// @}
+
+}
+
+#endif // LEMON_ERROR_H
diff --git a/lemon/euler.h b/lemon/euler.h
new file mode 100644
index 0000000..3a3cbd0
--- /dev/null
+++ b/lemon/euler.h
@@ -0,0 +1,287 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_EULER_H
+#define LEMON_EULER_H
+
+#include<lemon/core.h>
+#include<lemon/adaptors.h>
+#include<lemon/connectivity.h>
+#include <list>
+
+/// \ingroup graph_properties
+/// \file
+/// \brief Euler tour iterators and a function for checking the \e Eulerian
+/// property.
+///
+///This file provides Euler tour iterators and a function to check
+///if a (di)graph is \e Eulerian.
+
+namespace lemon {
+
+  ///Euler tour iterator for digraphs.
+
+  /// \ingroup graph_properties
+  ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
+  ///graph (if there exists) and it converts to the \c Arc type of the digraph.
+  ///
+  ///For example, if the given digraph has an Euler tour (i.e it has only one
+  ///non-trivial component and the in-degree is equal to the out-degree
+  ///for all nodes), then the following code will put the arcs of \c g
+  ///to the vector \c et according to an Euler tour of \c g.
+  ///\code
+  ///  std::vector<ListDigraph::Arc> et;
+  ///  for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
+  ///    et.push_back(e);
+  ///\endcode
+  ///If \c g has no Euler tour, then the resulted walk will not be closed
+  ///or not contain all arcs.
+  ///\sa EulerIt
+  template<typename GR>
+  class DiEulerIt
+  {
+    typedef typename GR::Node Node;
+    typedef typename GR::NodeIt NodeIt;
+    typedef typename GR::Arc Arc;
+    typedef typename GR::ArcIt ArcIt;
+    typedef typename GR::OutArcIt OutArcIt;
+    typedef typename GR::InArcIt InArcIt;
+
+    const GR &g;
+    typename GR::template NodeMap<OutArcIt> narc;
+    std::list<Arc> euler;
+
+  public:
+
+    ///Constructor
+
+    ///Constructor.
+    ///\param gr A digraph.
+    ///\param start The starting point of the tour. If it is not given,
+    ///the tour will start from the first node that has an outgoing arc.
+    DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
+      : g(gr), narc(g)
+    {
+      if (start==INVALID) {
+        NodeIt n(g);
+        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
+        start=n;
+      }
+      if (start!=INVALID) {
+        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
+        while (narc[start]!=INVALID) {
+          euler.push_back(narc[start]);
+          Node next=g.target(narc[start]);
+          ++narc[start];
+          start=next;
+        }
+      }
+    }
+
+    ///Arc conversion
+    operator Arc() { return euler.empty()?INVALID:euler.front(); }
+    ///Compare with \c INVALID
+    bool operator==(Invalid) { return euler.empty(); }
+    ///Compare with \c INVALID
+    bool operator!=(Invalid) { return !euler.empty(); }
+
+    ///Next arc of the tour
+
+    ///Next arc of the tour
+    ///
+    DiEulerIt &operator++() {
+      Node s=g.target(euler.front());
+      euler.pop_front();
+      typename std::list<Arc>::iterator next=euler.begin();
+      while(narc[s]!=INVALID) {
+        euler.insert(next,narc[s]);
+        Node n=g.target(narc[s]);
+        ++narc[s];
+        s=n;
+      }
+      return *this;
+    }
+    ///Postfix incrementation
+
+    /// Postfix incrementation.
+    ///
+    ///\warning This incrementation
+    ///returns an \c Arc, not a \ref DiEulerIt, as one may
+    ///expect.
+    Arc operator++(int)
+    {
+      Arc e=*this;
+      ++(*this);
+      return e;
+    }
+  };
+
+  ///Euler tour iterator for graphs.
+
+  /// \ingroup graph_properties
+  ///This iterator provides an Euler tour (Eulerian circuit) of an
+  ///\e undirected graph (if there exists) and it converts to the \c Arc
+  ///and \c Edge types of the graph.
+  ///
+  ///For example, if the given graph has an Euler tour (i.e it has only one
+  ///non-trivial component and the degree of each node is even),
+  ///the following code will print the arc IDs according to an
+  ///Euler tour of \c g.
+  ///\code
+  ///  for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
+  ///    std::cout << g.id(Edge(e)) << std::eol;
+  ///  }
+  ///\endcode
+  ///Although this iterator is for undirected graphs, it still returns
+  ///arcs in order to indicate the direction of the tour.
+  ///(But arcs convert to edges, of course.)
+  ///
+  ///If \c g has no Euler tour, then the resulted walk will not be closed
+  ///or not contain all edges.
+  template<typename GR>
+  class EulerIt
+  {
+    typedef typename GR::Node Node;
+    typedef typename GR::NodeIt NodeIt;
+    typedef typename GR::Arc Arc;
+    typedef typename GR::Edge Edge;
+    typedef typename GR::ArcIt ArcIt;
+    typedef typename GR::OutArcIt OutArcIt;
+    typedef typename GR::InArcIt InArcIt;
+
+    const GR &g;
+    typename GR::template NodeMap<OutArcIt> narc;
+    typename GR::template EdgeMap<bool> visited;
+    std::list<Arc> euler;
+
+  public:
+
+    ///Constructor
+
+    ///Constructor.
+    ///\param gr A graph.
+    ///\param start The starting point of the tour. If it is not given,
+    ///the tour will start from the first node that has an incident edge.
+    EulerIt(const GR &gr, typename GR::Node start = INVALID)
+      : g(gr), narc(g), visited(g, false)
+    {
+      if (start==INVALID) {
+        NodeIt n(g);
+        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
+        start=n;
+      }
+      if (start!=INVALID) {
+        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
+        while(narc[start]!=INVALID) {
+          euler.push_back(narc[start]);
+          visited[narc[start]]=true;
+          Node next=g.target(narc[start]);
+          ++narc[start];
+          start=next;
+          while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
+        }
+      }
+    }
+
+    ///Arc conversion
+    operator Arc() const { return euler.empty()?INVALID:euler.front(); }
+    ///Edge conversion
+    operator Edge() const { return euler.empty()?INVALID:euler.front(); }
+    ///Compare with \c INVALID
+    bool operator==(Invalid) const { return euler.empty(); }
+    ///Compare with \c INVALID
+    bool operator!=(Invalid) const { return !euler.empty(); }
+
+    ///Next arc of the tour
+
+    ///Next arc of the tour
+    ///
+    EulerIt &operator++() {
+      Node s=g.target(euler.front());
+      euler.pop_front();
+      typename std::list<Arc>::iterator next=euler.begin();
+      while(narc[s]!=INVALID) {
+        while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
+        if(narc[s]==INVALID) break;
+        else {
+          euler.insert(next,narc[s]);
+          visited[narc[s]]=true;
+          Node n=g.target(narc[s]);
+          ++narc[s];
+          s=n;
+        }
+      }
+      return *this;
+    }
+
+    ///Postfix incrementation
+
+    /// Postfix incrementation.
+    ///
+    ///\warning This incrementation returns an \c Arc (which converts to
+    ///an \c Edge), not an \ref EulerIt, as one may expect.
+    Arc operator++(int)
+    {
+      Arc e=*this;
+      ++(*this);
+      return e;
+    }
+  };
+
+
+  ///Check if the given graph is Eulerian
+
+  /// \ingroup graph_properties
+  ///This function checks if the given graph is Eulerian.
+  ///It works for both directed and undirected graphs.
+  ///
+  ///By definition, a digraph is called \e Eulerian if
+  ///and only if it is connected and the number of incoming and outgoing
+  ///arcs are the same for each node.
+  ///Similarly, an undirected graph is called \e Eulerian if
+  ///and only if it is connected and the number of incident edges is even
+  ///for each node.
+  ///
+  ///\note There are (di)graphs that are not Eulerian, but still have an
+  /// Euler tour, since they may contain isolated nodes.
+  ///
+  ///\sa DiEulerIt, EulerIt
+  template<typename GR>
+#ifdef DOXYGEN
+  bool
+#else
+  typename enable_if<UndirectedTagIndicator<GR>,bool>::type
+  eulerian(const GR &g)
+  {
+    for(typename GR::NodeIt n(g);n!=INVALID;++n)
+      if(countIncEdges(g,n)%2) return false;
+    return connected(g);
+  }
+  template<class GR>
+  typename disable_if<UndirectedTagIndicator<GR>,bool>::type
+#endif
+  eulerian(const GR &g)
+  {
+    for(typename GR::NodeIt n(g);n!=INVALID;++n)
+      if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
+    return connected(undirector(g));
+  }
+
+}
+
+#endif
diff --git a/lemon/fib_heap.h b/lemon/fib_heap.h
new file mode 100644
index 0000000..3441722
--- /dev/null
+++ b/lemon/fib_heap.h
@@ -0,0 +1,475 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_FIB_HEAP_H
+#define LEMON_FIB_HEAP_H
+
+///\file
+///\ingroup heaps
+///\brief Fibonacci heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  /// \brief Fibonacci heap data structure.
+  ///
+  /// This class implements the \e Fibonacci \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The methods \ref increase() and \ref erase() are not efficient in a
+  /// Fibonacci heap. In case of many calls of these operations, it is
+  /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class FibHeap {
+  public:
+
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+  private:
+    class Store;
+
+    std::vector<Store> _data;
+    int _minimum;
+    ItemIntMap &_iim;
+    Compare _comp;
+    int _num;
+
+  public:
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit FibHeap(ItemIntMap &map)
+      : _minimum(0), _iim(map), _num() {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    FibHeap(ItemIntMap &map, const Compare &comp)
+      : _minimum(0), _iim(map), _comp(comp), _num() {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num==0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _minimum = 0; _num = 0;
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param item The item to insert.
+    /// \param prio The priority of the item.
+    /// \pre \e item must not be stored in the heap.
+    void push (const Item& item, const Prio& prio) {
+      int i=_iim[item];
+      if ( i < 0 ) {
+        int s=_data.size();
+        _iim.set( item, s );
+        Store st;
+        st.name=item;
+        _data.push_back(st);
+        i=s;
+      } else {
+        _data[i].parent=_data[i].child=-1;
+        _data[i].degree=0;
+        _data[i].in=true;
+        _data[i].marked=false;
+      }
+
+      if ( _num ) {
+        _data[_data[_minimum].right_neighbor].left_neighbor=i;
+        _data[i].right_neighbor=_data[_minimum].right_neighbor;
+        _data[_minimum].right_neighbor=i;
+        _data[i].left_neighbor=_minimum;
+        if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
+      } else {
+        _data[i].right_neighbor=_data[i].left_neighbor=i;
+        _minimum=i;
+      }
+      _data[i].prio=prio;
+      ++_num;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[_minimum].name; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[_minimum].prio; }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      /*The first case is that there are only one root.*/
+      if ( _data[_minimum].left_neighbor==_minimum ) {
+        _data[_minimum].in=false;
+        if ( _data[_minimum].degree!=0 ) {
+          makeRoot(_data[_minimum].child);
+          _minimum=_data[_minimum].child;
+          balance();
+        }
+      } else {
+        int right=_data[_minimum].right_neighbor;
+        unlace(_minimum);
+        _data[_minimum].in=false;
+        if ( _data[_minimum].degree > 0 ) {
+          int left=_data[_minimum].left_neighbor;
+          int child=_data[_minimum].child;
+          int last_child=_data[child].left_neighbor;
+
+          makeRoot(child);
+
+          _data[left].right_neighbor=child;
+          _data[child].left_neighbor=left;
+          _data[right].left_neighbor=last_child;
+          _data[last_child].right_neighbor=right;
+        }
+        _minimum=right;
+        balance();
+      } // the case where there are more roots
+      --_num;
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param item The item to delete.
+    /// \pre \e item must be in the heap.
+    void erase (const Item& item) {
+      int i=_iim[item];
+
+      if ( i >= 0 && _data[i].in ) {
+        if ( _data[i].parent!=-1 ) {
+          int p=_data[i].parent;
+          cut(i,p);
+          cascade(p);
+        }
+        _minimum=i;     //As if its prio would be -infinity
+        pop();
+      }
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param item The item.
+    /// \pre \e item must be in the heap.
+    Prio operator[](const Item& item) const {
+      return _data[_iim[item]].prio;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param item The item.
+    /// \param prio The priority.
+    void set (const Item& item, const Prio& prio) {
+      int i=_iim[item];
+      if ( i >= 0 && _data[i].in ) {
+        if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
+        if ( _comp(_data[i].prio, prio) ) increase(item, prio);
+      } else push(item, prio);
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param prio The priority.
+    /// \pre \e item must be stored in the heap with priority at least \e prio.
+    void decrease (const Item& item, const Prio& prio) {
+      int i=_iim[item];
+      _data[i].prio=prio;
+      int p=_data[i].parent;
+
+      if ( p!=-1 && _comp(prio, _data[p].prio) ) {
+        cut(i,p);
+        cascade(p);
+      }
+      if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param prio The priority.
+    /// \pre \e item must be stored in the heap with priority at most \e prio.
+    void increase (const Item& item, const Prio& prio) {
+      erase(item);
+      push(item, prio);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param item The item.
+    State state(const Item &item) const {
+      int i=_iim[item];
+      if( i>=0 ) {
+        if ( _data[i].in ) i=0;
+        else i=-2;
+      }
+      return State(i);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    void balance() {
+
+      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
+
+      std::vector<int> A(maxdeg,-1);
+
+      /*
+       *Recall that now minimum does not point to the minimum prio element.
+       *We set minimum to this during balance().
+       */
+      int anchor=_data[_minimum].left_neighbor;
+      int next=_minimum;
+      bool end=false;
+
+      do {
+        int active=next;
+        if ( anchor==active ) end=true;
+        int d=_data[active].degree;
+        next=_data[active].right_neighbor;
+
+        while (A[d]!=-1) {
+          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
+            fuse(active,A[d]);
+          } else {
+            fuse(A[d],active);
+            active=A[d];
+          }
+          A[d]=-1;
+          ++d;
+        }
+        A[d]=active;
+      } while ( !end );
+
+
+      while ( _data[_minimum].parent >=0 )
+        _minimum=_data[_minimum].parent;
+      int s=_minimum;
+      int m=_minimum;
+      do {
+        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
+        s=_data[s].right_neighbor;
+      } while ( s != m );
+    }
+
+    void makeRoot(int c) {
+      int s=c;
+      do {
+        _data[s].parent=-1;
+        s=_data[s].right_neighbor;
+      } while ( s != c );
+    }
+
+    void cut(int a, int b) {
+      /*
+       *Replacing a from the children of b.
+       */
+      --_data[b].degree;
+
+      if ( _data[b].degree !=0 ) {
+        int child=_data[b].child;
+        if ( child==a )
+          _data[b].child=_data[child].right_neighbor;
+        unlace(a);
+      }
+
+
+      /*Lacing a to the roots.*/
+      int right=_data[_minimum].right_neighbor;
+      _data[_minimum].right_neighbor=a;
+      _data[a].left_neighbor=_minimum;
+      _data[a].right_neighbor=right;
+      _data[right].left_neighbor=a;
+
+      _data[a].parent=-1;
+      _data[a].marked=false;
+    }
+
+    void cascade(int a) {
+      if ( _data[a].parent!=-1 ) {
+        int p=_data[a].parent;
+
+        if ( _data[a].marked==false ) _data[a].marked=true;
+        else {
+          cut(a,p);
+          cascade(p);
+        }
+      }
+    }
+
+    void fuse(int a, int b) {
+      unlace(b);
+
+      /*Lacing b under a.*/
+      _data[b].parent=a;
+
+      if (_data[a].degree==0) {
+        _data[b].left_neighbor=b;
+        _data[b].right_neighbor=b;
+        _data[a].child=b;
+      } else {
+        int child=_data[a].child;
+        int last_child=_data[child].left_neighbor;
+        _data[child].left_neighbor=b;
+        _data[b].right_neighbor=child;
+        _data[last_child].right_neighbor=b;
+        _data[b].left_neighbor=last_child;
+      }
+
+      ++_data[a].degree;
+
+      _data[b].marked=false;
+    }
+
+    /*
+     *It is invoked only if a has siblings.
+     */
+    void unlace(int a) {
+      int leftn=_data[a].left_neighbor;
+      int rightn=_data[a].right_neighbor;
+      _data[leftn].right_neighbor=rightn;
+      _data[rightn].left_neighbor=leftn;
+    }
+
+
+    class Store {
+      friend class FibHeap;
+
+      Item name;
+      int parent;
+      int left_neighbor;
+      int right_neighbor;
+      int child;
+      int degree;
+      bool marked;
+      bool in;
+      Prio prio;
+
+      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_FIB_HEAP_H
+
diff --git a/lemon/fractional_matching.h b/lemon/fractional_matching.h
new file mode 100644
index 0000000..7448f41
--- /dev/null
+++ b/lemon/fractional_matching.h
@@ -0,0 +1,2139 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_FRACTIONAL_MATCHING_H
+#define LEMON_FRACTIONAL_MATCHING_H
+
+#include <vector>
+#include <queue>
+#include <set>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/unionfind.h>
+#include <lemon/bin_heap.h>
+#include <lemon/maps.h>
+#include <lemon/assert.h>
+#include <lemon/elevator.h>
+
+///\ingroup matching
+///\file
+///\brief Fractional matching algorithms in general graphs.
+
+namespace lemon {
+
+  /// \brief Default traits class of MaxFractionalMatching class.
+  ///
+  /// Default traits class of MaxFractionalMatching class.
+  /// \tparam GR Graph type.
+  template <typename GR>
+  struct MaxFractionalMatchingDefaultTraits {
+
+    /// \brief The type of the graph the algorithm runs on.
+    typedef GR Graph;
+
+    /// \brief The type of the map that stores the matching.
+    ///
+    /// The type of the map that stores the matching arcs.
+    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
+
+    /// \brief Instantiates a MatchingMap.
+    ///
+    /// This function instantiates a \ref MatchingMap.
+    /// \param graph The graph for which we would like to define
+    /// the matching map.
+    static MatchingMap* createMatchingMap(const Graph& graph) {
+      return new MatchingMap(graph);
+    }
+
+    /// \brief The elevator type used by MaxFractionalMatching algorithm.
+    ///
+    /// The elevator type used by MaxFractionalMatching algorithm.
+    ///
+    /// \sa Elevator
+    /// \sa LinkedElevator
+    typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
+
+    /// \brief Instantiates an Elevator.
+    ///
+    /// This function instantiates an \ref Elevator.
+    /// \param graph The graph for which we would like to define
+    /// the elevator.
+    /// \param max_level The maximum level of the elevator.
+    static Elevator* createElevator(const Graph& graph, int max_level) {
+      return new Elevator(graph, max_level);
+    }
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Max cardinality fractional matching
+  ///
+  /// This class provides an implementation of fractional matching
+  /// algorithm based on push-relabel principle.
+  ///
+  /// The maximum cardinality fractional matching is a relaxation of the
+  /// maximum cardinality matching problem where the odd set constraints
+  /// are omitted.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$. The result can be represented as the union of a
+  /// matching with one value edges and a set of odd length cycles
+  /// with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional matching and a
+  /// barrier. The number of adjacents of any node set minus the size
+  /// of node set is a lower bound on the uncovered nodes in the
+  /// graph. For maximum matching a barrier is computed which
+  /// maximizes this difference.
+  ///
+  /// The algorithm can be executed with the run() function.  After it
+  /// the matching (the primal solution) and the barrier (the dual
+  /// solution) can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxFractionalMatching::primalScale "2".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+#ifdef DOXYGEN
+  template <typename GR, typename TR>
+#else
+  template <typename GR,
+            typename TR = MaxFractionalMatchingDefaultTraits<GR> >
+#endif
+  class MaxFractionalMatching {
+  public:
+
+    /// \brief The \ref lemon::MaxFractionalMatchingDefaultTraits
+    /// "traits class" of the algorithm.
+    typedef TR Traits;
+    /// The type of the graph the algorithm runs on.
+    typedef typename TR::Graph Graph;
+    /// The type of the matching map.
+    typedef typename TR::MatchingMap MatchingMap;
+    /// The type of the elevator.
+    typedef typename TR::Elevator Elevator;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+  private:
+
+    const Graph &_graph;
+    int _node_num;
+    bool _allow_loops;
+    int _empty_level;
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    bool _local_matching;
+    MatchingMap *_matching;
+
+    bool _local_level;
+    Elevator *_level;
+
+    typedef typename Graph::template NodeMap<int> InDegMap;
+    InDegMap *_indeg;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _local_matching = true;
+        _matching = Traits::createMatchingMap(_graph);
+      }
+      if (!_level) {
+        _local_level = true;
+        _level = Traits::createElevator(_graph, _node_num);
+      }
+      if (!_indeg) {
+        _indeg = new InDegMap(_graph);
+      }
+    }
+
+    void destroyStructures() {
+      if (_local_matching) {
+        delete _matching;
+      }
+      if (_local_level) {
+        delete _level;
+      }
+      if (_indeg) {
+        delete _indeg;
+      }
+    }
+
+    void postprocessing() {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] != 0) continue;
+        _indeg->set(n, -1);
+        Node u = n;
+        while ((*_matching)[u] != INVALID) {
+          Node v = _graph.target((*_matching)[u]);
+          _indeg->set(v, -1);
+          Arc a = _graph.oppositeArc((*_matching)[u]);
+          u = _graph.target((*_matching)[v]);
+          _indeg->set(u, -1);
+          _matching->set(v, a);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] != 1) continue;
+        _indeg->set(n, -1);
+
+        int num = 1;
+        Node u = _graph.target((*_matching)[n]);
+        while (u != n) {
+          _indeg->set(u, -1);
+          u = _graph.target((*_matching)[u]);
+          ++num;
+        }
+        if (num % 2 == 0 && num > 2) {
+          Arc prev = _graph.oppositeArc((*_matching)[n]);
+          Node v = _graph.target((*_matching)[n]);
+          u = _graph.target((*_matching)[v]);
+          _matching->set(v, prev);
+          while (u != n) {
+            prev = _graph.oppositeArc((*_matching)[u]);
+            v = _graph.target((*_matching)[u]);
+            u = _graph.target((*_matching)[v]);
+            _matching->set(v, prev);
+          }
+        }
+      }
+    }
+
+  public:
+
+    typedef MaxFractionalMatching Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <typename T>
+    struct SetMatchingMapTraits : public Traits {
+      typedef T MatchingMap;
+      static MatchingMap *createMatchingMap(const Graph&) {
+        LEMON_ASSERT(false, "MatchingMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// MatchingMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting MatchingMap
+    /// type.
+    template <typename T>
+    struct SetMatchingMap
+      : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
+      typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Graph&, int) {
+        LEMON_ASSERT(false, "Elevator is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type. If this named parameter is used, then an external
+    /// elevator object must be passed to the algorithm using the
+    /// \ref elevator(Elevator&) "elevator()" function before calling
+    /// \ref run() or \ref init().
+    /// \sa SetStandardElevator
+    template <typename T>
+    struct SetElevator
+      : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
+      typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetStandardElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Graph& graph, int max_level) {
+        return new Elevator(graph, max_level);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type with automatic allocation.
+    /// The Elevator should have standard constructor interface to be
+    /// able to automatically created by the algorithm (i.e. the
+    /// graph and the maximum level should be passed to it).
+    /// However an external elevator object could also be passed to the
+    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
+    /// before calling \ref run() or \ref init().
+    /// \sa SetElevator
+    template <typename T>
+    struct SetStandardElevator
+      : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
+      typedef MaxFractionalMatching<Graph,
+                                    SetStandardElevatorTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    MaxFractionalMatching() {}
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    ///
+    MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
+      : _graph(graph), _allow_loops(allow_loops),
+        _local_matching(false), _matching(0),
+        _local_level(false), _level(0),  _indeg(0)
+    {}
+
+    ~MaxFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \brief Sets the matching map.
+    ///
+    /// Sets the matching map.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    MaxFractionalMatching& matchingMap(MatchingMap& map) {
+      if (_local_matching) {
+        delete _matching;
+        _local_matching = false;
+      }
+      _matching = ↦
+      return *this;
+    }
+
+    /// \brief Sets the elevator used by algorithm.
+    ///
+    /// Sets the elevator used by algorithm.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated elevator,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    MaxFractionalMatching& elevator(Elevator& elevator) {
+      if (_local_level) {
+        delete _level;
+        _local_level = false;
+      }
+      _level = &elevator;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the elevator.
+    ///
+    /// Returns a const reference to the elevator.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const Elevator& elevator() const {
+      return *_level;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use one of the
+    /// member functions called \c run(). \n
+    /// If you need more control on the execution, first
+    /// you must call \ref init() and then one variant of the start()
+    /// member.
+
+    /// @{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// matching.
+    void init() {
+      createStructures();
+
+      _level->initStart();
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _indeg->set(n, 0);
+        _matching->set(n, INVALID);
+        _level->initAddItem(n);
+      }
+      _level->initFinish();
+
+      _empty_level = _node_num;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+          if (_graph.target(a) == n && !_allow_loops) continue;
+          _matching->set(n, a);
+          Node v = _graph.target((*_matching)[n]);
+          _indeg->set(v, (*_indeg)[v] + 1);
+          break;
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] == 0) {
+          _level->activate(n);
+        }
+      }
+    }
+
+    /// \brief Starts the algorithm and computes a fractional matching
+    ///
+    /// The algorithm computes a maximum fractional matching.
+    ///
+    /// \param postprocess The algorithm computes first a matching
+    /// which is a union of a matching with one value edges, cycles
+    /// with half value edges and even length paths with half value
+    /// edges. If the parameter is true, then after the push-relabel
+    /// algorithm it postprocesses the matching to contain only
+    /// matching edges and half value odd cycles.
+    void start(bool postprocess = true) {
+      Node n;
+      while ((n = _level->highestActive()) != INVALID) {
+        int level = _level->highestActiveLevel();
+        int new_level = _level->maxLevel();
+        for (InArcIt a(_graph, n); a != INVALID; ++a) {
+          Node u = _graph.source(a);
+          if (n == u && !_allow_loops) continue;
+          Node v = _graph.target((*_matching)[u]);
+          if ((*_level)[v] < level) {
+            _indeg->set(v, (*_indeg)[v] - 1);
+            if ((*_indeg)[v] == 0) {
+              _level->activate(v);
+            }
+            _matching->set(u, a);
+            _indeg->set(n, (*_indeg)[n] + 1);
+            _level->deactivate(n);
+            goto no_more_push;
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+        if (new_level + 1 < _level->maxLevel()) {
+          _level->liftHighestActive(new_level + 1);
+        } else {
+          _level->liftHighestActiveToTop();
+        }
+        if (_level->emptyLevel(level)) {
+          _level->liftToTop(level);
+        }
+      no_more_push:
+        ;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] == INVALID) continue;
+        Node u = _graph.target((*_matching)[n]);
+        if ((*_indeg)[u] > 1) {
+          _indeg->set(u, (*_indeg)[u] - 1);
+          _matching->set(n, INVALID);
+        }
+      }
+      if (postprocess) {
+        postprocessing();
+      }
+    }
+
+    /// \brief Starts the algorithm and computes a perfect fractional
+    /// matching
+    ///
+    /// The algorithm computes a perfect fractional matching. If it
+    /// does not exists, then the algorithm returns false and the
+    /// matching is undefined and the barrier.
+    ///
+    /// \param postprocess The algorithm computes first a matching
+    /// which is a union of a matching with one value edges, cycles
+    /// with half value edges and even length paths with half value
+    /// edges. If the parameter is true, then after the push-relabel
+    /// algorithm it postprocesses the matching to contain only
+    /// matching edges and half value odd cycles.
+    bool startPerfect(bool postprocess = true) {
+      Node n;
+      while ((n = _level->highestActive()) != INVALID) {
+        int level = _level->highestActiveLevel();
+        int new_level = _level->maxLevel();
+        for (InArcIt a(_graph, n); a != INVALID; ++a) {
+          Node u = _graph.source(a);
+          if (n == u && !_allow_loops) continue;
+          Node v = _graph.target((*_matching)[u]);
+          if ((*_level)[v] < level) {
+            _indeg->set(v, (*_indeg)[v] - 1);
+            if ((*_indeg)[v] == 0) {
+              _level->activate(v);
+            }
+            _matching->set(u, a);
+            _indeg->set(n, (*_indeg)[n] + 1);
+            _level->deactivate(n);
+            goto no_more_push;
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+        if (new_level + 1 < _level->maxLevel()) {
+          _level->liftHighestActive(new_level + 1);
+        } else {
+          _level->liftHighestActiveToTop();
+          _empty_level = _level->maxLevel() - 1;
+          return false;
+        }
+        if (_level->emptyLevel(level)) {
+          _level->liftToTop(level);
+          _empty_level = level;
+          return false;
+        }
+      no_more_push:
+        ;
+      }
+      if (postprocess) {
+        postprocessing();
+      }
+      return true;
+    }
+
+    /// \brief Runs the algorithm
+    ///
+    /// Just a shortcut for the next code:
+    ///\code
+    /// init();
+    /// start();
+    ///\endcode
+    void run(bool postprocess = true) {
+      init();
+      start(postprocess);
+    }
+
+    /// \brief Runs the algorithm to find a perfect fractional matching
+    ///
+    /// Just a shortcut for the next code:
+    ///\code
+    /// init();
+    /// startPerfect();
+    ///\endcode
+    bool runPerfect(bool postprocess = true) {
+      init();
+      return startPerfect(postprocess);
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    /// The result of the %Matching algorithm can be obtained using these
+    /// functions.\n
+    /// Before the use of these functions,
+    /// either run() or start() must be called.
+    ///@{
+
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Returns a const reference to the matching map.
+    ///
+    /// Returns a const reference to the node map storing the found
+    /// fractional matching. This method can be called after
+    /// running the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
+        (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Returns true if the node is in the barrier
+    ///
+    /// The barrier is a subset of the nodes. If the nodes in the
+    /// barrier have less adjacent nodes than the size of the barrier,
+    /// then at least as much nodes cannot be covered as the
+    /// difference of the two subsets.
+    bool barrier(const Node& node) const {
+      return (*_level)[node] >= _empty_level;
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted fractional matching in general graphs
+  ///
+  /// This class provides an efficient implementation of fractional
+  /// matching algorithm. The implementation uses priority queues and
+  /// provides \f$O(nm\log n)\f$ time complexity.
+  ///
+  /// The maximum weighted fractional matching is a relaxation of the
+  /// maximum weighted matching problem where the odd set constraints
+  /// are omitted.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_ew_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$. The result must be the union of a matching with one
+  /// value edges and a set of odd length cycles with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional matching and a
+  /// proof of the optimality. The solution of the dual problem can be
+  /// used to check the result of the algorithm. The dual linear
+  /// problem is the following.
+  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
+  /// \f[y_u \ge 0 \quad \forall u \in V\f]
+  /// \f[\min \sum_{u \in V}y_u \f]
+  ///
+  /// The algorithm can be executed with the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxWeightedFractionalMatching::primalScale "2".
+  /// If the value type is integer, then the dual
+  /// solution is scaled by
+  /// \ref MaxWeightedFractionalMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedFractionalMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+    /// \brief Scaling factor for dual solution
+    ///
+    /// Scaling factor for dual solution. It is equal to 4 or 1
+    /// according to the value type.
+    static const int dualScale =
+      std::numeric_limits<Value>::is_integer ? 4 : 1;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+    NodePotential* _node_potential;
+
+    int _node_num;
+    bool _allow_loops;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef typename Graph::template NodeMap<Status> StatusMap;
+    StatusMap* _status;
+
+    typedef typename Graph::template NodeMap<Arc> PredMap;
+    PredMap* _pred;
+
+    typedef ExtendFindEnum<IntNodeMap> TreeSet;
+
+    IntNodeMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntNodeMap *_delta1_index;
+    BinHeap<Value, IntNodeMap> *_delta1;
+
+    IntNodeMap *_delta2_index;
+    BinHeap<Value, IntNodeMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    Value _delta_sum;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+      if (!_status) {
+        _status = new StatusMap(_graph);
+      }
+      if (!_pred) {
+        _pred = new PredMap(_graph);
+      }
+      if (!_tree_set) {
+        _tree_set_index = new IntNodeMap(_graph);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      if (!_delta1) {
+        _delta1_index = new IntNodeMap(_graph);
+        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
+      }
+      if (!_delta2) {
+        _delta2_index = new IntNodeMap(_graph);
+        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
+      }
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_status) {
+        delete _status;
+      }
+      if (_pred) {
+        delete _pred;
+      }
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta1) {
+        delete _delta1_index;
+        delete _delta1;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+    }
+
+    void matchedToEven(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      _delta1->push(node, (*_node_potential)[node]);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->push(a, rw / 2);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->push(a, rw / 2);
+        } else if ((*_status)[v] == MATCHED) {
+          if (_delta2->state(v) != _delta2->IN_HEAP) {
+            _pred->set(v, a);
+            _delta2->push(v, rw);
+          } else if ((*_delta2)[v] > rw) {
+            _pred->set(v, a);
+            _delta2->decrease(v, rw);
+          }
+        }
+      }
+    }
+
+    void matchedToOdd(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+    }
+
+    void evenToMatched(Node node, int tree) {
+      _delta1->erase(node);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->erase(a);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->erase(a);
+          if (minrw > rw) {
+            min = _graph.oppositeArc(a);
+            minrw = rw;
+          }
+        } else if ((*_status)[v]  == MATCHED) {
+          if ((*_pred)[v] == a) {
+            Arc mina = INVALID;
+            Value minrwa = std::numeric_limits<Value>::max();
+            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
+              Node va = _graph.target(aa);
+              if ((*_status)[va] != EVEN ||
+                  _tree_set->find(va) == tree) continue;
+              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
+                dualScale * _weight[aa];
+              if (minrwa > rwa) {
+                minrwa = rwa;
+                mina = aa;
+              }
+            }
+            if (mina != INVALID) {
+              _pred->set(v, mina);
+              _delta2->increase(v, minrwa);
+            } else {
+              _pred->set(v, INVALID);
+              _delta2->erase(v);
+            }
+          }
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void oddToMatched(Node node) {
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        if ((*_status)[v] != EVEN) continue;
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (minrw > rw) {
+          min = _graph.oppositeArc(a);
+          minrw = rw;
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void alternatePath(Node even, int tree) {
+      Node odd;
+
+      _status->set(even, MATCHED);
+      evenToMatched(even, tree);
+
+      Arc prev = (*_matching)[even];
+      while (prev != INVALID) {
+        odd = _graph.target(prev);
+        even = _graph.target((*_pred)[odd]);
+        _matching->set(odd, (*_pred)[odd]);
+        _status->set(odd, MATCHED);
+        oddToMatched(odd);
+
+        prev = (*_matching)[even];
+        _status->set(even, MATCHED);
+        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
+        evenToMatched(even, tree);
+      }
+    }
+
+    void destroyTree(int tree) {
+      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
+        if ((*_status)[n] == EVEN) {
+          _status->set(n, MATCHED);
+          evenToMatched(n, tree);
+        } else if ((*_status)[n] == ODD) {
+          _status->set(n, MATCHED);
+          oddToMatched(n);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+
+    void unmatchNode(const Node& node) {
+      int tree = _tree_set->find(node);
+
+      alternatePath(node, tree);
+      destroyTree(tree);
+
+      _matching->set(node, INVALID);
+    }
+
+
+    void augmentOnEdge(const Edge& edge) {
+      Node left = _graph.u(edge);
+      int left_tree = _tree_set->find(left);
+
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+      _matching->set(left, _graph.direct(edge, true));
+
+      Node right = _graph.v(edge);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.direct(edge, false));
+    }
+
+    void augmentOnArc(const Arc& arc) {
+      Node left = _graph.source(arc);
+      _status->set(left, MATCHED);
+      _matching->set(left, arc);
+      _pred->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+    void extendOnArc(const Arc& arc) {
+      Node base = _graph.target(arc);
+      int tree = _tree_set->find(base);
+
+      Node odd = _graph.source(arc);
+      _tree_set->insert(odd, tree);
+      _status->set(odd, ODD);
+      matchedToOdd(odd, tree);
+      _pred->set(odd, arc);
+
+      Node even = _graph.target((*_matching)[odd]);
+      _tree_set->insert(even, tree);
+      _status->set(even, EVEN);
+      matchedToEven(even, tree);
+    }
+
+    void cycleOnEdge(const Edge& edge, int tree) {
+      Node nca = INVALID;
+      std::vector<Node> left_path, right_path;
+
+      {
+        std::set<Node> left_set, right_set;
+        Node left = _graph.u(edge);
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        Node right = _graph.v(edge);
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+          if ((*_matching)[left] == INVALID) break;
+
+          left = _graph.target((*_matching)[left]);
+          left_path.push_back(left);
+          left = _graph.target((*_pred)[left]);
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_matching)[right] == INVALID) break;
+
+          right = _graph.target((*_matching)[right]);
+          right_path.push_back(right);
+          right = _graph.target((*_pred)[right]);
+          right_path.push_back(right);
+
+          right_set.insert(right);
+
+        }
+
+        if (nca == INVALID) {
+          if ((*_matching)[left] == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              right_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              left_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      alternatePath(nca, tree);
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        _matching->set(left_path[i], prev);
+        _status->set(left_path[i], MATCHED);
+        evenToMatched(left_path[i], tree);
+
+        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
+        _status->set(left_path[i + 1], MATCHED);
+        oddToMatched(left_path[i + 1]);
+      }
+      _matching->set(nca, prev);
+
+      for (int i = 0; right_path[i] != nca; i += 2) {
+        _status->set(right_path[i], MATCHED);
+        evenToMatched(right_path[i], tree);
+
+        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
+        _status->set(right_path[i + 1], MATCHED);
+        oddToMatched(right_path[i + 1]);
+      }
+
+      destroyTree(tree);
+    }
+
+    void extractCycle(const Arc &arc) {
+      Node left = _graph.source(arc);
+      Node odd = _graph.target((*_matching)[left]);
+      Arc prev;
+      while (odd != left) {
+        Node even = _graph.target((*_matching)[odd]);
+        prev = (*_matching)[odd];
+        odd = _graph.target((*_matching)[even]);
+        _matching->set(even, _graph.oppositeArc(prev));
+      }
+      _matching->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
+                                  bool allow_loops = true)
+      : _graph(graph), _weight(weight), _matching(0),
+      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
+      _status(0),  _pred(0),
+      _tree_set_index(0), _tree_set(0),
+
+      _delta1_index(0), _delta1(0),
+      _delta2_index(0), _delta2(0),
+      _delta3_index(0), _delta3(0),
+
+      _delta_sum() {}
+
+    ~MaxWeightedFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta1_index)[n] = _delta1->PRE_HEAP;
+        (*_delta2_index)[n] = _delta2->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _tree_set->clear();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = 0;
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n && !_allow_loops) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        _node_potential->set(n, max);
+        _delta1->push(n, max);
+
+        _tree_set->insert(n);
+
+        _matching->set(n, INVALID);
+        _status->set(n, EVEN);
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        Node left = _graph.u(e);
+        Node right = _graph.v(e);
+        if (left == right && !_allow_loops) continue;
+        _delta3->push(e, ((*_node_potential)[left] +
+                          (*_node_potential)[right] -
+                          dualScale * _weight[e]) / 2);
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    void start() {
+      enum OpType {
+        D1, D2, D3
+      };
+
+      int unmatched = _node_num;
+      while (unmatched > 0) {
+        Value d1 = !_delta1->empty() ?
+          _delta1->prio() : std::numeric_limits<Value>::max();
+
+        Value d2 = !_delta2->empty() ?
+          _delta2->prio() : std::numeric_limits<Value>::max();
+
+        Value d3 = !_delta3->empty() ?
+          _delta3->prio() : std::numeric_limits<Value>::max();
+
+        _delta_sum = d3; OpType ot = D3;
+        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+
+        switch (ot) {
+        case D1:
+          {
+            Node n = _delta1->top();
+            unmatchNode(n);
+            --unmatched;
+          }
+          break;
+        case D2:
+          {
+            Node n = _delta2->top();
+            Arc a = (*_pred)[n];
+            if ((*_matching)[n] == INVALID) {
+              augmentOnArc(a);
+              --unmatched;
+            } else {
+              Node v = _graph.target((*_matching)[n]);
+              if ((*_matching)[n] !=
+                  _graph.oppositeArc((*_matching)[v])) {
+                extractCycle(a);
+                --unmatched;
+              } else {
+                extendOnArc(a);
+              }
+            }
+          } break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            Node left = _graph.u(e);
+            Node right = _graph.v(e);
+
+            int left_tree = _tree_set->find(left);
+            int right_tree = _tree_set->find(right);
+
+            if (left_tree == right_tree) {
+              cycleOnEdge(e, left_tree);
+              --unmatched;
+            } else {
+              augmentOnEdge(e);
+              unmatched -= 2;
+            }
+          } break;
+        }
+      }
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
+    ///
+    /// \note mwfm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwfm.init();
+    ///   mwfm.start();
+    /// \endcode
+    void run() {
+      init();
+      start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching. This
+    /// value is scaled by \ref primalScale "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum * primalScale / 2;
+    }
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
+        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      return sum;
+    }
+
+    /// \brief Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted fractional perfect matching in general graphs
+  ///
+  /// This class provides an efficient implementation of fractional
+  /// matching algorithm. The implementation uses priority queues and
+  /// provides \f$O(nm\log n)\f$ time complexity.
+  ///
+  /// The maximum weighted fractional perfect matching is a relaxation
+  /// of the maximum weighted perfect matching problem where the odd
+  /// set constraints are omitted.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_ew_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$. The result must be the union of a matching with one
+  /// value edges and a set of odd length cycles with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional matching and a
+  /// proof of the optimality. The solution of the dual problem can be
+  /// used to check the result of the algorithm. The dual linear
+  /// problem is the following.
+  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
+  /// \f[\min \sum_{u \in V}y_u \f]
+  ///
+  /// The algorithm can be executed with the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
+  /// If the value type is integer, then the dual
+  /// solution is scaled by
+  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedPerfectFractionalMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+    /// \brief Scaling factor for dual solution
+    ///
+    /// Scaling factor for dual solution. It is equal to 4 or 1
+    /// according to the value type.
+    static const int dualScale =
+      std::numeric_limits<Value>::is_integer ? 4 : 1;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+    NodePotential* _node_potential;
+
+    int _node_num;
+    bool _allow_loops;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef typename Graph::template NodeMap<Status> StatusMap;
+    StatusMap* _status;
+
+    typedef typename Graph::template NodeMap<Arc> PredMap;
+    PredMap* _pred;
+
+    typedef ExtendFindEnum<IntNodeMap> TreeSet;
+
+    IntNodeMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntNodeMap *_delta2_index;
+    BinHeap<Value, IntNodeMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    Value _delta_sum;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+      if (!_status) {
+        _status = new StatusMap(_graph);
+      }
+      if (!_pred) {
+        _pred = new PredMap(_graph);
+      }
+      if (!_tree_set) {
+        _tree_set_index = new IntNodeMap(_graph);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      if (!_delta2) {
+        _delta2_index = new IntNodeMap(_graph);
+        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
+      }
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_status) {
+        delete _status;
+      }
+      if (_pred) {
+        delete _pred;
+      }
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+    }
+
+    void matchedToEven(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->push(a, rw / 2);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->push(a, rw / 2);
+        } else if ((*_status)[v] == MATCHED) {
+          if (_delta2->state(v) != _delta2->IN_HEAP) {
+            _pred->set(v, a);
+            _delta2->push(v, rw);
+          } else if ((*_delta2)[v] > rw) {
+            _pred->set(v, a);
+            _delta2->decrease(v, rw);
+          }
+        }
+      }
+    }
+
+    void matchedToOdd(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+    }
+
+    void evenToMatched(Node node, int tree) {
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->erase(a);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->erase(a);
+          if (minrw > rw) {
+            min = _graph.oppositeArc(a);
+            minrw = rw;
+          }
+        } else if ((*_status)[v]  == MATCHED) {
+          if ((*_pred)[v] == a) {
+            Arc mina = INVALID;
+            Value minrwa = std::numeric_limits<Value>::max();
+            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
+              Node va = _graph.target(aa);
+              if ((*_status)[va] != EVEN ||
+                  _tree_set->find(va) == tree) continue;
+              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
+                dualScale * _weight[aa];
+              if (minrwa > rwa) {
+                minrwa = rwa;
+                mina = aa;
+              }
+            }
+            if (mina != INVALID) {
+              _pred->set(v, mina);
+              _delta2->increase(v, minrwa);
+            } else {
+              _pred->set(v, INVALID);
+              _delta2->erase(v);
+            }
+          }
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void oddToMatched(Node node) {
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        if ((*_status)[v] != EVEN) continue;
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (minrw > rw) {
+          min = _graph.oppositeArc(a);
+          minrw = rw;
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void alternatePath(Node even, int tree) {
+      Node odd;
+
+      _status->set(even, MATCHED);
+      evenToMatched(even, tree);
+
+      Arc prev = (*_matching)[even];
+      while (prev != INVALID) {
+        odd = _graph.target(prev);
+        even = _graph.target((*_pred)[odd]);
+        _matching->set(odd, (*_pred)[odd]);
+        _status->set(odd, MATCHED);
+        oddToMatched(odd);
+
+        prev = (*_matching)[even];
+        _status->set(even, MATCHED);
+        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
+        evenToMatched(even, tree);
+      }
+    }
+
+    void destroyTree(int tree) {
+      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
+        if ((*_status)[n] == EVEN) {
+          _status->set(n, MATCHED);
+          evenToMatched(n, tree);
+        } else if ((*_status)[n] == ODD) {
+          _status->set(n, MATCHED);
+          oddToMatched(n);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+    void augmentOnEdge(const Edge& edge) {
+      Node left = _graph.u(edge);
+      int left_tree = _tree_set->find(left);
+
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+      _matching->set(left, _graph.direct(edge, true));
+
+      Node right = _graph.v(edge);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.direct(edge, false));
+    }
+
+    void augmentOnArc(const Arc& arc) {
+      Node left = _graph.source(arc);
+      _status->set(left, MATCHED);
+      _matching->set(left, arc);
+      _pred->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+    void extendOnArc(const Arc& arc) {
+      Node base = _graph.target(arc);
+      int tree = _tree_set->find(base);
+
+      Node odd = _graph.source(arc);
+      _tree_set->insert(odd, tree);
+      _status->set(odd, ODD);
+      matchedToOdd(odd, tree);
+      _pred->set(odd, arc);
+
+      Node even = _graph.target((*_matching)[odd]);
+      _tree_set->insert(even, tree);
+      _status->set(even, EVEN);
+      matchedToEven(even, tree);
+    }
+
+    void cycleOnEdge(const Edge& edge, int tree) {
+      Node nca = INVALID;
+      std::vector<Node> left_path, right_path;
+
+      {
+        std::set<Node> left_set, right_set;
+        Node left = _graph.u(edge);
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        Node right = _graph.v(edge);
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+          if ((*_matching)[left] == INVALID) break;
+
+          left = _graph.target((*_matching)[left]);
+          left_path.push_back(left);
+          left = _graph.target((*_pred)[left]);
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_matching)[right] == INVALID) break;
+
+          right = _graph.target((*_matching)[right]);
+          right_path.push_back(right);
+          right = _graph.target((*_pred)[right]);
+          right_path.push_back(right);
+
+          right_set.insert(right);
+
+        }
+
+        if (nca == INVALID) {
+          if ((*_matching)[left] == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              right_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              left_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      alternatePath(nca, tree);
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        _matching->set(left_path[i], prev);
+        _status->set(left_path[i], MATCHED);
+        evenToMatched(left_path[i], tree);
+
+        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
+        _status->set(left_path[i + 1], MATCHED);
+        oddToMatched(left_path[i + 1]);
+      }
+      _matching->set(nca, prev);
+
+      for (int i = 0; right_path[i] != nca; i += 2) {
+        _status->set(right_path[i], MATCHED);
+        evenToMatched(right_path[i], tree);
+
+        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
+        _status->set(right_path[i + 1], MATCHED);
+        oddToMatched(right_path[i + 1]);
+      }
+
+      destroyTree(tree);
+    }
+
+    void extractCycle(const Arc &arc) {
+      Node left = _graph.source(arc);
+      Node odd = _graph.target((*_matching)[left]);
+      Arc prev;
+      while (odd != left) {
+        Node even = _graph.target((*_matching)[odd]);
+        prev = (*_matching)[odd];
+        odd = _graph.target((*_matching)[even]);
+        _matching->set(even, _graph.oppositeArc(prev));
+      }
+      _matching->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedPerfectFractionalMatching(const Graph& graph,
+                                         const WeightMap& weight,
+                                         bool allow_loops = true)
+      : _graph(graph), _weight(weight), _matching(0),
+      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
+      _status(0),  _pred(0),
+      _tree_set_index(0), _tree_set(0),
+
+      _delta2_index(0), _delta2(0),
+      _delta3_index(0), _delta3(0),
+
+      _delta_sum() {}
+
+    ~MaxWeightedPerfectFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta2_index)[n] = _delta2->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+
+      _delta2->clear();
+      _delta3->clear();
+      _tree_set->clear();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = - std::numeric_limits<Value>::max();
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n && !_allow_loops) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        _node_potential->set(n, max);
+
+        _tree_set->insert(n);
+
+        _matching->set(n, INVALID);
+        _status->set(n, EVEN);
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        Node left = _graph.u(e);
+        Node right = _graph.v(e);
+        if (left == right && !_allow_loops) continue;
+        _delta3->push(e, ((*_node_potential)[left] +
+                          (*_node_potential)[right] -
+                          dualScale * _weight[e]) / 2);
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    bool start() {
+      enum OpType {
+        D2, D3
+      };
+
+      int unmatched = _node_num;
+      while (unmatched > 0) {
+        Value d2 = !_delta2->empty() ?
+          _delta2->prio() : std::numeric_limits<Value>::max();
+
+        Value d3 = !_delta3->empty() ?
+          _delta3->prio() : std::numeric_limits<Value>::max();
+
+        _delta_sum = d3; OpType ot = D3;
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+
+        if (_delta_sum == std::numeric_limits<Value>::max()) {
+          return false;
+        }
+
+        switch (ot) {
+        case D2:
+          {
+            Node n = _delta2->top();
+            Arc a = (*_pred)[n];
+            if ((*_matching)[n] == INVALID) {
+              augmentOnArc(a);
+              --unmatched;
+            } else {
+              Node v = _graph.target((*_matching)[n]);
+              if ((*_matching)[n] !=
+                  _graph.oppositeArc((*_matching)[v])) {
+                extractCycle(a);
+                --unmatched;
+              } else {
+                extendOnArc(a);
+              }
+            }
+          } break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            Node left = _graph.u(e);
+            Node right = _graph.v(e);
+
+            int left_tree = _tree_set->find(left);
+            int right_tree = _tree_set->find(right);
+
+            if (left_tree == right_tree) {
+              cycleOnEdge(e, left_tree);
+              --unmatched;
+            } else {
+              augmentOnEdge(e);
+              unmatched -= 2;
+            }
+          } break;
+        }
+      }
+      return true;
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedPerfectFractionalMatching
+    /// algorithm.
+    ///
+    /// \note mwfm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwpfm.init();
+    ///   mwpfm.start();
+    /// \endcode
+    bool run() {
+      init();
+      return start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching. This
+    /// value is scaled by \ref primalScale "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum * primalScale / 2;
+    }
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
+        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      return sum;
+    }
+
+    /// \brief Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// @}
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_FRACTIONAL_MATCHING_H
diff --git a/lemon/full_graph.h b/lemon/full_graph.h
new file mode 100644
index 0000000..b63df2e
--- /dev/null
+++ b/lemon/full_graph.h
@@ -0,0 +1,1082 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_FULL_GRAPH_H
+#define LEMON_FULL_GRAPH_H
+
+#include <lemon/core.h>
+#include <lemon/bits/graph_extender.h>
+
+///\ingroup graphs
+///\file
+///\brief FullDigraph and FullGraph classes.
+
+namespace lemon {
+
+  class FullDigraphBase {
+  public:
+
+    typedef FullDigraphBase Digraph;
+
+    class Node;
+    class Arc;
+
+  protected:
+
+    int _node_num;
+    int _arc_num;
+
+    FullDigraphBase() {}
+
+    void construct(int n) { _node_num = n; _arc_num = n * n; }
+
+  public:
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+
+    Node operator()(int ix) const { return Node(ix); }
+    static int index(const Node& node) { return node._id; }
+
+    Arc arc(const Node& s, const Node& t) const {
+      return Arc(s._id * _node_num + t._id);
+    }
+
+    int nodeNum() const { return _node_num; }
+    int arcNum() const { return _arc_num; }
+
+    int maxNodeId() const { return _node_num - 1; }
+    int maxArcId() const { return _arc_num - 1; }
+
+    Node source(Arc arc) const { return arc._id / _node_num; }
+    Node target(Arc arc) const { return arc._id % _node_num; }
+
+    static int id(Node node) { return node._id; }
+    static int id(Arc arc) { return arc._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+
+    typedef True FindArcTag;
+
+    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
+      return prev == INVALID ? arc(s, t) : INVALID;
+    }
+
+    class Node {
+      friend class FullDigraphBase;
+
+    protected:
+      int _id;
+      Node(int id) : _id(id) {}
+    public:
+      Node() {}
+      Node (Invalid) : _id(-1) {}
+      bool operator==(const Node node) const {return _id == node._id;}
+      bool operator!=(const Node node) const {return _id != node._id;}
+      bool operator<(const Node node) const {return _id < node._id;}
+    };
+
+    class Arc {
+      friend class FullDigraphBase;
+
+    protected:
+      int _id;  // _node_num * source + target;
+
+      Arc(int id) : _id(id) {}
+
+    public:
+      Arc() { }
+      Arc (Invalid) { _id = -1; }
+      bool operator==(const Arc arc) const {return _id == arc._id;}
+      bool operator!=(const Arc arc) const {return _id != arc._id;}
+      bool operator<(const Arc arc) const {return _id < arc._id;}
+    };
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = _arc_num - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc._id = (node._id + 1) * _node_num - 1;
+    }
+
+    void nextOut(Arc& arc) const {
+      if (arc._id % _node_num == 0) arc._id = 0;
+      --arc._id;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc._id = _arc_num + node._id - _node_num;
+    }
+
+    void nextIn(Arc& arc) const {
+      arc._id -= _node_num;
+      if (arc._id < 0) arc._id = -1;
+    }
+
+  };
+
+  typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief A 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, FullGraph
+  /// conforms to the \ref concepts::Graph "Graph" concept,
+  /// moreover FullGraph does not contain a loop for each
+  /// node as this class does.
+  ///
+  /// \sa FullGraph
+  class FullDigraph : public ExtendedFullDigraphBase {
+    typedef ExtendedFullDigraphBase Parent;
+
+  public:
+
+    /// \brief Default constructor.
+    ///
+    /// Default constructor. The number of nodes and arcs will be zero.
+    FullDigraph() { construct(0); }
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param n The number of the nodes.
+    FullDigraph(int n) { construct(n); }
+
+    /// \brief Resizes the digraph
+    ///
+    /// 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) {
+      Parent::notifier(Arc()).clear();
+      Parent::notifier(Node()).clear();
+      construct(n);
+      Parent::notifier(Node()).build();
+      Parent::notifier(Arc()).build();
+    }
+
+    /// \brief Returns the node with the given index.
+    ///
+    /// Returns the node with the given index. Since 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); }
+
+    /// \brief Returns the index of the given 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(Node u, Node v) const {
+      return Parent::arc(u, v);
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of arcs.
+    int arcNum() const { return Parent::arcNum(); }
+  };
+
+
+  class FullGraphBase {
+  public:
+
+    typedef FullGraphBase Graph;
+
+    class Node;
+    class Arc;
+    class Edge;
+
+  protected:
+
+    int _node_num;
+    int _edge_num;
+
+    FullGraphBase() {}
+
+    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
+
+    int _uid(int e) const {
+      int u = e / _node_num;
+      int v = e % _node_num;
+      return u < v ? u : _node_num - 2 - u;
+    }
+
+    int _vid(int e) const {
+      int u = e / _node_num;
+      int v = e % _node_num;
+      return u < v ? v : _node_num - 1 - v;
+    }
+
+    void _uvid(int e, int& u, int& v) const {
+      u = e / _node_num;
+      v = e % _node_num;
+      if  (u >= v) {
+        u = _node_num - 2 - u;
+        v = _node_num - 1 - v;
+      }
+    }
+
+    void _stid(int a, int& s, int& t) const {
+      if ((a & 1) == 1) {
+        _uvid(a >> 1, s, t);
+      } else {
+        _uvid(a >> 1, t, s);
+      }
+    }
+
+    int _eid(int u, int v) const {
+      if (u < (_node_num - 1) / 2) {
+        return u * _node_num + v;
+      } else {
+        return (_node_num - 1 - u) * _node_num - v - 1;
+      }
+    }
+
+  public:
+
+    Node operator()(int ix) const { return Node(ix); }
+    static int index(const Node& node) { return node._id; }
+
+    Edge edge(const Node& u, const Node& v) const {
+      if (u._id < v._id) {
+        return Edge(_eid(u._id, v._id));
+      } else if (u._id != v._id) {
+        return Edge(_eid(v._id, u._id));
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc arc(const Node& s, const Node& t) const {
+      if (s._id < t._id) {
+        return Arc((_eid(s._id, t._id) << 1) | 1);
+      } else if (s._id != t._id) {
+        return Arc(_eid(t._id, s._id) << 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+    typedef True EdgeNumTag;
+
+    int nodeNum() const { return _node_num; }
+    int arcNum() const { return 2 * _edge_num; }
+    int edgeNum() const { return _edge_num; }
+
+    static int id(Node node) { return node._id; }
+    static int id(Arc arc) { return arc._id; }
+    static int id(Edge edge) { return edge._id; }
+
+    int maxNodeId() const { return _node_num-1; }
+    int maxArcId() const { return 2 * _edge_num-1; }
+    int maxEdgeId() const { return _edge_num-1; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    Node u(Edge edge) const {
+      return Node(_uid(edge._id));
+    }
+
+    Node v(Edge edge) const {
+      return Node(_vid(edge._id));
+    }
+
+    Node source(Arc arc) const {
+      return Node((arc._id & 1) == 1 ?
+                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
+    }
+
+    Node target(Arc arc) const {
+      return Node((arc._id & 1) == 1 ?
+                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
+    }
+
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      return prev != INVALID ? INVALID : edge(u, v);
+    }
+
+    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
+      return prev != INVALID ? INVALID : arc(s, t);
+    }
+
+    class Node {
+      friend class FullGraphBase;
+
+    protected:
+      int _id;
+      Node(int id) : _id(id) {}
+    public:
+      Node() {}
+      Node (Invalid) { _id = -1; }
+      bool operator==(const Node node) const {return _id == node._id;}
+      bool operator!=(const Node node) const {return _id != node._id;}
+      bool operator<(const Node node) const {return _id < node._id;}
+    };
+
+    class Edge {
+      friend class FullGraphBase;
+      friend class Arc;
+
+    protected:
+      int _id;
+
+      Edge(int id) : _id(id) {}
+
+    public:
+      Edge() { }
+      Edge (Invalid) { _id = -1; }
+
+      bool operator==(const Edge edge) const {return _id == edge._id;}
+      bool operator!=(const Edge edge) const {return _id != edge._id;}
+      bool operator<(const Edge edge) const {return _id < edge._id;}
+    };
+
+    class Arc {
+      friend class FullGraphBase;
+
+    protected:
+      int _id;
+
+      Arc(int id) : _id(id) {}
+
+    public:
+      Arc() { }
+      Arc (Invalid) { _id = -1; }
+
+      operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
+
+      bool operator==(const Arc arc) const {return _id == arc._id;}
+      bool operator!=(const Arc arc) const {return _id != arc._id;}
+      bool operator<(const Arc arc) const {return _id < arc._id;}
+    };
+
+    static bool direction(Arc arc) {
+      return (arc._id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc((edge._id << 1) | (dir ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = (_edge_num << 1) - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void first(Edge& edge) const {
+      edge._id = _edge_num - 1;
+    }
+
+    static void next(Edge& edge) {
+      --edge._id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      int s = node._id, t = _node_num - 1;
+      if (s < t) {
+        arc._id = (_eid(s, t) << 1) | 1;
+      } else {
+        --t;
+        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
+      }
+    }
+
+    void nextOut(Arc& arc) const {
+      int s, t;
+      _stid(arc._id, s, t);
+      --t;
+      if (s < t) {
+        arc._id = (_eid(s, t) << 1) | 1;
+      } else {
+        if (s == t) --t;
+        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
+      }
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      int s = _node_num - 1, t = node._id;
+      if (s > t) {
+        arc._id = (_eid(t, s) << 1);
+      } else {
+        --s;
+        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
+      }
+    }
+
+    void nextIn(Arc& arc) const {
+      int s, t;
+      _stid(arc._id, s, t);
+      --s;
+      if (s > t) {
+        arc._id = (_eid(t, s) << 1);
+      } else {
+        if (s == t) --s;
+        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
+      }
+    }
+
+    void firstInc(Edge& edge, bool& dir, const Node& node) const {
+      int u = node._id, v = _node_num - 1;
+      if (u < v) {
+        edge._id = _eid(u, v);
+        dir = true;
+      } else {
+        --v;
+        edge._id = (v != -1 ? _eid(v, u) : -1);
+        dir = false;
+      }
+    }
+
+    void nextInc(Edge& edge, bool& dir) const {
+      int u, v;
+      if (dir) {
+        _uvid(edge._id, u, v);
+        --v;
+        if (u < v) {
+          edge._id = _eid(u, v);
+        } else {
+          --v;
+          edge._id = (v != -1 ? _eid(v, u) : -1);
+          dir = false;
+        }
+      } else {
+        _uvid(edge._id, v, u);
+        --v;
+        edge._id = (v != -1 ? _eid(v, u) : -1);
+      }
+    }
+
+  };
+
+  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief An undirected full graph class.
+  ///
+  /// 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 this class does not contain a loop for each
+  /// node as FullDigraph does.
+  ///
+  /// \sa FullDigraph
+  class FullGraph : public ExtendedFullGraphBase {
+    typedef ExtendedFullGraphBase Parent;
+
+  public:
+
+    /// \brief Default constructor.
+    ///
+    /// Default constructor. The number of nodes and edges will be zero.
+    FullGraph() { construct(0); }
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param n The number of the nodes.
+    FullGraph(int n) { construct(n); }
+
+    /// \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 n) {
+      Parent::notifier(Arc()).clear();
+      Parent::notifier(Edge()).clear();
+      Parent::notifier(Node()).clear();
+      construct(n);
+      Parent::notifier(Node()).build();
+      Parent::notifier(Edge()).build();
+      Parent::notifier(Arc()).build();
+    }
+
+    /// \brief Returns the node with the given index.
+    ///
+    /// Returns the node with the given index. Since 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); }
+
+    /// \brief Returns the index of the given 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(Node s, Node t) const {
+      return Parent::arc(s, t);
+    }
+
+    /// \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);
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of arcs.
+    int arcNum() const { return Parent::arcNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
+
+  };
+
+  class FullBpGraphBase {
+
+  protected:
+
+    int _red_num, _blue_num;
+    int _node_num, _edge_num;
+
+  public:
+
+    typedef FullBpGraphBase Graph;
+
+    class Node;
+    class Arc;
+    class Edge;
+
+    class Node {
+      friend class FullBpGraphBase;
+    protected:
+
+      int _id;
+      explicit 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 RedNode : public Node {
+      friend class FullBpGraphBase;
+    protected:
+
+      explicit RedNode(int pid) : Node(pid) {}
+
+    public:
+      RedNode() {}
+      RedNode(const RedNode& node) : Node(node) {}
+      RedNode(Invalid) : Node(INVALID){}
+    };
+
+    class BlueNode : public Node {
+      friend class FullBpGraphBase;
+    protected:
+
+      explicit BlueNode(int pid) : Node(pid) {}
+
+    public:
+      BlueNode() {}
+      BlueNode(const BlueNode& node) : Node(node) {}
+      BlueNode(Invalid) : Node(INVALID){}
+    };
+
+    class Edge {
+      friend class FullBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Edge(int id) { _id = id;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { _id = -1; }
+      bool operator==(const Edge& arc) const {return _id == arc._id;}
+      bool operator!=(const Edge& arc) const {return _id != arc._id;}
+      bool operator<(const Edge& arc) const {return _id < arc._id;}
+    };
+
+    class Arc {
+      friend class FullBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Arc(int id) { _id = id;}
+
+    public:
+      operator Edge() const {
+        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
+      }
+
+      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;}
+    };
+
+
+  protected:
+
+    FullBpGraphBase()
+      : _red_num(0), _blue_num(0), _node_num(0), _edge_num(0) {}
+
+    void construct(int redNum, int blueNum) {
+      _red_num = redNum; _blue_num = blueNum;
+      _node_num = redNum + blueNum; _edge_num = redNum * blueNum;
+    }
+
+  public:
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return _node_num; }
+    int redNum() const { return _red_num; }
+    int blueNum() const { return _blue_num; }
+    int edgeNum() const { return _edge_num; }
+    int arcNum() const { return 2 * _edge_num; }
+
+    int maxNodeId() const { return _node_num - 1; }
+    int maxRedId() const { return _red_num - 1; }
+    int maxBlueId() const { return _blue_num - 1; }
+    int maxEdgeId() const { return _edge_num - 1; }
+    int maxArcId() const { return 2 * _edge_num - 1; }
+
+    bool red(Node n) const { return n._id < _red_num; }
+    bool blue(Node n) const { return n._id >= _red_num; }
+
+    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
+    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
+
+    Node source(Arc a) const {
+      if (a._id & 1) {
+        return Node((a._id >> 1) % _red_num);
+      } else {
+        return Node((a._id >> 1) / _red_num + _red_num);
+      }
+    }
+    Node target(Arc a) const {
+      if (a._id & 1) {
+        return Node((a._id >> 1) / _red_num + _red_num);
+      } else {
+        return Node((a._id >> 1) % _red_num);
+      }
+    }
+
+    RedNode redNode(Edge e) const {
+      return RedNode(e._id % _red_num);
+    }
+    BlueNode blueNode(Edge e) const {
+      return BlueNode(e._id / _red_num + _red_num);
+    }
+
+    static bool direction(Arc a) {
+      return (a._id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e._id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(RedNode& node) const {
+      node._id = _red_num - 1;
+    }
+
+    static void next(RedNode& node) {
+      --node._id;
+    }
+
+    void first(BlueNode& node) const {
+      if (_red_num == _node_num) node._id = -1;
+      else node._id = _node_num - 1;
+    }
+
+    void next(BlueNode& node) const {
+      if (node._id == _red_num) node._id = -1;
+      else --node._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = 2 * _edge_num - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void first(Edge& arc) const {
+      arc._id = _edge_num - 1;
+    }
+
+    static void next(Edge& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc &a, const Node& v) const {
+      if (v._id < _red_num) {
+        a._id = 2 * (v._id + _red_num * (_blue_num - 1)) + 1;
+      } else {
+        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num));
+      }
+    }
+    void nextOut(Arc &a) const {
+      if (a._id & 1) {
+        a._id -= 2 * _red_num;
+        if (a._id < 0) a._id = -1;
+      } else {
+        if (a._id % (2 * _red_num) == 0) a._id = -1;
+        else a._id -= 2;
+      }
+    }
+
+    void firstIn(Arc &a, const Node& v) const {
+      if (v._id < _red_num) {
+        a._id = 2 * (v._id + _red_num * (_blue_num - 1));
+      } else {
+        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)) + 1;
+      }
+    }
+    void nextIn(Arc &a) const {
+      if (a._id & 1) {
+        if (a._id % (2 * _red_num) == 1) a._id = -1;
+        else a._id -= 2;
+      } else {
+        a._id -= 2 * _red_num;
+        if (a._id < 0) a._id = -1;
+      }
+    }
+
+    void firstInc(Edge &e, bool& d, const Node& v) const {
+      if (v._id < _red_num) {
+        d = true;
+        e._id = v._id + _red_num * (_blue_num - 1);
+      } else {
+        d = false;
+        e._id = _red_num - 1 + _red_num * (v._id - _red_num);
+      }
+    }
+    void nextInc(Edge &e, bool& d) const {
+      if (d) {
+        e._id -= _red_num;
+        if (e._id < 0) e._id = -1;
+      } else {
+        if (e._id % _red_num == 0) e._id = -1;
+        else --e._id;
+      }
+    }
+
+    static int id(const Node& v) { return v._id; }
+    int id(const RedNode& v) const { return v._id; }
+    int id(const BlueNode& v) const { return v._id - _red_num; }
+    static int id(Arc e) { return e._id; }
+    static int id(Edge e) { return e._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n._id >= 0 && n._id < _node_num;
+    }
+    bool valid(Arc a) const {
+      return a._id >= 0 && a._id < 2 * _edge_num;
+    }
+    bool valid(Edge e) const {
+      return e._id >= 0 && e._id < _edge_num;
+    }
+
+    RedNode redNode(int index) const {
+      return RedNode(index);
+    }
+
+    int index(RedNode n) const {
+      return n._id;
+    }
+
+    BlueNode blueNode(int index) const {
+      return BlueNode(index + _red_num);
+    }
+
+    int index(BlueNode n) const {
+      return n._id - _red_num;
+    }
+
+    void clear() {
+      _red_num = 0; _blue_num = 0;
+      _node_num = 0; _edge_num = 0;
+    }
+
+    Edge edge(const Node& u, const Node& v) const {
+      if (u._id < _red_num) {
+        if (v._id < _red_num) {
+          return Edge(-1);
+        } else {
+          return Edge(u._id + _red_num * (v._id - _red_num));
+        }
+      } else {
+        if (v._id < _red_num) {
+          return Edge(v._id + _red_num * (u._id - _red_num));
+        } else {
+          return Edge(-1);
+        }
+      }
+    }
+
+    Arc arc(const Node& u, const Node& v) const {
+      if (u._id < _red_num) {
+        if (v._id < _red_num) {
+          return Arc(-1);
+        } else {
+          return Arc(2 * (u._id + _red_num * (v._id - _red_num)) + 1);
+        }
+      } else {
+        if (v._id < _red_num) {
+          return Arc(2 * (v._id + _red_num * (u._id - _red_num)));
+        } else {
+          return Arc(-1);
+        }
+      }
+    }
+
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      return prev != INVALID ? INVALID : edge(u, v);
+    }
+
+    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
+      return prev != INVALID ? INVALID : arc(s, t);
+    }
+
+  };
+
+  typedef BpGraphExtender<FullBpGraphBase> ExtendedFullBpGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief An undirected full bipartite graph class.
+  ///
+  /// FullBpGraph is a simple and fast implmenetation of undirected
+  /// full bipartite graphs. It contains an edge between every
+  /// red-blue pairs of nodes, therefore the number of edges is
+  /// <tt>nr*nb</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::BpGraph "BpGraph 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.
+  ///
+  /// \sa FullGraph
+  class FullBpGraph : public ExtendedFullBpGraphBase {
+  public:
+
+    typedef ExtendedFullBpGraphBase Parent;
+
+    /// \brief Default constructor.
+    ///
+    /// Default constructor. The number of nodes and edges will be zero.
+    FullBpGraph() { construct(0, 0); }
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param redNum The number of the red nodes.
+    /// \param blueNum The number of the blue nodes.
+    FullBpGraph(int redNum, int blueNum) { construct(redNum, blueNum); }
+
+    /// \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 redNum, int blueNum) {
+      Parent::notifier(Arc()).clear();
+      Parent::notifier(Edge()).clear();
+      Parent::notifier(Node()).clear();
+      Parent::notifier(BlueNode()).clear();
+      Parent::notifier(RedNode()).clear();
+      construct(redNum, blueNum);
+      Parent::notifier(RedNode()).build();
+      Parent::notifier(BlueNode()).build();
+      Parent::notifier(Node()).build();
+      Parent::notifier(Edge()).build();
+      Parent::notifier(Arc()).build();
+    }
+
+    using Parent::redNode;
+    using Parent::blueNode;
+
+    /// \brief Returns the red node with the given index.
+    ///
+    /// Returns the red node with the given index. Since this
+    /// structure is completely static, the red nodes can be indexed
+    /// with integers from the range <tt>[0..redNum()-1]</tt>.
+    /// \sa redIndex()
+    RedNode redNode(int index) const { return Parent::redNode(index); }
+
+    /// \brief Returns the index of the given red node.
+    ///
+    /// Returns the index of the given red node. Since this structure
+    /// is completely static, the red nodes can be indexed with
+    /// integers from the range <tt>[0..redNum()-1]</tt>.
+    ///
+    /// \sa operator()()
+    int index(RedNode node) const { return Parent::index(node); }
+
+    /// \brief Returns the blue node with the given index.
+    ///
+    /// Returns the blue node with the given index. Since this
+    /// structure is completely static, the blue nodes can be indexed
+    /// with integers from the range <tt>[0..blueNum()-1]</tt>.
+    /// \sa blueIndex()
+    BlueNode blueNode(int index) const { return Parent::blueNode(index); }
+
+    /// \brief Returns the index of the given blue node.
+    ///
+    /// Returns the index of the given blue node. Since this structure
+    /// is completely static, the blue nodes can be indexed with
+    /// integers from the range <tt>[0..blueNum()-1]</tt>.
+    ///
+    /// \sa operator()()
+    int index(BlueNode node) const { return Parent::index(node); }
+
+    /// \brief Returns the edge which connects the given nodes.
+    ///
+    /// Returns the edge which connects the given nodes.
+    Edge edge(const Node& u, const Node& v) const {
+      return Parent::edge(u, v);
+    }
+
+    /// \brief Returns the arc which connects the given nodes.
+    ///
+    /// Returns the arc which connects the given nodes.
+    Arc arc(const Node& u, const Node& v) const {
+      return Parent::arc(u, v);
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of red nodes.
+    int redNum() const { return Parent::redNum(); }
+    /// \brief Number of blue nodes.
+    int blueNum() const { return Parent::blueNum(); }
+    /// \brief Number of arcs.
+    int arcNum() const { return Parent::arcNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
+  };
+
+
+} //namespace lemon
+
+
+#endif //LEMON_FULL_GRAPH_H
diff --git a/lemon/glpk.cc b/lemon/glpk.cc
new file mode 100644
index 0000000..38d8115
--- /dev/null
+++ b/lemon/glpk.cc
@@ -0,0 +1,1012 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
+
+#include <lemon/glpk.h>
+#include <glpk.h>
+
+#include <lemon/assert.h>
+
+namespace lemon {
+
+  // GlpkBase members
+
+  GlpkBase::GlpkBase() : LpBase() {
+    lp = glp_create_prob();
+    glp_create_index(lp);
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
+    lp = glp_create_prob();
+    glp_copy_prob(lp, other.lp, GLP_ON);
+    glp_create_index(lp);
+    rows = other.rows;
+    cols = other.cols;
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  GlpkBase::~GlpkBase() {
+    glp_delete_prob(lp);
+  }
+
+  int GlpkBase::_addCol() {
+    int i = glp_add_cols(lp, 1);
+    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  int GlpkBase::_addRow() {
+    int i = glp_add_rows(lp, 1);
+    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  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;
+  }
+
+  void GlpkBase::_eraseCol(int i) {
+    int ca[2];
+    ca[1] = i;
+    glp_del_cols(lp, 1, ca);
+  }
+
+  void GlpkBase::_eraseRow(int i) {
+    int ra[2];
+    ra[1] = i;
+    glp_del_rows(lp, 1, ra);
+  }
+
+  void GlpkBase::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+
+  void GlpkBase::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void GlpkBase::_getColName(int c, std::string& name) const {
+    const char *str = glp_get_col_name(lp, c);
+    if (str) name = str;
+    else name.clear();
+  }
+
+  void GlpkBase::_setColName(int c, const std::string & name) {
+    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
+
+  }
+
+  int GlpkBase::_colByName(const std::string& name) const {
+    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
+    return k > 0 ? k : -1;
+  }
+
+  void GlpkBase::_getRowName(int r, std::string& name) const {
+    const char *str = glp_get_row_name(lp, r);
+    if (str) name = str;
+    else name.clear();
+  }
+
+  void GlpkBase::_setRowName(int r, const std::string & name) {
+    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
+
+  }
+
+  int GlpkBase::_rowByName(const std::string& name) const {
+    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
+    return k > 0 ? k : -1;
+  }
+
+  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    indexes.push_back(0);
+    values.push_back(0);
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    glp_set_mat_row(lp, i, values.size() - 1,
+                    &indexes.front(), &values.front());
+  }
+
+  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
+    int length = glp_get_mat_row(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i <= length; ++i) {
+      *b = std::make_pair(indexes[i], values[i]);
+      ++b;
+    }
+  }
+
+  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
+                                     ExprIterator e) {
+
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    indexes.push_back(0);
+    values.push_back(0);
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    glp_set_mat_col(lp, ix, values.size() - 1,
+                    &indexes.front(), &values.front());
+  }
+
+  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
+    int length = glp_get_mat_col(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i  <= length; ++i) {
+      *b = std::make_pair(indexes[i], values[i]);
+      ++b;
+    }
+  }
+
+  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
+
+    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
+
+      int length = glp_get_mat_row(lp, ix, 0, 0);
+
+      std::vector<int> indexes(length + 2);
+      std::vector<Value> values(length + 2);
+
+      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+      //The following code does not suppose that the elements of the
+      //array indexes are sorted
+      bool found = false;
+      for (int i = 1; i  <= length; ++i) {
+        if (indexes[i] == jx) {
+          found = true;
+          values[i] = value;
+          break;
+        }
+      }
+      if (!found) {
+        ++length;
+        indexes[length] = jx;
+        values[length] = value;
+      }
+
+      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
+
+    } else {
+
+      int length = glp_get_mat_col(lp, jx, 0, 0);
+
+      std::vector<int> indexes(length + 2);
+      std::vector<Value> values(length + 2);
+
+      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
+
+      //The following code does not suppose that the elements of the
+      //array indexes are sorted
+      bool found = false;
+      for (int i = 1; i <= length; ++i) {
+        if (indexes[i] == ix) {
+          found = true;
+          values[i] = value;
+          break;
+        }
+      }
+      if (!found) {
+        ++length;
+        indexes[length] = ix;
+        values[length] = value;
+      }
+
+      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
+
+    int length = glp_get_mat_row(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i  <= length; ++i) {
+      if (indexes[i] == jx) {
+        return values[i];
+      }
+    }
+
+    return 0;
+  }
+
+  void GlpkBase::_setColLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+
+    int b = glp_get_col_type(lp, i);
+    double up = glp_get_col_ub(lp, i);
+    if (lo == -INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_UP:
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
+    int b = glp_get_col_type(lp, i);
+    switch (b) {
+    case GLP_LO:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_col_lb(lp, i);
+    default:
+      return -INF;
+    }
+  }
+
+  void GlpkBase::_setColUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+
+    int b = glp_get_col_type(lp, i);
+    double lo = glp_get_col_lb(lp, i);
+    if (up == INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        break;
+      case GLP_UP:
+        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_UP:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_LO:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
+    int b = glp_get_col_type(lp, i);
+      switch (b) {
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        return glp_get_col_ub(lp, i);
+      default:
+        return INF;
+      }
+  }
+
+  void GlpkBase::_setRowLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+
+    int b = glp_get_row_type(lp, i);
+    double up = glp_get_row_ub(lp, i);
+    if (lo == -INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_UP:
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
+    int b = glp_get_row_type(lp, i);
+    switch (b) {
+    case GLP_LO:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_row_lb(lp, i);
+    default:
+      return -INF;
+    }
+  }
+
+  void GlpkBase::_setRowUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+
+    int b = glp_get_row_type(lp, i);
+    double lo = glp_get_row_lb(lp, i);
+    if (up == INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        break;
+      case GLP_UP:
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_UP:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_LO:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
+    int b = glp_get_row_type(lp, i);
+    switch (b) {
+    case GLP_UP:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_row_ub(lp, i);
+    default:
+      return INF;
+    }
+  }
+
+  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
+      glp_set_obj_coef(lp, i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      glp_set_obj_coef(lp, it->first, it->second);
+    }
+  }
+
+  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
+    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
+      Value val = glp_get_obj_coef(lp, i);
+      if (val != 0.0) {
+        *b = std::make_pair(i, val);
+        ++b;
+      }
+    }
+  }
+
+  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
+    //i = 0 means the constant term (shift)
+    glp_set_obj_coef(lp, i, obj_coef);
+  }
+
+  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
+    //i = 0 means the constant term (shift)
+    return glp_get_obj_coef(lp, i);
+  }
+
+  void GlpkBase::_setSense(GlpkBase::Sense sense) {
+    switch (sense) {
+    case MIN:
+      glp_set_obj_dir(lp, GLP_MIN);
+      break;
+    case MAX:
+      glp_set_obj_dir(lp, GLP_MAX);
+      break;
+    }
+  }
+
+  GlpkBase::Sense GlpkBase::_getSense() const {
+    switch(glp_get_obj_dir(lp)) {
+    case GLP_MIN:
+      return MIN;
+    case GLP_MAX:
+      return MAX;
+    default:
+      LEMON_ASSERT(false, "Wrong sense");
+      return GlpkBase::Sense();
+    }
+  }
+
+  void GlpkBase::_clear() {
+    glp_erase_prob(lp);
+  }
+
+  void GlpkBase::freeEnv() {
+    glp_free_env();
+  }
+
+  void GlpkBase::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _message_level = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR:
+      _message_level = GLP_MSG_ERR;
+      break;
+    case MESSAGE_WARNING:
+      _message_level = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL:
+      _message_level = GLP_MSG_ON;
+      break;
+    case MESSAGE_VERBOSE:
+      _message_level = GLP_MSG_ALL;
+      break;
+    }
+  }
+
+  void GlpkBase::_write(std::string file, std::string format) const
+  {
+    if(format == "MPS")
+      glp_write_mps(lp, GLP_MPS_FILE, 0, file.c_str());
+    else if(format == "LP")
+      glp_write_lp(lp, 0, file.c_str());
+    else throw UnsupportedFormatError(format);
+  }
+
+  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
+
+  // GlpkLp members
+
+  GlpkLp::GlpkLp()
+    : LpBase(), LpSolver(), GlpkBase() {
+    presolver(false);
+  }
+
+  GlpkLp::GlpkLp(const GlpkLp& other)
+    : LpBase(other), LpSolver(other), GlpkBase(other) {
+    presolver(false);
+  }
+
+  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
+  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
+
+  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
+
+  void GlpkLp::_clear_temporals() {
+    _primal_ray.clear();
+    _dual_ray.clear();
+  }
+
+  GlpkLp::SolveExitStatus GlpkLp::_solve() {
+    return solvePrimal();
+  }
+
+  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
+    _clear_temporals();
+
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    smcp.msg_lev = _message_level;
+    smcp.presolve = _presolve;
+
+    // If the basis is not valid we get an error return value.
+    // In this case we can try to create a new basis.
+    switch (glp_simplex(lp, &smcp)) {
+    case 0:
+      break;
+    case GLP_EBADB:
+    case GLP_ESING:
+    case GLP_ECOND:
+      glp_term_out(false);
+      glp_adv_basis(lp, 0);
+      glp_term_out(true);
+      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+      break;
+    default:
+      return UNSOLVED;
+    }
+
+    return SOLVED;
+  }
+
+  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
+    _clear_temporals();
+
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    smcp.msg_lev = _message_level;
+    smcp.meth = GLP_DUAL;
+    smcp.presolve = _presolve;
+
+    // If the basis is not valid we get an error return value.
+    // In this case we can try to create a new basis.
+    switch (glp_simplex(lp, &smcp)) {
+    case 0:
+      break;
+    case GLP_EBADB:
+    case GLP_ESING:
+    case GLP_ECOND:
+      glp_term_out(false);
+      glp_adv_basis(lp, 0);
+      glp_term_out(true);
+      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+      break;
+    default:
+      return UNSOLVED;
+    }
+    return SOLVED;
+  }
+
+  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
+    return glp_get_col_prim(lp, i);
+  }
+
+  GlpkLp::Value GlpkLp::_getDual(int i) const {
+    return glp_get_row_dual(lp, i);
+  }
+
+  GlpkLp::Value GlpkLp::_getPrimalValue() const {
+    return glp_get_obj_val(lp);
+  }
+
+  GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
+    switch (glp_get_col_stat(lp, i)) {
+    case GLP_BS:
+      return BASIC;
+    case GLP_UP:
+      return UPPER;
+    case GLP_LO:
+      return LOWER;
+    case GLP_NF:
+      return FREE;
+    case GLP_NS:
+      return FIXED;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return GlpkLp::VarStatus();
+    }
+  }
+
+  GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const {
+    switch (glp_get_row_stat(lp, i)) {
+    case GLP_BS:
+      return BASIC;
+    case GLP_UP:
+      return UPPER;
+    case GLP_LO:
+      return LOWER;
+    case GLP_NF:
+      return FREE;
+    case GLP_NS:
+      return FIXED;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return GlpkLp::VarStatus();
+    }
+  }
+
+  GlpkLp::Value GlpkLp::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      int row_num = glp_get_num_rows(lp);
+      int col_num = glp_get_num_cols(lp);
+
+      _primal_ray.resize(col_num + 1, 0.0);
+
+      int index = glp_get_unbnd_ray(lp);
+      if (index != 0) {
+        // The primal ray is found in primal simplex second phase
+        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
+                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
+                     "Wrong primal ray");
+
+        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
+
+        if (index > row_num) {
+          _primal_ray[index - row_num] = 1.0;
+          if (glp_get_col_dual(lp, index - row_num) > 0) {
+            negate = !negate;
+          }
+        } else {
+          if (glp_get_row_dual(lp, index) > 0) {
+            negate = !negate;
+          }
+        }
+
+        std::vector<int> ray_indexes(row_num + 1);
+        std::vector<Value> ray_values(row_num + 1);
+        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
+                                          &ray_values.front());
+
+        for (int i = 1; i <= ray_length; ++i) {
+          if (ray_indexes[i] > row_num) {
+            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
+          }
+        }
+
+        if (negate) {
+          for (int i = 1; i <= col_num; ++i) {
+            _primal_ray[i] = - _primal_ray[i];
+          }
+        }
+      } else {
+        for (int i = 1; i <= col_num; ++i) {
+          _primal_ray[i] = glp_get_col_prim(lp, i);
+        }
+      }
+    }
+    return _primal_ray[i];
+  }
+
+  GlpkLp::Value GlpkLp::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+      int row_num = glp_get_num_rows(lp);
+
+      _dual_ray.resize(row_num + 1, 0.0);
+
+      int index = glp_get_unbnd_ray(lp);
+      if (index != 0) {
+        // The dual ray is found in dual simplex second phase
+        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
+                      glp_get_col_stat(lp, index - row_num)) == GLP_BS,
+
+                     "Wrong dual ray");
+
+        int idx;
+        bool negate = false;
+
+        if (index > row_num) {
+          idx = glp_get_col_bind(lp, index - row_num);
+          if (glp_get_col_prim(lp, index - row_num) >
+              glp_get_col_ub(lp, index - row_num)) {
+            negate = true;
+          }
+        } else {
+          idx = glp_get_row_bind(lp, index);
+          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
+            negate = true;
+          }
+        }
+
+        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
+
+        glp_btran(lp, &_dual_ray.front());
+      } else {
+        double eps = 1e-7;
+        // The dual ray is found in primal simplex first phase
+        // We assume that the glpk minimizes the slack to get feasible solution
+        for (int i = 1; i <= row_num; ++i) {
+          int index = glp_get_bhead(lp, i);
+          if (index <= row_num) {
+            double res = glp_get_row_prim(lp, index);
+            if (res > glp_get_row_ub(lp, index) + eps) {
+              _dual_ray[i] = -1;
+            } else if (res < glp_get_row_lb(lp, index) - eps) {
+              _dual_ray[i] = 1;
+            } else {
+              _dual_ray[i] = 0;
+            }
+            _dual_ray[i] *= glp_get_rii(lp, index);
+          } else {
+            double res = glp_get_col_prim(lp, index - row_num);
+            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
+              _dual_ray[i] = -1;
+            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
+              _dual_ray[i] = 1;
+            } else {
+              _dual_ray[i] = 0;
+            }
+            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
+          }
+        }
+
+        glp_btran(lp, &_dual_ray.front());
+
+        for (int i = 1; i <= row_num; ++i) {
+          _dual_ray[i] /= glp_get_rii(lp, i);
+        }
+      }
+    }
+    return _dual_ray[i];
+  }
+
+  GlpkLp::ProblemType GlpkLp::_getPrimalType() const {
+    if (glp_get_status(lp) == GLP_OPT)
+      return OPTIMAL;
+    switch (glp_get_prim_stat(lp)) {
+    case GLP_UNDEF:
+      return UNDEFINED;
+    case GLP_FEAS:
+    case GLP_INFEAS:
+      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    default:
+      LEMON_ASSERT(false, "Wrong primal type");
+      return  GlpkLp::ProblemType();
+    }
+  }
+
+  GlpkLp::ProblemType GlpkLp::_getDualType() const {
+    if (glp_get_status(lp) == GLP_OPT)
+      return OPTIMAL;
+    switch (glp_get_dual_stat(lp)) {
+    case GLP_UNDEF:
+      return UNDEFINED;
+    case GLP_FEAS:
+    case GLP_INFEAS:
+      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    default:
+      LEMON_ASSERT(false, "Wrong primal type");
+      return  GlpkLp::ProblemType();
+    }
+  }
+
+  void GlpkLp::presolver(bool presolve) {
+    _presolve = presolve;
+  }
+
+  // GlpkMip members
+
+  GlpkMip::GlpkMip()
+    : LpBase(), MipSolver(), GlpkBase() {
+  }
+
+  GlpkMip::GlpkMip(const GlpkMip& other)
+    : LpBase(), MipSolver(), GlpkBase(other) {
+  }
+
+  void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
+    switch (col_type) {
+    case INTEGER:
+      glp_set_col_kind(lp, i, GLP_IV);
+      break;
+    case REAL:
+      glp_set_col_kind(lp, i, GLP_CV);
+      break;
+    }
+  }
+
+  GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
+    switch (glp_get_col_kind(lp, i)) {
+    case GLP_IV:
+    case GLP_BV:
+      return INTEGER;
+    default:
+      return REAL;
+    }
+
+  }
+
+  GlpkMip::SolveExitStatus GlpkMip::_solve() {
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    smcp.msg_lev = _message_level;
+    smcp.meth = GLP_DUAL;
+
+    // If the basis is not valid we get an error return value.
+    // In this case we can try to create a new basis.
+    switch (glp_simplex(lp, &smcp)) {
+    case 0:
+      break;
+    case GLP_EBADB:
+    case GLP_ESING:
+    case GLP_ECOND:
+      glp_term_out(false);
+      glp_adv_basis(lp, 0);
+      glp_term_out(true);
+      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+      break;
+    default:
+      return UNSOLVED;
+    }
+
+    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
+
+    glp_iocp iocp;
+    glp_init_iocp(&iocp);
+
+    iocp.msg_lev = _message_level;
+
+    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+
+  GlpkMip::ProblemType GlpkMip::_getType() const {
+    switch (glp_get_status(lp)) {
+    case GLP_OPT:
+      switch (glp_mip_status(lp)) {
+      case GLP_UNDEF:
+        return UNDEFINED;
+      case GLP_NOFEAS:
+        return INFEASIBLE;
+      case GLP_FEAS:
+        return FEASIBLE;
+      case GLP_OPT:
+        return OPTIMAL;
+      default:
+        LEMON_ASSERT(false, "Wrong problem type.");
+        return GlpkMip::ProblemType();
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    case GLP_INFEAS:
+    case GLP_FEAS:
+      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    default:
+      LEMON_ASSERT(false, "Wrong problem type.");
+      return GlpkMip::ProblemType();
+    }
+  }
+
+  GlpkMip::Value GlpkMip::_getSol(int i) const {
+    return glp_mip_col_val(lp, i);
+  }
+
+  GlpkMip::Value GlpkMip::_getSolValue() const {
+    return glp_mip_obj_val(lp);
+  }
+
+  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
+  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
+
+  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
+
+
+
+} //END OF NAMESPACE LEMON
diff --git a/lemon/glpk.h b/lemon/glpk.h
new file mode 100644
index 0000000..ccdc54a
--- /dev/null
+++ b/lemon/glpk.h
@@ -0,0 +1,263 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_GLPK_H
+#define LEMON_GLPK_H
+
+///\file
+///\brief Header of the LEMON-GLPK lp solver interface.
+///\ingroup lp_group
+
+#include <lemon/lp_base.h>
+
+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
+  ///
+  /// This class implements the common interface of the GLPK LP and MIP solver.
+  /// \ingroup lp_group
+  class GlpkBase : virtual public LpBase {
+  protected:
+
+    _solver_bits::VoidPtr lp;
+
+    GlpkBase();
+    GlpkBase(const GlpkBase&);
+    virtual ~GlpkBase();
+
+  protected:
+
+    virtual int _addCol();
+    virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense);
+    virtual Sense _getSense() const;
+
+    virtual void _clear();
+
+    virtual void _messageLevel(MessageLevel level);
+
+    virtual void _write(std::string file, std::string format) const;
+
+  private:
+
+    static void freeEnv();
+
+    struct FreeEnvHelper {
+      ~FreeEnvHelper() {
+        freeEnv();
+      }
+    };
+
+    static FreeEnvHelper freeEnvHelper;
+
+  protected:
+
+    int _message_level;
+
+  public:
+
+    ///Pointer to the underlying GLPK data structure.
+    _solver_bits::VoidPtr lpx() {return lp;}
+    ///Const pointer to the underlying GLPK data structure.
+    _solver_bits::VoidPtr lpx() const {return lp;}
+
+    ///Returns the constraint identifier understood by GLPK.
+    int lpxRow(Row r) const { return rows(id(r)); }
+
+    ///Returns the variable identifier understood by GLPK.
+    int lpxCol(Col c) const { return cols(id(c)); }
+
+#ifdef DOXYGEN
+    /// Write the problem or the solution to a file in the given format
+
+    /// This function writes the problem or the solution
+    /// to a file in the given format.
+    /// Trying to write in an unsupported format will trigger
+    /// \ref LpBase::UnsupportedFormatError.
+    /// \param file The file path
+    /// \param format The output file format.
+    /// Supportted formats are "MPS" and "LP".
+    void write(std::string file, std::string format = "MPS") const {}
+#endif
+
+  };
+
+  /// \brief Interface for the GLPK LP solver
+  ///
+  /// This class implements an interface for the GLPK LP solver.
+  ///\ingroup lp_group
+  class GlpkLp : public LpSolver, public GlpkBase {
+  public:
+
+    ///\e
+    GlpkLp();
+    ///\e
+    GlpkLp(const GlpkLp&);
+
+    ///\e
+    virtual GlpkLp* cloneSolver() const;
+    ///\e
+    virtual GlpkLp* newSolver() const;
+
+  private:
+
+    mutable std::vector<double> _primal_ray;
+    mutable std::vector<double> _dual_ray;
+
+    void _clear_temporals();
+
+  protected:
+
+    virtual const char* _solverName() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+  public:
+
+    ///Solve with primal simplex
+    SolveExitStatus solvePrimal();
+
+    ///Solve with dual simplex
+    SolveExitStatus solveDual();
+
+  private:
+
+    bool _presolve;
+
+  public:
+
+    ///Turns on or off the presolver
+
+    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
+    ///
+    ///The presolver is off by default.
+    void presolver(bool presolve);
+
+  };
+
+  /// \brief Interface for the GLPK MIP solver
+  ///
+  /// This class implements an interface for the GLPK MIP solver.
+  ///\ingroup lp_group
+  class GlpkMip : public MipSolver, public GlpkBase {
+  public:
+
+    ///\e
+    GlpkMip();
+    ///\e
+    GlpkMip(const GlpkMip&);
+
+    virtual GlpkMip* cloneSolver() const;
+    virtual GlpkMip* newSolver() const;
+
+  protected:
+
+    virtual const char* _solverName() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+  };
+
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_GLPK_H
+
diff --git a/lemon/gomory_hu.h b/lemon/gomory_hu.h
new file mode 100644
index 0000000..c43305f
--- /dev/null
+++ b/lemon/gomory_hu.h
@@ -0,0 +1,568 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_GOMORY_HU_TREE_H
+#define LEMON_GOMORY_HU_TREE_H
+
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/preflow.h>
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
+
+/// \ingroup min_cut
+/// \file
+/// \brief Gomory-Hu cut tree in graphs.
+
+namespace lemon {
+
+  /// \ingroup min_cut
+  ///
+  /// \brief Gomory-Hu cut tree algorithm
+  ///
+  /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
+  /// may contain edges which are not in the original graph. It has the
+  /// property that the minimum capacity edge of the path between two nodes
+  /// in this tree has the same weight as the minimum cut in the graph
+  /// between these nodes. Moreover the components obtained by removing
+  /// this edge from the tree determine the corresponding minimum cut.
+  /// Therefore once this tree is computed, the minimum cut between any pair
+  /// of nodes can easily be obtained.
+  ///
+  /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
+  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{m})\f$ overall
+  /// time complexity. It calculates a rooted Gomory-Hu tree.
+  /// The structure of the tree and the edge weights can be
+  /// obtained using \c predNode(), \c predValue() and \c rootDist().
+  /// The functions \c minCutMap() and \c minCutValue() calculate
+  /// the minimum cut and the minimum cut value between any two nodes
+  /// in the graph. You can also list (iterate on) the nodes and the
+  /// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt.
+  ///
+  /// \tparam GR The type of the undirected graph the algorithm runs on.
+  /// \tparam CAP The type of the edge map containing the capacities.
+  /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR,
+            typename CAP>
+#else
+  template <typename GR,
+            typename CAP = typename GR::template EdgeMap<int> >
+#endif
+  class GomoryHu {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The capacity map type of the algorithm
+    typedef CAP Capacity;
+    /// The value type of capacities
+    typedef typename Capacity::Value Value;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    const Graph& _graph;
+    const Capacity& _capacity;
+
+    Node _root;
+    typename Graph::template NodeMap<Node>* _pred;
+    typename Graph::template NodeMap<Value>* _weight;
+    typename Graph::template NodeMap<int>* _order;
+
+    void createStructures() {
+      if (!_pred) {
+        _pred = new typename Graph::template NodeMap<Node>(_graph);
+      }
+      if (!_weight) {
+        _weight = new typename Graph::template NodeMap<Value>(_graph);
+      }
+      if (!_order) {
+        _order = new typename Graph::template NodeMap<int>(_graph);
+      }
+    }
+
+    void destroyStructures() {
+      if (_pred) {
+        delete _pred;
+      }
+      if (_weight) {
+        delete _weight;
+      }
+      if (_order) {
+        delete _order;
+      }
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param graph The undirected graph the algorithm runs on.
+    /// \param capacity The edge capacity map.
+    GomoryHu(const Graph& graph, const Capacity& capacity)
+      : _graph(graph), _capacity(capacity),
+        _pred(0), _weight(0), _order(0)
+    {
+      checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
+    }
+
+
+    /// \brief Destructor
+    ///
+    /// Destructor.
+    ~GomoryHu() {
+      destroyStructures();
+    }
+
+  private:
+
+    // Initialize the internal data structures
+    void init() {
+      createStructures();
+
+      _root = NodeIt(_graph);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_pred)[n] = _root;
+        (*_order)[n] = -1;
+      }
+      (*_pred)[_root] = INVALID;
+      (*_weight)[_root] = std::numeric_limits<Value>::max();
+    }
+
+
+    // Start the algorithm
+    void start() {
+      Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (n == _root) continue;
+
+        Node pn = (*_pred)[n];
+        fa.source(n);
+        fa.target(pn);
+
+        fa.runMinCut();
+
+        (*_weight)[n] = fa.flowValue();
+
+        for (NodeIt nn(_graph); nn != INVALID; ++nn) {
+          if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
+            (*_pred)[nn] = n;
+          }
+        }
+        if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
+          (*_pred)[n] = (*_pred)[pn];
+          (*_pred)[pn] = n;
+          (*_weight)[n] = (*_weight)[pn];
+          (*_weight)[pn] = fa.flowValue();
+        }
+      }
+
+      (*_order)[_root] = 0;
+      int index = 1;
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        std::vector<Node> st;
+        Node nn = n;
+        while ((*_order)[nn] == -1) {
+          st.push_back(nn);
+          nn = (*_pred)[nn];
+        }
+        while (!st.empty()) {
+          (*_order)[st.back()] = index++;
+          st.pop_back();
+        }
+      }
+    }
+
+  public:
+
+    ///\name Execution Control
+
+    ///@{
+
+    /// \brief Run the Gomory-Hu algorithm.
+    ///
+    /// This function runs the Gomory-Hu algorithm.
+    void run() {
+      init();
+      start();
+    }
+
+    /// @}
+
+    ///\name Query Functions
+    ///The results of the algorithm can be obtained using these
+    ///functions.\n
+    ///\ref run() should be called before using them.\n
+    ///See also \ref MinCutNodeIt and \ref MinCutEdgeIt.
+
+    ///@{
+
+    /// \brief Return the predecessor node in the Gomory-Hu tree.
+    ///
+    /// This function returns the predecessor node of the given node
+    /// in the Gomory-Hu tree.
+    /// If \c node is the root of the tree, then it returns \c INVALID.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Node predNode(const Node& node) const {
+      return (*_pred)[node];
+    }
+
+    /// \brief Return the weight of the predecessor edge in the
+    /// Gomory-Hu tree.
+    ///
+    /// This function returns the weight of the predecessor edge of the
+    /// given node in the Gomory-Hu tree.
+    /// If \c node is the root of the tree, the result is undefined.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Value predValue(const Node& node) const {
+      return (*_weight)[node];
+    }
+
+    /// \brief Return the distance from the root node in the Gomory-Hu tree.
+    ///
+    /// This function returns the distance of the given node from the root
+    /// node in the Gomory-Hu tree.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    int rootDist(const Node& node) const {
+      return (*_order)[node];
+    }
+
+    /// \brief Return the minimum cut value between two nodes
+    ///
+    /// This function returns the minimum cut value between the nodes
+    /// \c s and \c t.
+    /// It finds the nearest common ancestor of the given nodes in the
+    /// Gomory-Hu tree and calculates the minimum weight edge on the
+    /// paths to the ancestor.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Value minCutValue(const Node& s, const Node& t) const {
+      Node sn = s, tn = t;
+      Value value = std::numeric_limits<Value>::max();
+
+      while (sn != tn) {
+        if ((*_order)[sn] < (*_order)[tn]) {
+          if ((*_weight)[tn] <= value) value = (*_weight)[tn];
+          tn = (*_pred)[tn];
+        } else {
+          if ((*_weight)[sn] <= value) value = (*_weight)[sn];
+          sn = (*_pred)[sn];
+        }
+      }
+      return value;
+    }
+
+    /// \brief Return the minimum cut between two nodes
+    ///
+    /// This function returns the minimum cut between the nodes \c s and \c t
+    /// in the \c cutMap parameter by setting the nodes in the component of
+    /// \c s to \c true and the other nodes to \c false.
+    ///
+    /// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt.
+    ///
+    /// \param s The base node.
+    /// \param t The node you want to separate from node \c s.
+    /// \param cutMap The cut will be returned in this map.
+    /// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap
+    /// "ReadWriteMap" on the graph nodes.
+    ///
+    /// \return The value of the minimum cut between \c s and \c t.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename CutMap>
+    Value minCutMap(const Node& s,
+                    const Node& t,
+                    CutMap& cutMap
+                    ) const {
+      Node sn = s, tn = t;
+      bool s_root=false;
+      Node rn = INVALID;
+      Value value = std::numeric_limits<Value>::max();
+
+      while (sn != tn) {
+        if ((*_order)[sn] < (*_order)[tn]) {
+          if ((*_weight)[tn] <= value) {
+            rn = tn;
+            s_root = false;
+            value = (*_weight)[tn];
+          }
+          tn = (*_pred)[tn];
+        } else {
+          if ((*_weight)[sn] <= value) {
+            rn = sn;
+            s_root = true;
+            value = (*_weight)[sn];
+          }
+          sn = (*_pred)[sn];
+        }
+      }
+
+      typename Graph::template NodeMap<bool> reached(_graph, false);
+      reached[_root] = true;
+      cutMap.set(_root, !s_root);
+      reached[rn] = true;
+      cutMap.set(rn, s_root);
+
+      std::vector<Node> st;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        st.clear();
+        Node nn = n;
+        while (!reached[nn]) {
+          st.push_back(nn);
+          nn = (*_pred)[nn];
+        }
+        while (!st.empty()) {
+          cutMap.set(st.back(), cutMap[nn]);
+          st.pop_back();
+        }
+      }
+
+      return value;
+    }
+
+    ///@}
+
+    friend class MinCutNodeIt;
+
+    /// Iterate on the nodes of a minimum cut
+
+    /// This iterator class lists the nodes of a minimum cut found by
+    /// GomoryHu. Before using it, you must allocate a GomoryHu class
+    /// and call its \ref GomoryHu::run() "run()" method.
+    ///
+    /// This example counts the nodes in the minimum cut separating \c s from
+    /// \c t.
+    /// \code
+    /// GomoryHu<Graph> gom(g, capacities);
+    /// gom.run();
+    /// int cnt=0;
+    /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
+    /// \endcode
+    class MinCutNodeIt
+    {
+      bool _side;
+      typename Graph::NodeIt _node_it;
+      typename Graph::template NodeMap<bool> _cut;
+    public:
+      /// Constructor
+
+      /// Constructor.
+      ///
+      MinCutNodeIt(GomoryHu const &gomory,
+                   ///< The GomoryHu class. You must call its
+                   ///  run() method
+                   ///  before initializing this iterator.
+                   const Node& s, ///< The base node.
+                   const Node& t,
+                   ///< The node you want to separate from node \c s.
+                   bool side=true
+                   ///< If it is \c true (default) then the iterator lists
+                   ///  the nodes of the component containing \c s,
+                   ///  otherwise it lists the other component.
+                   /// \note As the minimum cut is not always unique,
+                   /// \code
+                   /// MinCutNodeIt(gomory, s, t, true);
+                   /// \endcode
+                   /// and
+                   /// \code
+                   /// MinCutNodeIt(gomory, t, s, false);
+                   /// \endcode
+                   /// does not necessarily give the same set of nodes.
+                   /// However, it is ensured that
+                   /// \code
+                   /// MinCutNodeIt(gomory, s, t, true);
+                   /// \endcode
+                   /// and
+                   /// \code
+                   /// MinCutNodeIt(gomory, s, t, false);
+                   /// \endcode
+                   /// together list each node exactly once.
+                   )
+        : _side(side), _cut(gomory._graph)
+      {
+        gomory.minCutMap(s,t,_cut);
+        for(_node_it=typename Graph::NodeIt(gomory._graph);
+            _node_it!=INVALID && _cut[_node_it]!=_side;
+            ++_node_it) {}
+      }
+      /// Conversion to \c Node
+
+      /// Conversion to \c Node.
+      ///
+      operator typename Graph::Node() const
+      {
+        return _node_it;
+      }
+      bool operator==(Invalid) { return _node_it==INVALID; }
+      bool operator!=(Invalid) { return _node_it!=INVALID; }
+      /// Next node
+
+      /// Next node.
+      ///
+      MinCutNodeIt &operator++()
+      {
+        for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
+        return *this;
+      }
+      /// Postfix incrementation
+
+      /// Postfix incrementation.
+      ///
+      /// \warning This incrementation
+      /// returns a \c Node, not a \c MinCutNodeIt, as one may
+      /// expect.
+      typename Graph::Node operator++(int)
+      {
+        typename Graph::Node n=*this;
+        ++(*this);
+        return n;
+      }
+    };
+
+    friend class MinCutEdgeIt;
+
+    /// Iterate on the edges of a minimum cut
+
+    /// This iterator class lists the edges of a minimum cut found by
+    /// GomoryHu. Before using it, you must allocate a GomoryHu class
+    /// and call its \ref GomoryHu::run() "run()" method.
+    ///
+    /// This example computes the value of the minimum cut separating \c s from
+    /// \c t.
+    /// \code
+    /// GomoryHu<Graph> gom(g, capacities);
+    /// gom.run();
+    /// int value=0;
+    /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
+    ///   value+=capacities[e];
+    /// \endcode
+    /// The result will be the same as the value returned by
+    /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)".
+    class MinCutEdgeIt
+    {
+      bool _side;
+      const Graph &_graph;
+      typename Graph::NodeIt _node_it;
+      typename Graph::OutArcIt _arc_it;
+      typename Graph::template NodeMap<bool> _cut;
+      void step()
+      {
+        ++_arc_it;
+        while(_node_it!=INVALID && _arc_it==INVALID)
+          {
+            for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
+            if(_node_it!=INVALID)
+              _arc_it=typename Graph::OutArcIt(_graph,_node_it);
+          }
+      }
+
+    public:
+      /// Constructor
+
+      /// Constructor.
+      ///
+      MinCutEdgeIt(GomoryHu const &gomory,
+                   ///< The GomoryHu class. You must call its
+                   ///  run() method
+                   ///  before initializing this iterator.
+                   const Node& s,  ///< The base node.
+                   const Node& t,
+                   ///< The node you want to separate from node \c s.
+                   bool side=true
+                   ///< If it is \c true (default) then the listed arcs
+                   ///  will be oriented from the
+                   ///  nodes of the component containing \c s,
+                   ///  otherwise they will be oriented in the opposite
+                   ///  direction.
+                   )
+        : _graph(gomory._graph), _cut(_graph)
+      {
+        gomory.minCutMap(s,t,_cut);
+        if(!side)
+          for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
+            _cut[n]=!_cut[n];
+
+        for(_node_it=typename Graph::NodeIt(_graph);
+            _node_it!=INVALID && !_cut[_node_it];
+            ++_node_it) {}
+        _arc_it = _node_it!=INVALID ?
+          typename Graph::OutArcIt(_graph,_node_it) : INVALID;
+        while(_node_it!=INVALID && _arc_it == INVALID)
+          {
+            for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
+            if(_node_it!=INVALID)
+              _arc_it= typename Graph::OutArcIt(_graph,_node_it);
+          }
+        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
+      }
+      /// Conversion to \c Arc
+
+      /// Conversion to \c Arc.
+      ///
+      operator typename Graph::Arc() const
+      {
+        return _arc_it;
+      }
+      /// Conversion to \c Edge
+
+      /// Conversion to \c Edge.
+      ///
+      operator typename Graph::Edge() const
+      {
+        return _arc_it;
+      }
+      bool operator==(Invalid) { return _node_it==INVALID; }
+      bool operator!=(Invalid) { return _node_it!=INVALID; }
+      /// Next edge
+
+      /// Next edge.
+      ///
+      MinCutEdgeIt &operator++()
+      {
+        step();
+        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
+        return *this;
+      }
+      /// Postfix incrementation
+
+      /// Postfix incrementation.
+      ///
+      /// \warning This incrementation
+      /// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect.
+      typename Graph::Arc operator++(int)
+      {
+        typename Graph::Arc e=*this;
+        ++(*this);
+        return e;
+      }
+    };
+
+  };
+
+}
+
+#endif
diff --git a/lemon/graph_to_eps.h b/lemon/graph_to_eps.h
new file mode 100644
index 0000000..29ba836
--- /dev/null
+++ b/lemon/graph_to_eps.h
@@ -0,0 +1,1186 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_GRAPH_TO_EPS_H
+#define LEMON_GRAPH_TO_EPS_H
+
+#include<iostream>
+#include<fstream>
+#include<sstream>
+#include<algorithm>
+#include<vector>
+
+#ifndef WIN32
+#include<sys/time.h>
+#include<ctime>
+#else
+#include<lemon/bits/windows.h>
+#endif
+
+#include<lemon/math.h>
+#include<lemon/core.h>
+#include<lemon/dim2.h>
+#include<lemon/maps.h>
+#include<lemon/color.h>
+#include<lemon/bits/bezier.h>
+#include<lemon/error.h>
+
+
+///\ingroup eps_io
+///\file
+///\brief A well configurable tool for visualizing graphs
+
+namespace lemon {
+
+  namespace _graph_to_eps_bits {
+    template<class MT>
+    class _NegY {
+    public:
+      typedef typename MT::Key Key;
+      typedef typename MT::Value Value;
+      const MT ↦
+      int yscale;
+      _NegY(const MT &m,bool b) : map(m), yscale(1-b*2) {}
+      Value operator[](Key n) { return Value(map[n].x,map[n].y*yscale);}
+    };
+  }
+
+///Default traits class of GraphToEps
+
+///Default traits class of \ref GraphToEps.
+///
+///\param GR is the type of the underlying graph.
+template<class GR>
+struct DefaultGraphToEpsTraits
+{
+  typedef GR Graph;
+  typedef GR Digraph;
+  typedef typename Graph::Node Node;
+  typedef typename Graph::NodeIt NodeIt;
+  typedef typename Graph::Arc Arc;
+  typedef typename Graph::ArcIt ArcIt;
+  typedef typename Graph::InArcIt InArcIt;
+  typedef typename Graph::OutArcIt OutArcIt;
+
+
+  const Graph &g;
+
+  std::ostream& os;
+
+  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
+  CoordsMapType _coords;
+  ConstMap<typename Graph::Node,double > _nodeSizes;
+  ConstMap<typename Graph::Node,int > _nodeShapes;
+
+  ConstMap<typename Graph::Node,Color > _nodeColors;
+  ConstMap<typename Graph::Arc,Color > _arcColors;
+
+  ConstMap<typename Graph::Arc,double > _arcWidths;
+
+  double _arcWidthScale;
+
+  double _nodeScale;
+  double _xBorder, _yBorder;
+  double _scale;
+  double _nodeBorderQuotient;
+
+  bool _drawArrows;
+  double _arrowLength, _arrowWidth;
+
+  bool _showNodes, _showArcs;
+
+  bool _enableParallel;
+  double _parArcDist;
+
+  bool _showNodeText;
+  ConstMap<typename Graph::Node,bool > _nodeTexts;
+  double _nodeTextSize;
+
+  bool _showNodePsText;
+  ConstMap<typename Graph::Node,bool > _nodePsTexts;
+  char *_nodePsTextsPreamble;
+
+  bool _undirected;
+
+  bool _pleaseRemoveOsStream;
+
+  bool _scaleToA4;
+
+  std::string _title;
+  std::string _copyright;
+
+  enum NodeTextColorType
+    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
+  ConstMap<typename Graph::Node,Color > _nodeTextColors;
+
+  bool _autoNodeScale;
+  bool _autoArcWidthScale;
+
+  bool _absoluteNodeSizes;
+  bool _absoluteArcWidths;
+
+  bool _negY;
+
+  bool _preScale;
+  ///Constructor
+
+  ///Constructor
+  ///\param gr  Reference to the graph to be printed.
+  ///\param ost Reference to the output stream.
+  ///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.
+  DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
+                          bool pros = false) :
+    g(gr), os(ost),
+    _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
+    _nodeColors(WHITE), _arcColors(BLACK),
+    _arcWidths(1.0), _arcWidthScale(0.003),
+    _nodeScale(.01), _xBorder(10), _yBorder(10), _scale(1.0),
+    _nodeBorderQuotient(.1),
+    _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
+    _showNodes(true), _showArcs(true),
+    _enableParallel(false), _parArcDist(1),
+    _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
+    _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
+    _undirected(lemon::UndirectedTagIndicator<GR>::value),
+    _pleaseRemoveOsStream(pros), _scaleToA4(false),
+    _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
+    _autoNodeScale(false),
+    _autoArcWidthScale(false),
+    _absoluteNodeSizes(false),
+    _absoluteArcWidths(false),
+    _negY(false),
+    _preScale(true)
+  {}
+};
+
+///Auxiliary class to implement the named parameters of \ref graphToEps()
+
+///Auxiliary class to implement the named parameters of \ref graphToEps().
+///
+///For detailed examples see the \ref graph_to_eps_demo.cc demo file.
+template<class T> class GraphToEps : public T
+{
+  // Can't believe it is required by the C++ standard
+  using T::g;
+  using T::os;
+
+  using T::_coords;
+  using T::_nodeSizes;
+  using T::_nodeShapes;
+  using T::_nodeColors;
+  using T::_arcColors;
+  using T::_arcWidths;
+
+  using T::_arcWidthScale;
+  using T::_nodeScale;
+  using T::_xBorder;
+  using T::_yBorder;
+  using T::_scale;
+  using T::_nodeBorderQuotient;
+
+  using T::_drawArrows;
+  using T::_arrowLength;
+  using T::_arrowWidth;
+
+  using T::_showNodes;
+  using T::_showArcs;
+
+  using T::_enableParallel;
+  using T::_parArcDist;
+
+  using T::_showNodeText;
+  using T::_nodeTexts;
+  using T::_nodeTextSize;
+
+  using T::_showNodePsText;
+  using T::_nodePsTexts;
+  using T::_nodePsTextsPreamble;
+
+  using T::_undirected;
+
+  using T::_pleaseRemoveOsStream;
+
+  using T::_scaleToA4;
+
+  using T::_title;
+  using T::_copyright;
+
+  using T::CUST_COL;
+  using T::DIST_COL;
+  using T::DIST_BW;
+  using T::_nodeTextColorType;
+  using T::_nodeTextColors;
+
+  using T::_autoNodeScale;
+  using T::_autoArcWidthScale;
+
+  using T::_absoluteNodeSizes;
+  using T::_absoluteArcWidths;
+
+
+  using T::_negY;
+  using T::_preScale;
+
+  // dradnats ++C eht yb deriuqer si ti eveileb t'naC
+
+  typedef typename T::Graph Graph;
+  typedef typename T::Digraph Digraph;
+  typedef typename Graph::Node Node;
+  typedef typename Graph::NodeIt NodeIt;
+  typedef typename Graph::Arc Arc;
+  typedef typename Graph::ArcIt ArcIt;
+  typedef typename Graph::InArcIt InArcIt;
+  typedef typename Graph::OutArcIt OutArcIt;
+
+  static const int INTERPOL_PREC;
+  static const double A4HEIGHT;
+  static const double A4WIDTH;
+  static const double A4BORDER;
+
+  bool dontPrint;
+
+public:
+  ///Node shapes
+
+  ///Node shapes.
+  ///
+  enum NodeShapes {
+    /// = 0
+    ///\image html nodeshape_0.png
+    ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
+    CIRCLE=0,
+    /// = 1
+    ///\image html nodeshape_1.png
+    ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
+    SQUARE=1,
+    /// = 2
+    ///\image html nodeshape_2.png
+    ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
+    DIAMOND=2,
+    /// = 3
+    ///\image html nodeshape_3.png
+    ///\image latex nodeshape_3.eps "MALE shape (3)" width=2cm
+    MALE=3,
+    /// = 4
+    ///\image html nodeshape_4.png
+    ///\image latex nodeshape_4.eps "FEMALE shape (4)" width=2cm
+    FEMALE=4
+  };
+
+private:
+  class arcLess {
+    const Graph &g;
+  public:
+    arcLess(const Graph &_g) : g(_g) {}
+    bool operator()(Arc a,Arc b) const
+    {
+      Node ai=std::min(g.source(a),g.target(a));
+      Node aa=std::max(g.source(a),g.target(a));
+      Node bi=std::min(g.source(b),g.target(b));
+      Node ba=std::max(g.source(b),g.target(b));
+      return ai<bi ||
+        (ai==bi && (aa < ba ||
+                    (aa==ba && ai==g.source(a) && bi==g.target(b))));
+    }
+  };
+  bool isParallel(Arc e,Arc f) const
+  {
+    return (g.source(e)==g.source(f)&&
+            g.target(e)==g.target(f)) ||
+      (g.source(e)==g.target(f)&&
+       g.target(e)==g.source(f));
+  }
+  template<class TT>
+  static std::string psOut(const dim2::Point<TT> &p)
+    {
+      std::ostringstream os;
+      os << p.x << ' ' << p.y;
+      return os.str();
+    }
+  static std::string psOut(const Color &c)
+    {
+      std::ostringstream os;
+      os << c.red() << ' ' << c.green() << ' ' << c.blue();
+      return os.str();
+    }
+
+public:
+  GraphToEps(const T &t) : T(t), dontPrint(false) {};
+
+  template<class X> struct CoordsTraits : public T {
+  typedef X CoordsMapType;
+    const X &_coords;
+    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
+  };
+  ///Sets the map of the node coordinates
+
+  ///Sets the map of the node coordinates.
+  ///\param x must be a node map with \ref dim2::Point "dim2::Point<double>" or
+  ///\ref dim2::Point "dim2::Point<int>" values.
+  template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
+    dontPrint=true;
+    return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
+  }
+  template<class X> struct NodeSizesTraits : public T {
+    const X &_nodeSizes;
+    NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
+  };
+  ///Sets the map of the node sizes
+
+  ///Sets the map of the node sizes.
+  ///\param x must be a node map with \c double (or convertible) values.
+  template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
+  {
+    dontPrint=true;
+    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
+  }
+  template<class X> struct NodeShapesTraits : public T {
+    const X &_nodeShapes;
+    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
+  };
+  ///Sets the map of the node shapes
+
+  ///Sets the map of the node shapes.
+  ///The available shape values
+  ///can be found in \ref NodeShapes "enum NodeShapes".
+  ///\param x must be a node map with \c int (or convertible) values.
+  ///\sa NodeShapes
+  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
+  {
+    dontPrint=true;
+    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
+  }
+  template<class X> struct NodeTextsTraits : public T {
+    const X &_nodeTexts;
+    NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
+  };
+  ///Sets the text printed on the nodes
+
+  ///Sets the text printed on the nodes.
+  ///\param x must be a node map with type that can be pushed to a standard
+  ///\c ostream.
+  template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
+  {
+    dontPrint=true;
+    _showNodeText=true;
+    return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
+  }
+  template<class X> struct NodePsTextsTraits : public T {
+    const X &_nodePsTexts;
+    NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
+  };
+  ///Inserts a PostScript block to the nodes
+
+  ///With this command it is possible to insert a verbatim PostScript
+  ///block to the nodes.
+  ///The PS current point will be moved to the center of the node before
+  ///the PostScript block inserted.
+  ///
+  ///Before and after the block a newline character is inserted so you
+  ///don't have to bother with the separators.
+  ///
+  ///\param x must be a node map with type that can be pushed to a standard
+  ///\c ostream.
+  ///
+  ///\sa nodePsTextsPreamble()
+  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
+  {
+    dontPrint=true;
+    _showNodePsText=true;
+    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
+  }
+  template<class X> struct ArcWidthsTraits : public T {
+    const X &_arcWidths;
+    ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {}
+  };
+  ///Sets the map of the arc widths
+
+  ///Sets the map of the arc widths.
+  ///\param x must be an arc map with \c double (or convertible) values.
+  template<class X> GraphToEps<ArcWidthsTraits<X> > arcWidths(const X &x)
+  {
+    dontPrint=true;
+    return GraphToEps<ArcWidthsTraits<X> >(ArcWidthsTraits<X>(*this,x));
+  }
+
+  template<class X> struct NodeColorsTraits : public T {
+    const X &_nodeColors;
+    NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
+  };
+  ///Sets the map of the node colors
+
+  ///Sets the map of the node colors.
+  ///\param x must be a node map with \ref Color values.
+  ///
+  ///\sa Palette
+  template<class X> GraphToEps<NodeColorsTraits<X> >
+  nodeColors(const X &x)
+  {
+    dontPrint=true;
+    return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
+  }
+  template<class X> struct NodeTextColorsTraits : public T {
+    const X &_nodeTextColors;
+    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
+  };
+  ///Sets the map of the node text colors
+
+  ///Sets the map of the node text colors.
+  ///\param x must be a node map with \ref Color values.
+  ///
+  ///\sa Palette
+  template<class X> GraphToEps<NodeTextColorsTraits<X> >
+  nodeTextColors(const X &x)
+  {
+    dontPrint=true;
+    _nodeTextColorType=CUST_COL;
+    return GraphToEps<NodeTextColorsTraits<X> >
+      (NodeTextColorsTraits<X>(*this,x));
+  }
+  template<class X> struct ArcColorsTraits : public T {
+    const X &_arcColors;
+    ArcColorsTraits(const T &t,const X &x) : T(t), _arcColors(x) {}
+  };
+  ///Sets the map of the arc colors
+
+  ///Sets the map of the arc colors.
+  ///\param x must be an arc map with \ref Color values.
+  ///
+  ///\sa Palette
+  template<class X> GraphToEps<ArcColorsTraits<X> >
+  arcColors(const X &x)
+  {
+    dontPrint=true;
+    return GraphToEps<ArcColorsTraits<X> >(ArcColorsTraits<X>(*this,x));
+  }
+  ///Sets a global scale factor for node sizes
+
+  ///Sets a global scale factor for node sizes.
+  ///
+  /// If nodeSizes() is not given, this function simply sets the node
+  /// sizes to \c d.  If nodeSizes() is given, but
+  /// autoNodeScale() is not, then the node size given by
+  /// nodeSizes() will be multiplied by the value \c d.
+  /// If both nodeSizes() and autoNodeScale() are used, then the
+  /// node sizes will be scaled in such a way that the greatest size will be
+  /// equal to \c d.
+  /// \sa nodeSizes()
+  /// \sa autoNodeScale()
+  GraphToEps<T> &nodeScale(double d=.01) {_nodeScale=d;return *this;}
+  ///Turns on/off the automatic node size scaling.
+
+  ///Turns on/off the automatic node size scaling.
+  ///
+  ///\sa nodeScale()
+  ///
+  GraphToEps<T> &autoNodeScale(bool b=true) {
+    _autoNodeScale=b;return *this;
+  }
+
+  ///Turns on/off the absolutematic node size scaling.
+
+  ///Turns on/off the absolutematic node size scaling.
+  ///
+  ///\sa nodeScale()
+  ///
+  GraphToEps<T> &absoluteNodeSizes(bool b=true) {
+    _absoluteNodeSizes=b;return *this;
+  }
+
+  ///Negates the Y coordinates.
+  GraphToEps<T> &negateY(bool b=true) {
+    _negY=b;return *this;
+  }
+
+  ///Turn on/off pre-scaling
+
+  ///By default, graphToEps() rescales the whole image in order to avoid
+  ///very big or very small bounding boxes.
+  ///
+  ///This (p)rescaling can be turned off with this function.
+  ///
+  GraphToEps<T> &preScale(bool b=true) {
+    _preScale=b;return *this;
+  }
+
+  ///Sets a global scale factor for arc widths
+
+  /// Sets a global scale factor for arc widths.
+  ///
+  /// If arcWidths() is not given, this function simply sets the arc
+  /// widths to \c d.  If arcWidths() is given, but
+  /// autoArcWidthScale() is not, then the arc withs given by
+  /// arcWidths() will be multiplied by the value \c d.
+  /// If both arcWidths() and autoArcWidthScale() are used, then the
+  /// arc withs will be scaled in such a way that the greatest width will be
+  /// equal to \c d.
+  GraphToEps<T> &arcWidthScale(double d=.003) {_arcWidthScale=d;return *this;}
+  ///Turns on/off the automatic arc width scaling.
+
+  ///Turns on/off the automatic arc width scaling.
+  ///
+  ///\sa arcWidthScale()
+  ///
+  GraphToEps<T> &autoArcWidthScale(bool b=true) {
+    _autoArcWidthScale=b;return *this;
+  }
+  ///Turns on/off the absolutematic arc width scaling.
+
+  ///Turns on/off the absolutematic arc width scaling.
+  ///
+  ///\sa arcWidthScale()
+  ///
+  GraphToEps<T> &absoluteArcWidths(bool b=true) {
+    _absoluteArcWidths=b;return *this;
+  }
+  ///Sets a global scale factor for the whole picture
+  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
+  ///Sets the width of the border around the picture
+  GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
+  ///Sets the width of the border around the picture
+  GraphToEps<T> &border(double x, double y) {
+    _xBorder=x;_yBorder=y;return *this;
+  }
+  ///Sets whether to draw arrows
+  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
+  ///Sets the length of the arrowheads
+  GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
+  ///Sets the width of the arrowheads
+  GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
+
+  ///Scales the drawing to fit to A4 page
+  GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
+
+  ///Enables parallel arcs
+  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
+
+  ///Sets the distance between parallel arcs
+  GraphToEps<T> &parArcDist(double d) {_parArcDist*=d;return *this;}
+
+  ///Hides the arcs
+  GraphToEps<T> &hideArcs(bool b=true) {_showArcs=!b;return *this;}
+  ///Hides the nodes
+  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
+
+  ///Sets the size of the node texts
+  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
+
+  ///Sets the color of the node texts to be different from the node color
+
+  ///Sets the color of the node texts to be as different from the node color
+  ///as it is possible.
+  GraphToEps<T> &distantColorNodeTexts()
+  {_nodeTextColorType=DIST_COL;return *this;}
+  ///Sets the color of the node texts to be black or white and always visible.
+
+  ///Sets the color of the node texts to be black or white according to
+  ///which is more different from the node color.
+  GraphToEps<T> &distantBWNodeTexts()
+  {_nodeTextColorType=DIST_BW;return *this;}
+
+  ///Gives a preamble block for node Postscript block.
+
+  ///Gives a preamble block for node Postscript block.
+  ///
+  ///\sa nodePsTexts()
+  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
+    _nodePsTextsPreamble=str ;return *this;
+  }
+  ///Sets whether the graph is undirected
+
+  ///Sets whether the graph is undirected.
+  ///
+  ///This setting is the default for undirected graphs.
+  ///
+  ///\sa directed()
+   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
+
+  ///Sets whether the graph is directed
+
+  ///Sets whether the graph is directed.
+  ///Use it to show the edges as a pair of directed ones.
+  ///
+  ///This setting is the default for digraphs.
+  ///
+  ///\sa undirected()
+  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
+
+  ///Sets the title.
+
+  ///Sets the title of the generated image,
+  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
+  ///the EPS file.
+  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
+  ///Sets the copyright statement.
+
+  ///Sets the copyright statement of the generated image,
+  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
+  ///the EPS file.
+  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
+
+protected:
+  bool isInsideNode(dim2::Point<double> p, double r,int t)
+  {
+    switch(t) {
+    case CIRCLE:
+    case MALE:
+    case FEMALE:
+      return p.normSquare()<=r*r;
+    case SQUARE:
+      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
+    case DIAMOND:
+      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
+    }
+    return false;
+  }
+
+public:
+  ~GraphToEps() { }
+
+  ///Draws the graph.
+
+  ///Like other functions using
+  ///\ref named-templ-func-param "named template parameters",
+  ///this function calls the algorithm itself, i.e. in this case
+  ///it draws the graph.
+  void run() {
+    const double EPSILON=1e-9;
+    if(dontPrint) return;
+
+    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
+      mycoords(_coords,_negY);
+
+    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
+    if(_title.size()>0) os << "%%Title: " << _title << '\n';
+     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
+    os << "%%Creator: LEMON, graphToEps()\n";
+
+    {
+      os << "%%CreationDate: ";
+#ifndef WIN32
+      timeval tv;
+      gettimeofday(&tv, 0);
+
+      char cbuf[26];
+      ctime_r(&tv.tv_sec,cbuf);
+      os << cbuf;
+#else
+      os << bits::getWinFormattedDate();
+      os << std::endl;
+#endif
+    }
+
+    if (_autoArcWidthScale) {
+      double max_w=0;
+      for(ArcIt e(g);e!=INVALID;++e)
+        max_w=std::max(double(_arcWidths[e]),max_w);
+      if(max_w>EPSILON) {
+        _arcWidthScale/=max_w;
+      }
+    }
+
+    if (_autoNodeScale) {
+      double max_s=0;
+      for(NodeIt n(g);n!=INVALID;++n)
+        max_s=std::max(double(_nodeSizes[n]),max_s);
+      if(max_s>EPSILON) {
+        _nodeScale/=max_s;
+      }
+    }
+
+    double diag_len = 1;
+    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
+      dim2::Box<double> bb;
+      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
+      if (bb.empty()) {
+        bb = dim2::Box<double>(dim2::Point<double>(0,0));
+      }
+      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
+      if(diag_len<EPSILON) diag_len = 1;
+      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
+      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
+    }
+
+    dim2::Box<double> bb;
+    for(NodeIt n(g);n!=INVALID;++n) {
+      double ns=_nodeSizes[n]*_nodeScale;
+      dim2::Point<double> p(ns,ns);
+      switch(_nodeShapes[n]) {
+      case CIRCLE:
+      case SQUARE:
+      case DIAMOND:
+        bb.add(p+mycoords[n]);
+        bb.add(-p+mycoords[n]);
+        break;
+      case MALE:
+        bb.add(-p+mycoords[n]);
+        bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
+        break;
+      case FEMALE:
+        bb.add(p+mycoords[n]);
+        bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
+        break;
+      }
+    }
+    if (bb.empty()) {
+      bb = dim2::Box<double>(dim2::Point<double>(0,0));
+    }
+
+    if(_scaleToA4)
+      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
+    else {
+      if(_preScale) {
+        //Rescale so that BoundingBox won't be neither to big nor too small.
+        while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10;
+        while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10;
+      }
+
+      os << "%%BoundingBox: "
+         << int(floor(bb.left()   * _scale - _xBorder)) << ' '
+         << int(floor(bb.bottom() * _scale - _yBorder)) << ' '
+         << int(ceil(bb.right()  * _scale + _xBorder)) << ' '
+         << int(ceil(bb.top()    * _scale + _yBorder)) << '\n';
+    }
+
+    os << "%%EndComments\n";
+
+    //x1 y1 x2 y2 x3 y3 cr cg cb w
+    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
+       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
+    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke }"
+       << " bind def\n";
+    //x y r
+    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath }"
+       << " bind def\n";
+    //x y r
+    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
+       << "      2 index 1 index sub 2 index 2 index add lineto\n"
+       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
+       << "      2 index 1 index add 2 index 2 index sub lineto\n"
+       << "      closepath pop pop pop} bind def\n";
+    //x y r
+    os << "/di { newpath 2 index 1 index add 2 index moveto\n"
+       << "      2 index             2 index 2 index add lineto\n"
+       << "      2 index 1 index sub 2 index             lineto\n"
+       << "      2 index             2 index 2 index sub lineto\n"
+       << "      closepath pop pop pop} bind def\n";
+    // x y r cr cg cb
+    os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n"
+       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
+       << "   } bind def\n";
+    os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n"
+       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n"
+       << "   } bind def\n";
+    os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n"
+       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n"
+       << "   } bind def\n";
+    os << "/nfemale { 0 0 0 setrgbcolor 3 index "
+       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
+       << " 1.5 mul mul setlinewidth\n"
+       << "  newpath 5 index 5 index moveto "
+       << "5 index 5 index 5 index 3.01 mul sub\n"
+       << "  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub"
+       << " moveto\n"
+       << "  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto "
+       << "stroke\n"
+       << "  5 index 5 index 5 index c fill\n"
+       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
+       << "  } bind def\n";
+    os << "/nmale {\n"
+       << "  0 0 0 setrgbcolor 3 index "
+       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
+       <<" 1.5 mul mul setlinewidth\n"
+       << "  newpath 5 index 5 index moveto\n"
+       << "  5 index 4 index 1 mul 1.5 mul add\n"
+       << "  5 index 5 index 3 sqrt 1.5 mul mul add\n"
+       << "  1 index 1 index lineto\n"
+       << "  1 index 1 index 7 index sub moveto\n"
+       << "  1 index 1 index lineto\n"
+       << "  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub"
+       << " lineto\n"
+       << "  stroke\n"
+       << "  5 index 5 index 5 index c fill\n"
+       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
+       << "  } bind def\n";
+
+
+    os << "/arrl " << _arrowLength << " def\n";
+    os << "/arrw " << _arrowWidth << " def\n";
+    // l dx_norm dy_norm
+    os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
+    //len w dx_norm dy_norm x1 y1 cr cg cb
+    os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx "
+       << "exch def\n"
+       << "       /w exch def /len exch def\n"
+      //<< "0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
+       << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
+       << "       len w sub arrl sub dx dy lrl\n"
+       << "       arrw dy dx neg lrl\n"
+       << "       dx arrl w add mul dy w 2 div arrw add mul sub\n"
+       << "       dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
+       << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
+       << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
+       << "       arrw dy dx neg lrl\n"
+       << "       len w sub arrl sub neg dx dy lrl\n"
+       << "       closepath fill } bind def\n";
+    os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
+       << "         neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
+
+    os << "\ngsave\n";
+    if(_scaleToA4)
+      if(bb.height()>bb.width()) {
+        double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.height(),
+                  (A4WIDTH-2*A4BORDER)/bb.width());
+        os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' '
+           << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER
+           << " translate\n"
+           << sc << " dup scale\n"
+           << -bb.left() << ' ' << -bb.bottom() << " translate\n";
+      }
+      else {
+        double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.width(),
+                  (A4WIDTH-2*A4BORDER)/bb.height());
+        os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' '
+           << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER
+           << " translate\n"
+           << sc << " dup scale\n90 rotate\n"
+           << -bb.left() << ' ' << -bb.top() << " translate\n";
+        }
+    else if(_scale!=1.0) os << _scale << " dup scale\n";
+
+    if(_showArcs) {
+      os << "%Arcs:\ngsave\n";
+      if(_enableParallel) {
+        std::vector<Arc> el;
+        for(ArcIt e(g);e!=INVALID;++e)
+          if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
+             &&g.source(e)!=g.target(e))
+            el.push_back(e);
+        std::sort(el.begin(),el.end(),arcLess(g));
+
+        typename std::vector<Arc>::iterator j;
+        for(typename std::vector<Arc>::iterator i=el.begin();i!=el.end();i=j) {
+          for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
+
+          double sw=0;
+          for(typename std::vector<Arc>::iterator e=i;e!=j;++e)
+            sw+=_arcWidths[*e]*_arcWidthScale+_parArcDist;
+          sw-=_parArcDist;
+          sw/=-2.0;
+          dim2::Point<double>
+            dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
+          double l=std::sqrt(dvec.normSquare());
+          dim2::Point<double> d(dvec/std::max(l,EPSILON));
+          dim2::Point<double> m;
+//           m=dim2::Point<double>(mycoords[g.target(*i)]+
+//                                 mycoords[g.source(*i)])/2.0;
+
+//            m=dim2::Point<double>(mycoords[g.source(*i)])+
+//             dvec*(double(_nodeSizes[g.source(*i)])/
+//                (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
+
+          m=dim2::Point<double>(mycoords[g.source(*i)])+
+            d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
+
+          for(typename std::vector<Arc>::iterator e=i;e!=j;++e) {
+            sw+=_arcWidths[*e]*_arcWidthScale/2.0;
+            dim2::Point<double> mm=m+rot90(d)*sw/.75;
+            if(_drawArrows) {
+              int node_shape;
+              dim2::Point<double> s=mycoords[g.source(*e)];
+              dim2::Point<double> t=mycoords[g.target(*e)];
+              double rn=_nodeSizes[g.target(*e)]*_nodeScale;
+              node_shape=_nodeShapes[g.target(*e)];
+              dim2::Bezier3 bez(s,mm,mm,t);
+              double t1=0,t2=1;
+              for(int ii=0;ii<INTERPOL_PREC;++ii)
+                if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
+                else t1=(t1+t2)/2;
+              dim2::Point<double> apoint=bez((t1+t2)/2);
+              rn = _arrowLength+_arcWidths[*e]*_arcWidthScale;
+              rn*=rn;
+              t2=(t1+t2)/2;t1=0;
+              for(int ii=0;ii<INTERPOL_PREC;++ii)
+                if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
+                else t2=(t1+t2)/2;
+              dim2::Point<double> linend=bez((t1+t2)/2);
+              bez=bez.before((t1+t2)/2);
+//               rn=_nodeSizes[g.source(*e)]*_nodeScale;
+//               node_shape=_nodeShapes[g.source(*e)];
+//               t1=0;t2=1;
+//               for(int i=0;i<INTERPOL_PREC;++i)
+//                 if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape))
+//                   t1=(t1+t2)/2;
+//                 else t2=(t1+t2)/2;
+//               bez=bez.after((t1+t2)/2);
+              os << _arcWidths[*e]*_arcWidthScale << " setlinewidth "
+                 << _arcColors[*e].red() << ' '
+                 << _arcColors[*e].green() << ' '
+                 << _arcColors[*e].blue() << " setrgbcolor newpath\n"
+                 << bez.p1.x << ' ' <<  bez.p1.y << " moveto\n"
+                 << bez.p2.x << ' ' << bez.p2.y << ' '
+                 << bez.p3.x << ' ' << bez.p3.y << ' '
+                 << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
+              dim2::Point<double> dd(rot90(linend-apoint));
+              dd*=(.5*_arcWidths[*e]*_arcWidthScale+_arrowWidth)/
+                std::sqrt(dd.normSquare());
+              os << "newpath " << psOut(apoint) << " moveto "
+                 << psOut(linend+dd) << " lineto "
+                 << psOut(linend-dd) << " lineto closepath fill\n";
+            }
+            else {
+              os << mycoords[g.source(*e)].x << ' '
+                 << mycoords[g.source(*e)].y << ' '
+                 << mm.x << ' ' << mm.y << ' '
+                 << mycoords[g.target(*e)].x << ' '
+                 << mycoords[g.target(*e)].y << ' '
+                 << _arcColors[*e].red() << ' '
+                 << _arcColors[*e].green() << ' '
+                 << _arcColors[*e].blue() << ' '
+                 << _arcWidths[*e]*_arcWidthScale << " lb\n";
+            }
+            sw+=_arcWidths[*e]*_arcWidthScale/2.0+_parArcDist;
+          }
+        }
+      }
+      else for(ArcIt e(g);e!=INVALID;++e)
+        if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
+           &&g.source(e)!=g.target(e)) {
+          if(_drawArrows) {
+            dim2::Point<double> d(mycoords[g.target(e)]-mycoords[g.source(e)]);
+            double rn=_nodeSizes[g.target(e)]*_nodeScale;
+            int node_shape=_nodeShapes[g.target(e)];
+            double t1=0,t2=1;
+            for(int i=0;i<INTERPOL_PREC;++i)
+              if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
+              else t2=(t1+t2)/2;
+            double l=std::sqrt(d.normSquare());
+            d/=l;
+
+            os << l*(1-(t1+t2)/2) << ' '
+               << _arcWidths[e]*_arcWidthScale << ' '
+               << d.x << ' ' << d.y << ' '
+               << mycoords[g.source(e)].x << ' '
+               << mycoords[g.source(e)].y << ' '
+               << _arcColors[e].red() << ' '
+               << _arcColors[e].green() << ' '
+               << _arcColors[e].blue() << " arr\n";
+          }
+          else os << mycoords[g.source(e)].x << ' '
+                  << mycoords[g.source(e)].y << ' '
+                  << mycoords[g.target(e)].x << ' '
+                  << mycoords[g.target(e)].y << ' '
+                  << _arcColors[e].red() << ' '
+                  << _arcColors[e].green() << ' '
+                  << _arcColors[e].blue() << ' '
+                  << _arcWidths[e]*_arcWidthScale << " l\n";
+        }
+      os << "grestore\n";
+    }
+    if(_showNodes) {
+      os << "%Nodes:\ngsave\n";
+      for(NodeIt n(g);n!=INVALID;++n) {
+        os << mycoords[n].x << ' ' << mycoords[n].y << ' '
+           << _nodeSizes[n]*_nodeScale << ' '
+           << _nodeColors[n].red() << ' '
+           << _nodeColors[n].green() << ' '
+           << _nodeColors[n].blue() << ' ';
+        switch(_nodeShapes[n]) {
+        case CIRCLE:
+          os<< "nc";break;
+        case SQUARE:
+          os<< "nsq";break;
+        case DIAMOND:
+          os<< "ndi";break;
+        case MALE:
+          os<< "nmale";break;
+        case FEMALE:
+          os<< "nfemale";break;
+        }
+        os<<'\n';
+      }
+      os << "grestore\n";
+    }
+    if(_showNodeText) {
+      os << "%Node texts:\ngsave\n";
+      os << "/fosi " << _nodeTextSize << " def\n";
+      os << "(Helvetica) findfont fosi scalefont setfont\n";
+      for(NodeIt n(g);n!=INVALID;++n) {
+        switch(_nodeTextColorType) {
+        case DIST_COL:
+          os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
+          break;
+        case DIST_BW:
+          os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
+          break;
+        case CUST_COL:
+          os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
+          break;
+        default:
+          os << "0 0 0 setrgbcolor\n";
+        }
+        os << mycoords[n].x << ' ' << mycoords[n].y
+           << " (" << _nodeTexts[n] << ") cshow\n";
+      }
+      os << "grestore\n";
+    }
+    if(_showNodePsText) {
+      os << "%Node PS blocks:\ngsave\n";
+      for(NodeIt n(g);n!=INVALID;++n)
+        os << mycoords[n].x << ' ' << mycoords[n].y
+           << " moveto\n" << _nodePsTexts[n] << "\n";
+      os << "grestore\n";
+    }
+
+    os << "grestore\nshowpage\n";
+
+    //CleanUp:
+    if(_pleaseRemoveOsStream) {delete &os;}
+  }
+
+  ///\name Aliases
+  ///These are just some aliases to other parameter setting functions.
+
+  ///@{
+
+  ///An alias for arcWidths()
+  template<class X> GraphToEps<ArcWidthsTraits<X> > edgeWidths(const X &x)
+  {
+    return arcWidths(x);
+  }
+
+  ///An alias for arcColors()
+  template<class X> GraphToEps<ArcColorsTraits<X> >
+  edgeColors(const X &x)
+  {
+    return arcColors(x);
+  }
+
+  ///An alias for arcWidthScale()
+  GraphToEps<T> &edgeWidthScale(double d) {return arcWidthScale(d);}
+
+  ///An alias for autoArcWidthScale()
+  GraphToEps<T> &autoEdgeWidthScale(bool b=true)
+  {
+    return autoArcWidthScale(b);
+  }
+
+  ///An alias for absoluteArcWidths()
+  GraphToEps<T> &absoluteEdgeWidths(bool b=true)
+  {
+    return absoluteArcWidths(b);
+  }
+
+  ///An alias for parArcDist()
+  GraphToEps<T> &parEdgeDist(double d) {return parArcDist(d);}
+
+  ///An alias for hideArcs()
+  GraphToEps<T> &hideEdges(bool b=true) {return hideArcs(b);}
+
+  ///@}
+};
+
+template<class T>
+const int GraphToEps<T>::INTERPOL_PREC = 20;
+template<class T>
+const double GraphToEps<T>::A4HEIGHT = 841.8897637795276;
+template<class T>
+const double GraphToEps<T>::A4WIDTH  = 595.275590551181;
+template<class T>
+const double GraphToEps<T>::A4BORDER = 15;
+
+
+///Generates an EPS file from a graph
+
+///\ingroup eps_io
+///Generates an EPS file from a graph.
+///\param g Reference to the graph to be printed.
+///\param os Reference to the output stream.
+///By default, it is <tt>std::cout</tt>.
+///
+///This function also has a lot of
+///\ref named-templ-func-param "named parameters",
+///they are declared as the members of class \ref GraphToEps. The following
+///example shows how to use these parameters.
+///\code
+/// graphToEps(g,os).scale(10).coords(coords)
+///              .nodeScale(2).nodeSizes(sizes)
+///              .arcWidthScale(.4).run();
+///\endcode
+///
+///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()"
+///to the end of the parameter list.
+///\sa GraphToEps
+///\sa graphToEps(GR &g, const char *file_name)
+template<class GR>
+GraphToEps<DefaultGraphToEpsTraits<GR> >
+graphToEps(GR &g, std::ostream& os=std::cout)
+{
+  return
+    GraphToEps<DefaultGraphToEpsTraits<GR> >(DefaultGraphToEpsTraits<GR>(g,os));
+}
+
+///Generates an EPS file from a graph
+
+///\ingroup eps_io
+///This function does the same as
+///\ref graphToEps(GR &g,std::ostream& os)
+///but it writes its output into the file \c file_name
+///instead of a stream.
+///\sa graphToEps(GR &g, std::ostream& os)
+template<class GR>
+GraphToEps<DefaultGraphToEpsTraits<GR> >
+graphToEps(GR &g,const char *file_name)
+{
+  std::ostream* os = new std::ofstream(file_name);
+  if (!(*os)) {
+    delete os;
+    throw IoError("Cannot write file", file_name);
+  }
+  return GraphToEps<DefaultGraphToEpsTraits<GR> >
+    (DefaultGraphToEpsTraits<GR>(g,*os,true));
+}
+
+///Generates an EPS file from a graph
+
+///\ingroup eps_io
+///This function does the same as
+///\ref graphToEps(GR &g,std::ostream& os)
+///but it writes its output into the file \c file_name
+///instead of a stream.
+///\sa graphToEps(GR &g, std::ostream& os)
+template<class GR>
+GraphToEps<DefaultGraphToEpsTraits<GR> >
+graphToEps(GR &g,const std::string& file_name)
+{
+  std::ostream* os = new std::ofstream(file_name.c_str());
+  if (!(*os)) {
+    delete os;
+    throw IoError("Cannot write file", file_name);
+  }
+  return GraphToEps<DefaultGraphToEpsTraits<GR> >
+    (DefaultGraphToEpsTraits<GR>(g,*os,true));
+}
+
+} //END OF NAMESPACE LEMON
+
+#endif // LEMON_GRAPH_TO_EPS_H
diff --git a/lemon/greedy_tsp.h b/lemon/greedy_tsp.h
new file mode 100644
index 0000000..9546171
--- /dev/null
+++ b/lemon/greedy_tsp.h
@@ -0,0 +1,251 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_GREEDY_TSP_H
+#define LEMON_GREEDY_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief Greedy algorithm for symmetric TSP
+
+#include <vector>
+#include <algorithm>
+#include <lemon/full_graph.h>
+#include <lemon/unionfind.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief Greedy algorithm for symmetric TSP.
+  ///
+  /// GreedyTsp implements the greedy heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This algorithm is quite similar to the \ref NearestNeighborTsp
+  /// "nearest neighbor" heuristic, but it maintains a set of disjoint paths.
+  /// At each step, the shortest possible edge is added to these paths
+  /// as long as it does not create a cycle of less than n edges and it does
+  /// not increase the degree of any node above two.
+  ///
+  /// This method runs in O(n<sup>2</sup>) time.
+  /// It quickly finds a relatively short tour for most TSP instances,
+  /// but it could also yield a really bad (or even the worst) solution
+  /// in special cases.
+  ///
+  /// \tparam CM Type of the cost map.
+  template <typename CM>
+  class GreedyTsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      Cost _sum;
+      std::vector<Node> _path;
+
+    private:
+
+      // Functor class to compare edges by their costs
+      class EdgeComp {
+      private:
+        const CostMap &_cost;
+
+      public:
+        EdgeComp(const CostMap &cost) : _cost(cost) {}
+
+        bool operator()(const Edge &a, const Edge &b) const {
+          return _cost[a] < _cost[b];
+        }
+      };
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      GreedyTsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm.
+      ///
+      /// This function runs the algorithm.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run() {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+
+        std::vector<int> plist;
+        plist.resize(_gr.nodeNum()*2, -1);
+
+        std::vector<Edge> sorted_edges;
+        sorted_edges.reserve(_gr.edgeNum());
+        for (EdgeIt e(_gr); e != INVALID; ++e)
+          sorted_edges.push_back(e);
+        std::sort(sorted_edges.begin(), sorted_edges.end(), EdgeComp(_cost));
+
+        FullGraph::NodeMap<int> item_int_map(_gr);
+        UnionFind<FullGraph::NodeMap<int> > union_find(item_int_map);
+        for (NodeIt n(_gr); n != INVALID; ++n)
+          union_find.insert(n);
+
+        FullGraph::NodeMap<int> degree(_gr, 0);
+
+        int nodesNum = 0, i = 0;
+        while (nodesNum != _gr.nodeNum()-1) {
+          Edge e = sorted_edges[i++];
+          Node u = _gr.u(e),
+               v = _gr.v(e);
+
+          if (degree[u] <= 1 && degree[v] <= 1) {
+            if (union_find.join(u, v)) {
+              const int uid = _gr.id(u),
+                        vid = _gr.id(v);
+
+              plist[uid*2 + degree[u]] = vid;
+              plist[vid*2 + degree[v]] = uid;
+
+              ++degree[u];
+              ++degree[v];
+              ++nodesNum;
+            }
+          }
+        }
+
+        for (int i=0, n=-1; i<_gr.nodeNum()*2; ++i) {
+          if (plist[i] == -1) {
+            if (n==-1) {
+              n = i;
+            } else {
+              plist[n] = i/2;
+              plist[i] = n/2;
+              break;
+            }
+          }
+        }
+
+        for (int i=0, next=0, last=-1; i!=_gr.nodeNum(); ++i) {
+          _path.push_back(_gr.nodeFromId(next));
+          if (plist[2*next] != last) {
+            last = next;
+            next = plist[2*next];
+          } else {
+            last = next;
+            next = plist[2*next+1];
+          }
+        }
+
+        _sum = _cost[_gr.edge(_path.back(), _path.front())];
+        for (int i = 0; i < int(_path.size())-1; ++i) {
+          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
+        }
+
+        return _sum;
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _path;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_path.begin(), _path.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_path.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_path[i], _path[i+1]));
+        }
+        if (int(_path.size()) >= 2) {
+          path.addBack(_gr.arc(_path.back(), _path.front()));
+        }
+      }
+
+      /// @}
+
+  };
+
+}; // namespace lemon
+
+#endif
diff --git a/lemon/grid_graph.h b/lemon/grid_graph.h
new file mode 100644
index 0000000..a3dff0f
--- /dev/null
+++ b/lemon/grid_graph.h
@@ -0,0 +1,699 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef GRID_GRAPH_H
+#define GRID_GRAPH_H
+
+#include <lemon/core.h>
+#include <lemon/bits/graph_extender.h>
+#include <lemon/dim2.h>
+#include <lemon/assert.h>
+
+///\ingroup graphs
+///\file
+///\brief GridGraph class.
+
+namespace lemon {
+
+  class GridGraphBase {
+
+  public:
+
+    typedef GridGraphBase Graph;
+
+    class Node;
+    class Edge;
+    class Arc;
+
+  public:
+
+    GridGraphBase() {}
+
+  protected:
+
+    void construct(int width, int height) {
+       _width = width; _height = height;
+      _node_num = width * height;
+      _edge_num = 2 * _node_num - width - height;
+      _edge_limit = _node_num - _width;
+    }
+
+  public:
+
+    Node operator()(int i, int j) const {
+      LEMON_DEBUG(0 <= i && i < _width &&
+                  0 <= j  && j < _height, "Index out of range");
+      return Node(i + j * _width);
+    }
+
+    int col(Node n) const {
+      return n._id % _width;
+    }
+
+    int row(Node n) const {
+      return n._id / _width;
+    }
+
+    dim2::Point<int> pos(Node n) const {
+      return dim2::Point<int>(col(n), row(n));
+    }
+
+    int width() const {
+      return _width;
+    }
+
+    int height() const {
+      return _height;
+    }
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return _node_num; }
+    int edgeNum() const { return _edge_num; }
+    int arcNum() const { return 2 * _edge_num; }
+
+    Node u(Edge edge) const {
+      if (edge._id < _edge_limit) {
+        return edge._id;
+      } else {
+        return (edge._id - _edge_limit) % (_width - 1) +
+          (edge._id - _edge_limit) / (_width - 1) * _width;
+      }
+    }
+
+    Node v(Edge edge) const {
+      if (edge._id < _edge_limit) {
+        return edge._id + _width;
+      } else {
+        return (edge._id - _edge_limit) % (_width - 1) +
+          (edge._id - _edge_limit) / (_width - 1) * _width + 1;
+      }
+    }
+
+    Node source(Arc arc) const {
+      return (arc._id & 1) == 1 ? u(arc) : v(arc);
+    }
+
+    Node target(Arc arc) const {
+      return (arc._id & 1) == 1 ? v(arc) : u(arc);
+    }
+
+    static int id(Node node) { return node._id; }
+    static int id(Edge edge) { return edge._id; }
+    static int id(Arc arc) { return arc._id; }
+
+    int maxNodeId() const { return _node_num - 1; }
+    int maxEdgeId() const { return _edge_num - 1; }
+    int maxArcId() const { return 2 * _edge_num - 1; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      if (prev != INVALID) return INVALID;
+      if (v._id > u._id) {
+        if (v._id - u._id == _width)
+          return Edge(u._id);
+        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
+          return Edge(u._id / _width * (_width - 1) +
+                      u._id % _width + _edge_limit);
+        }
+      } else {
+        if (u._id - v._id == _width)
+          return Edge(v._id);
+        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
+          return Edge(v._id / _width * (_width - 1) +
+                      v._id % _width + _edge_limit);
+        }
+      }
+      return INVALID;
+    }
+
+    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
+      if (prev != INVALID) return INVALID;
+      if (v._id > u._id) {
+        if (v._id - u._id == _width)
+          return Arc((u._id << 1) | 1);
+        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
+          return Arc(((u._id / _width * (_width - 1) +
+                       u._id % _width + _edge_limit) << 1) | 1);
+        }
+      } else {
+        if (u._id - v._id == _width)
+          return Arc(v._id << 1);
+        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
+          return Arc((v._id / _width * (_width - 1) +
+                       v._id % _width + _edge_limit) << 1);
+        }
+      }
+      return INVALID;
+    }
+
+    class Node {
+      friend class GridGraphBase;
+
+    protected:
+      int _id;
+      Node(int id) : _id(id) {}
+    public:
+      Node() {}
+      Node (Invalid) : _id(-1) {}
+      bool operator==(const Node node) const {return _id == node._id;}
+      bool operator!=(const Node node) const {return _id != node._id;}
+      bool operator<(const Node node) const {return _id < node._id;}
+    };
+
+    class Edge {
+      friend class GridGraphBase;
+      friend class Arc;
+
+    protected:
+      int _id;
+
+      Edge(int id) : _id(id) {}
+
+    public:
+      Edge() {}
+      Edge (Invalid) : _id(-1) {}
+      bool operator==(const Edge edge) const {return _id == edge._id;}
+      bool operator!=(const Edge edge) const {return _id != edge._id;}
+      bool operator<(const Edge edge) const {return _id < edge._id;}
+    };
+
+    class Arc {
+      friend class GridGraphBase;
+
+    protected:
+      int _id;
+
+      Arc(int id) : _id(id) {}
+
+    public:
+      Arc() {}
+      Arc (Invalid) : _id(-1) {}
+      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
+      bool operator==(const Arc arc) const {return _id == arc._id;}
+      bool operator!=(const Arc arc) const {return _id != arc._id;}
+      bool operator<(const Arc arc) const {return _id < arc._id;}
+    };
+
+    static bool direction(Arc arc) {
+      return (arc._id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc((edge._id << 1) | (dir ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Edge& edge) const {
+      edge._id = _edge_num - 1;
+    }
+
+    static void next(Edge& edge) {
+      --edge._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = 2 * _edge_num - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      if (node._id % _width < _width - 1) {
+        arc._id = (_edge_limit + node._id % _width +
+                   (node._id / _width) * (_width - 1)) << 1 | 1;
+        return;
+      }
+      if (node._id < _node_num - _width) {
+        arc._id = node._id << 1 | 1;
+        return;
+      }
+      if (node._id % _width > 0) {
+        arc._id = (_edge_limit + node._id % _width +
+                   (node._id / _width) * (_width - 1) - 1) << 1;
+        return;
+      }
+      if (node._id >= _width) {
+        arc._id = (node._id - _width) << 1;
+        return;
+      }
+      arc._id = -1;
+    }
+
+    void nextOut(Arc& arc) const {
+      int nid = arc._id >> 1;
+      if ((arc._id & 1) == 1) {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width;
+          if (nid < _node_num - _width) {
+            arc._id = nid << 1 | 1;
+            return;
+          }
+        }
+        if (nid % _width > 0) {
+          arc._id = (_edge_limit + nid % _width +
+                     (nid / _width) * (_width - 1) - 1) << 1;
+          return;
+        }
+        if (nid >= _width) {
+          arc._id = (nid - _width) << 1;
+          return;
+        }
+      } else {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width + 1;
+          if (nid >= _width) {
+            arc._id = (nid - _width) << 1;
+            return;
+          }
+        }
+      }
+      arc._id = -1;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      if (node._id % _width < _width - 1) {
+        arc._id = (_edge_limit + node._id % _width +
+                   (node._id / _width) * (_width - 1)) << 1;
+        return;
+      }
+      if (node._id < _node_num - _width) {
+        arc._id = node._id << 1;
+        return;
+      }
+      if (node._id % _width > 0) {
+        arc._id = (_edge_limit + node._id % _width +
+                   (node._id / _width) * (_width - 1) - 1) << 1 | 1;
+        return;
+      }
+      if (node._id >= _width) {
+        arc._id = (node._id - _width) << 1 | 1;
+        return;
+      }
+      arc._id = -1;
+    }
+
+    void nextIn(Arc& arc) const {
+      int nid = arc._id >> 1;
+      if ((arc._id & 1) == 0) {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width;
+          if (nid < _node_num - _width) {
+            arc._id = nid << 1;
+            return;
+          }
+        }
+        if (nid % _width > 0) {
+          arc._id = (_edge_limit + nid % _width +
+                     (nid / _width) * (_width - 1) - 1) << 1 | 1;
+          return;
+        }
+        if (nid >= _width) {
+          arc._id = (nid - _width) << 1 | 1;
+          return;
+        }
+      } else {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width + 1;
+          if (nid >= _width) {
+            arc._id = (nid - _width) << 1 | 1;
+            return;
+          }
+        }
+      }
+      arc._id = -1;
+    }
+
+    void firstInc(Edge& edge, bool& dir, const Node& node) const {
+      if (node._id % _width < _width - 1) {
+        edge._id = _edge_limit + node._id % _width +
+          (node._id / _width) * (_width - 1);
+        dir = true;
+        return;
+      }
+      if (node._id < _node_num - _width) {
+        edge._id = node._id;
+        dir = true;
+        return;
+      }
+      if (node._id % _width > 0) {
+        edge._id = _edge_limit + node._id % _width +
+          (node._id / _width) * (_width - 1) - 1;
+        dir = false;
+        return;
+      }
+      if (node._id >= _width) {
+        edge._id = node._id - _width;
+        dir = false;
+        return;
+      }
+      edge._id = -1;
+      dir = true;
+    }
+
+    void nextInc(Edge& edge, bool& dir) const {
+      int nid = edge._id;
+      if (dir) {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width;
+          if (nid < _node_num - _width) {
+            edge._id = nid;
+            return;
+          }
+        }
+        if (nid % _width > 0) {
+          edge._id = _edge_limit + nid % _width +
+            (nid / _width) * (_width - 1) - 1;
+          dir = false;
+          return;
+        }
+        if (nid >= _width) {
+          edge._id = nid - _width;
+          dir = false;
+          return;
+        }
+      } else {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width + 1;
+          if (nid >= _width) {
+            edge._id = nid - _width;
+            return;
+          }
+        }
+      }
+      edge._id = -1;
+      dir = true;
+    }
+
+    Arc right(Node n) const {
+      if (n._id % _width < _width - 1) {
+        return Arc(((_edge_limit + n._id % _width +
+                    (n._id / _width) * (_width - 1)) << 1) | 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc left(Node n) const {
+      if (n._id % _width > 0) {
+        return Arc((_edge_limit + n._id % _width +
+                     (n._id / _width) * (_width - 1) - 1) << 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc up(Node n) const {
+      if (n._id < _edge_limit) {
+        return Arc((n._id << 1) | 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc down(Node n) const {
+      if (n._id >= _width) {
+        return Arc((n._id - _width) << 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+  private:
+    int _width, _height;
+    int _node_num, _edge_num;
+    int _edge_limit;
+  };
+
+
+  typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief Grid graph class
+  ///
+  /// 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
+  /// \image latex grid_graph.eps "Grid graph" width=\textwidth
+  ///
+  /// A short example about the basic usage:
+  ///\code
+  /// GridGraph graph(rows, cols);
+  /// GridGraph::NodeMap<int> val(graph);
+  /// for (int i = 0; i < graph.width(); ++i) {
+  ///   for (int j = 0; j < graph.height(); ++j) {
+  ///     val[graph(i, j)] = i + j;
+  ///   }
+  /// }
+  ///\endcode
+  ///
+  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes, edges and arcs.
+  class GridGraph : public ExtendedGridGraphBase {
+    typedef ExtendedGridGraphBase Parent;
+
+  public:
+
+    /// \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:
+      /// \brief The key type of the map
+      typedef GridGraph::Node Key;
+      /// \brief The value type of the map
+      typedef dim2::Point<int> Value;
+
+      /// \brief Constructor
+      IndexMap(const GridGraph& graph) : _graph(graph) {}
+
+      /// \brief The subscript operator
+      Value operator[](Key key) const {
+        return _graph.pos(key);
+      }
+
+    private:
+      const GridGraph& _graph;
+    };
+
+    /// \brief Map to get the column of the nodes.
+    ///
+    /// Map to get the column of the nodes.
+    class ColMap {
+    public:
+      /// \brief The key type of the map
+      typedef GridGraph::Node Key;
+      /// \brief The value type of the map
+      typedef int Value;
+
+      /// \brief Constructor
+      ColMap(const GridGraph& graph) : _graph(graph) {}
+
+      /// \brief The subscript operator
+      Value operator[](Key key) const {
+        return _graph.col(key);
+      }
+
+    private:
+      const GridGraph& _graph;
+    };
+
+    /// \brief Map to get the row of the nodes.
+    ///
+    /// Map to get the row of the nodes.
+    class RowMap {
+    public:
+      /// \brief The key type of the map
+      typedef GridGraph::Node Key;
+      /// \brief The value type of the map
+      typedef int Value;
+
+      /// \brief Constructor
+      RowMap(const GridGraph& graph) : _graph(graph) {}
+
+      /// \brief The subscript operator
+      Value operator[](Key key) const {
+        return _graph.row(key);
+      }
+
+    private:
+      const GridGraph& _graph;
+    };
+
+    /// \brief Constructor
+    ///
+    /// Construct a grid graph with the given size.
+    GridGraph(int width, int height) { construct(width, height); }
+
+    /// \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();
+      Parent::notifier(Edge()).clear();
+      Parent::notifier(Node()).clear();
+      construct(width, height);
+      Parent::notifier(Node()).build();
+      Parent::notifier(Edge()).build();
+      Parent::notifier(Arc()).build();
+    }
+
+    /// \brief The node on the given position.
+    ///
+    /// Gives back the node on the given position.
+    Node operator()(int i, int j) const {
+      return Parent::operator()(i, j);
+    }
+
+    /// \brief The column index of the node.
+    ///
+    /// Gives back the column index of the node.
+    int col(Node n) const {
+      return Parent::col(n);
+    }
+
+    /// \brief The row index of the node.
+    ///
+    /// Gives back the row index of the node.
+    int row(Node n) const {
+      return Parent::row(n);
+    }
+
+    /// \brief The position of the node.
+    ///
+    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
+    dim2::Point<int> pos(Node n) const {
+      return Parent::pos(n);
+    }
+
+    /// \brief The number of the columns.
+    ///
+    /// Gives back the number of the columns.
+    int width() const {
+      return Parent::width();
+    }
+
+    /// \brief The number of the rows.
+    ///
+    /// Gives back the number of the rows.
+    int height() const {
+      return Parent::height();
+    }
+
+    /// \brief The arc goes right from the node.
+    ///
+    /// Gives back the arc goes right from the node. If there is not
+    /// outgoing arc then it gives back INVALID.
+    Arc right(Node n) const {
+      return Parent::right(n);
+    }
+
+    /// \brief The arc goes left from the node.
+    ///
+    /// Gives back the arc goes left from the node. If there is not
+    /// outgoing arc then it gives back INVALID.
+    Arc left(Node n) const {
+      return Parent::left(n);
+    }
+
+    /// \brief The arc goes up from the node.
+    ///
+    /// Gives back the arc goes up from the node. If there is not
+    /// outgoing arc then it gives back INVALID.
+    Arc up(Node n) const {
+      return Parent::up(n);
+    }
+
+    /// \brief The arc goes down from the node.
+    ///
+    /// Gives back the arc goes down from the node. If there is not
+    /// outgoing arc then it gives back INVALID.
+    Arc down(Node n) const {
+      return Parent::down(n);
+    }
+
+    /// \brief Index map of the grid graph
+    ///
+    /// Just returns an IndexMap for the grid graph.
+    IndexMap indexMap() const {
+      return IndexMap(*this);
+    }
+
+    /// \brief Row map of the grid graph
+    ///
+    /// Just returns a RowMap for the grid graph.
+    RowMap rowMap() const {
+      return RowMap(*this);
+    }
+
+    /// \brief Column map of the grid graph
+    ///
+    /// Just returns a ColMap for the grid graph.
+    ColMap colMap() const {
+      return ColMap(*this);
+    }
+
+  };
+
+}
+#endif
diff --git a/lemon/grosso_locatelli_pullan_mc.h b/lemon/grosso_locatelli_pullan_mc.h
new file mode 100644
index 0000000..669e1fa
--- /dev/null
+++ b/lemon/grosso_locatelli_pullan_mc.h
@@ -0,0 +1,840 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_GROSSO_LOCATELLI_PULLAN_MC_H
+#define LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
+
+/// \ingroup approx_algs
+///
+/// \file
+/// \brief The iterated local search algorithm of Grosso, Locatelli, and Pullan
+/// for the maximum clique problem
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/random.h>
+
+namespace lemon {
+
+  /// \addtogroup approx_algs
+  /// @{
+
+  /// \brief Implementation of the iterated local search algorithm of Grosso,
+  /// Locatelli, and Pullan for the maximum clique problem
+  ///
+  /// \ref GrossoLocatelliPullanMc implements the iterated local search
+  /// algorithm of Grosso, Locatelli, and Pullan for solving the \e maximum
+  /// \e clique \e problem \cite grosso08maxclique.
+  /// It is to find the largest complete subgraph (\e clique) in an
+  /// undirected graph, i.e., the largest set of nodes where each
+  /// pair of nodes is connected.
+  ///
+  /// This class provides a simple but highly efficient and robust heuristic
+  /// method that quickly finds a quite large clique, but not necessarily the
+  /// largest one.
+  /// The algorithm performs a certain number of iterations to find several
+  /// cliques and selects the largest one among them. Various limits can be
+  /// specified to control the running time and the effectiveness of the
+  /// search process.
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  ///
+  /// \note %GrossoLocatelliPullanMc provides three different node selection
+  /// rules, from which the most powerful one is used by default.
+  /// For more information, see \ref SelectionRule.
+  template <typename GR>
+  class GrossoLocatelliPullanMc
+  {
+  public:
+
+    /// \brief Constants for specifying the node selection rule.
+    ///
+    /// Enum type containing constants for specifying the node selection rule
+    /// for the \ref run() function.
+    ///
+    /// During the algorithm, nodes are selected for addition to the current
+    /// clique according to the applied rule.
+    /// In general, the PENALTY_BASED rule turned out to be the most powerful
+    /// and the most robust, thus it is the default option.
+    /// However, another selection rule can be specified using the \ref run()
+    /// function with the proper parameter.
+    enum SelectionRule {
+
+      /// A node is selected randomly without any evaluation at each step.
+      RANDOM,
+
+      /// A node of maximum degree is selected randomly at each step.
+      DEGREE_BASED,
+
+      /// A node of minimum penalty is selected randomly at each step.
+      /// The node penalties are updated adaptively after each stage of the
+      /// search process.
+      PENALTY_BASED
+    };
+
+    /// \brief Constants for the causes of search termination.
+    ///
+    /// Enum type containing constants for the different causes of search
+    /// termination. The \ref run() function returns one of these values.
+    enum TerminationCause {
+
+      /// The iteration count limit is reached.
+      ITERATION_LIMIT,
+
+      /// The step count limit is reached.
+      STEP_LIMIT,
+
+      /// The clique size limit is reached.
+      SIZE_LIMIT
+    };
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(GR);
+
+    typedef std::vector<int> IntVector;
+    typedef std::vector<char> BoolVector;
+    typedef std::vector<BoolVector> BoolMatrix;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
+
+    // The underlying graph
+    const GR &_graph;
+    IntNodeMap _id;
+
+    // Internal matrix representation of the graph
+    BoolMatrix _gr;
+    int _n;
+
+    // Search options
+    bool _delta_based_restart;
+    int _restart_delta_limit;
+
+    // Search limits
+    int _iteration_limit;
+    int _step_limit;
+    int _size_limit;
+
+    // The current clique
+    BoolVector _clique;
+    int _size;
+
+    // The best clique found so far
+    BoolVector _best_clique;
+    int _best_size;
+
+    // The "distances" of the nodes from the current clique.
+    // _delta[u] is the number of nodes in the clique that are
+    // not connected with u.
+    IntVector _delta;
+
+    // The current tabu set
+    BoolVector _tabu;
+
+    // Random number generator
+    Random _rnd;
+
+  private:
+
+    // Implementation of the RANDOM node selection rule.
+    class RandomSelectionRule
+    {
+    private:
+
+      // References to the algorithm instance
+      const BoolVector &_clique;
+      const IntVector  &_delta;
+      const BoolVector &_tabu;
+      Random &_rnd;
+
+      // Pivot rule data
+      int _n;
+
+    public:
+
+      // Constructor
+      RandomSelectionRule(GrossoLocatelliPullanMc &mc) :
+        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
+        _rnd(mc._rnd), _n(mc._n)
+      {}
+
+      // Return a node index for a feasible add move or -1 if no one exists
+      int nextFeasibleAddNode() const {
+        int start_node = _rnd[_n];
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && !_tabu[i]) return i;
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && !_tabu[i]) return i;
+        }
+        return -1;
+      }
+
+      // Return a node index for a feasible swap move or -1 if no one exists
+      int nextFeasibleSwapNode() const {
+        int start_node = _rnd[_n];
+        for (int i = start_node; i != _n; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i]) return i;
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i]) return i;
+        }
+        return -1;
+      }
+
+      // Return a node index for an add move or -1 if no one exists
+      int nextAddNode() const {
+        int start_node = _rnd[_n];
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0) return i;
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0) return i;
+        }
+        return -1;
+      }
+
+      // Update internal data structures between stages (if necessary)
+      void update() {}
+
+    }; //class RandomSelectionRule
+
+
+    // Implementation of the DEGREE_BASED node selection rule.
+    class DegreeBasedSelectionRule
+    {
+    private:
+
+      // References to the algorithm instance
+      const BoolVector &_clique;
+      const IntVector  &_delta;
+      const BoolVector &_tabu;
+      Random &_rnd;
+
+      // Pivot rule data
+      int _n;
+      IntVector _deg;
+
+    public:
+
+      // Constructor
+      DegreeBasedSelectionRule(GrossoLocatelliPullanMc &mc) :
+        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
+        _rnd(mc._rnd), _n(mc._n), _deg(_n)
+      {
+        for (int i = 0; i != _n; i++) {
+          int d = 0;
+          BoolVector &row = mc._gr[i];
+          for (int j = 0; j != _n; j++) {
+            if (row[j]) d++;
+          }
+          _deg[i] = d;
+        }
+      }
+
+      // Return a node index for a feasible add move or -1 if no one exists
+      int nextFeasibleAddNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, max_deg = -1;
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && !_tabu[i] && _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && !_tabu[i] && _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        return node;
+      }
+
+      // Return a node index for a feasible swap move or -1 if no one exists
+      int nextFeasibleSwapNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, max_deg = -1;
+        for (int i = start_node; i != _n; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
+              _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
+              _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        return node;
+      }
+
+      // Return a node index for an add move or -1 if no one exists
+      int nextAddNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, max_deg = -1;
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        return node;
+      }
+
+      // Update internal data structures between stages (if necessary)
+      void update() {}
+
+    }; //class DegreeBasedSelectionRule
+
+
+    // Implementation of the PENALTY_BASED node selection rule.
+    class PenaltyBasedSelectionRule
+    {
+    private:
+
+      // References to the algorithm instance
+      const BoolVector &_clique;
+      const IntVector  &_delta;
+      const BoolVector &_tabu;
+      Random &_rnd;
+
+      // Pivot rule data
+      int _n;
+      IntVector _penalty;
+
+    public:
+
+      // Constructor
+      PenaltyBasedSelectionRule(GrossoLocatelliPullanMc &mc) :
+        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
+        _rnd(mc._rnd), _n(mc._n), _penalty(_n, 0)
+      {}
+
+      // Return a node index for a feasible add move or -1 if no one exists
+      int nextFeasibleAddNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, min_p = std::numeric_limits<int>::max();
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && !_tabu[i] && _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && !_tabu[i] && _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        return node;
+      }
+
+      // Return a node index for a feasible swap move or -1 if no one exists
+      int nextFeasibleSwapNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, min_p = std::numeric_limits<int>::max();
+        for (int i = start_node; i != _n; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
+              _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
+              _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        return node;
+      }
+
+      // Return a node index for an add move or -1 if no one exists
+      int nextAddNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, min_p = std::numeric_limits<int>::max();
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        return node;
+      }
+
+      // Update internal data structures between stages (if necessary)
+      void update() {}
+
+    }; //class PenaltyBasedSelectionRule
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// The global \ref rnd "random number generator instance" is used
+    /// during the algorithm.
+    ///
+    /// \param graph The undirected graph the algorithm runs on.
+    GrossoLocatelliPullanMc(const GR& graph) :
+      _graph(graph), _id(_graph), _rnd(rnd)
+    {
+      initOptions();
+    }
+
+    /// \brief Constructor with random seed.
+    ///
+    /// Constructor with random seed.
+    ///
+    /// \param graph The undirected graph the algorithm runs on.
+    /// \param seed Seed value for the internal random number generator
+    /// that is used during the algorithm.
+    GrossoLocatelliPullanMc(const GR& graph, int seed) :
+      _graph(graph), _id(_graph), _rnd(seed)
+    {
+      initOptions();
+    }
+
+    /// \brief Constructor with random number generator.
+    ///
+    /// Constructor with random number generator.
+    ///
+    /// \param graph The undirected graph the algorithm runs on.
+    /// \param random A random number generator that is used during the
+    /// algorithm.
+    GrossoLocatelliPullanMc(const GR& graph, const Random& random) :
+      _graph(graph), _id(_graph), _rnd(random)
+    {
+      initOptions();
+    }
+
+    /// \name Execution Control
+    /// The \ref run() function can be used to execute the algorithm.\n
+    /// The functions \ref iterationLimit(int), \ref stepLimit(int), and
+    /// \ref sizeLimit(int) can be used to specify various limits for the
+    /// search process.
+
+    /// @{
+
+    /// \brief Sets the maximum number of iterations.
+    ///
+    /// This function sets the maximum number of iterations.
+    /// Each iteration of the algorithm finds a maximal clique (but not
+    /// necessarily the largest one) by performing several search steps
+    /// (node selections).
+    ///
+    /// This limit controls the running time and the success of the
+    /// algorithm. For larger values, the algorithm runs slower, but it more
+    /// likely finds larger cliques. For smaller values, the algorithm is
+    /// faster but probably gives worse results.
+    ///
+    /// The default value is \c 1000.
+    /// \c -1 means that number of iterations is not limited.
+    ///
+    /// \warning You should specify a reasonable limit for the number of
+    /// iterations and/or the number of search steps.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \sa stepLimit(int)
+    /// \sa sizeLimit(int)
+    GrossoLocatelliPullanMc& iterationLimit(int limit) {
+      _iteration_limit = limit;
+      return *this;
+    }
+
+    /// \brief Sets the maximum number of search steps.
+    ///
+    /// This function sets the maximum number of elementary search steps.
+    /// Each iteration of the algorithm finds a maximal clique (but not
+    /// necessarily the largest one) by performing several search steps
+    /// (node selections).
+    ///
+    /// This limit controls the running time and the success of the
+    /// algorithm. For larger values, the algorithm runs slower, but it more
+    /// likely finds larger cliques. For smaller values, the algorithm is
+    /// faster but probably gives worse results.
+    ///
+    /// The default value is \c -1, which means that number of steps
+    /// is not limited explicitly. However, the number of iterations is
+    /// limited and each iteration performs a finite number of search steps.
+    ///
+    /// \warning You should specify a reasonable limit for the number of
+    /// iterations and/or the number of search steps.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \sa iterationLimit(int)
+    /// \sa sizeLimit(int)
+    GrossoLocatelliPullanMc& stepLimit(int limit) {
+      _step_limit = limit;
+      return *this;
+    }
+
+    /// \brief Sets the desired clique size.
+    ///
+    /// This function sets the desired clique size that serves as a search
+    /// limit. If a clique of this size (or a larger one) is found, then the
+    /// algorithm terminates.
+    ///
+    /// This function is especially useful if you know an exact upper bound
+    /// for the size of the cliques in the graph or if any clique above
+    /// a certain size limit is sufficient for your application.
+    ///
+    /// The default value is \c -1, which means that the size limit is set to
+    /// the number of nodes in the graph.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \sa iterationLimit(int)
+    /// \sa stepLimit(int)
+    GrossoLocatelliPullanMc& sizeLimit(int limit) {
+      _size_limit = limit;
+      return *this;
+    }
+
+    /// \brief The maximum number of iterations.
+    ///
+    /// This function gives back the maximum number of iterations.
+    /// \c -1 means that no limit is specified.
+    ///
+    /// \sa iterationLimit(int)
+    int iterationLimit() const {
+      return _iteration_limit;
+    }
+
+    /// \brief The maximum number of search steps.
+    ///
+    /// This function gives back the maximum number of search steps.
+    /// \c -1 means that no limit is specified.
+    ///
+    /// \sa stepLimit(int)
+    int stepLimit() const {
+      return _step_limit;
+    }
+
+    /// \brief The desired clique size.
+    ///
+    /// This function gives back the desired clique size that serves as a
+    /// search limit. \c -1 means that this limit is set to the number of
+    /// nodes in the graph.
+    ///
+    /// \sa sizeLimit(int)
+    int sizeLimit() const {
+      return _size_limit;
+    }
+
+    /// \brief Runs the algorithm.
+    ///
+    /// This function runs the algorithm. If one of the specified limits
+    /// is reached, the search process terminates.
+    ///
+    /// \param rule The node selection rule. For more information, see
+    /// \ref SelectionRule.
+    ///
+    /// \return The termination cause of the search. For more information,
+    /// see \ref TerminationCause.
+    TerminationCause run(SelectionRule rule = PENALTY_BASED)
+    {
+      init();
+      switch (rule) {
+        case RANDOM:
+          return start<RandomSelectionRule>();
+        case DEGREE_BASED:
+          return start<DegreeBasedSelectionRule>();
+        default:
+          return start<PenaltyBasedSelectionRule>();
+      }
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these functions.\n
+    /// The run() function must be called before using them.
+
+    /// @{
+
+    /// \brief The size of the found clique
+    ///
+    /// This function returns the size of the found clique.
+    ///
+    /// \pre run() must be called before using this function.
+    int cliqueSize() const {
+      return _best_size;
+    }
+
+    /// \brief Gives back the found clique in a \c bool node map
+    ///
+    /// This function gives back the characteristic vector of the found
+    /// clique in the given node map.
+    /// It must be a \ref concepts::WriteMap "writable" node map with
+    /// \c bool (or convertible) value type.
+    ///
+    /// \pre run() must be called before using this function.
+    template <typename CliqueMap>
+    void cliqueMap(CliqueMap &map) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        map[n] = static_cast<bool>(_best_clique[_id[n]]);
+      }
+    }
+
+    /// \brief Iterator to list the nodes of the found clique
+    ///
+    /// This iterator class lists the nodes of the found clique.
+    /// Before using it, you must allocate a GrossoLocatelliPullanMc instance
+    /// and call its \ref GrossoLocatelliPullanMc::run() "run()" method.
+    ///
+    /// The following example prints out the IDs of the nodes in the found
+    /// clique.
+    /// \code
+    ///   GrossoLocatelliPullanMc<Graph> mc(g);
+    ///   mc.run();
+    ///   for (GrossoLocatelliPullanMc<Graph>::CliqueNodeIt n(mc);
+    ///        n != INVALID; ++n)
+    ///   {
+    ///     std::cout << g.id(n) << std::endl;
+    ///   }
+    /// \endcode
+    class CliqueNodeIt
+    {
+    private:
+      NodeIt _it;
+      BoolNodeMap _map;
+
+    public:
+
+      /// Constructor
+
+      /// Constructor.
+      /// \param mc The algorithm instance.
+      CliqueNodeIt(const GrossoLocatelliPullanMc &mc)
+       : _map(mc._graph)
+      {
+        mc.cliqueMap(_map);
+        for (_it = NodeIt(mc._graph); _it != INVALID && !_map[_it]; ++_it) ;
+      }
+
+      /// Conversion to \c Node
+      operator Node() const { return _it; }
+
+      bool operator==(Invalid) const { return _it == INVALID; }
+      bool operator!=(Invalid) const { return _it != INVALID; }
+
+      /// Next node
+      CliqueNodeIt &operator++() {
+        for (++_it; _it != INVALID && !_map[_it]; ++_it) ;
+        return *this;
+      }
+
+      /// Postfix incrementation
+
+      /// Postfix incrementation.
+      ///
+      /// \warning This incrementation returns a \c Node, not a
+      /// \c CliqueNodeIt as one may expect.
+      typename GR::Node operator++(int) {
+        Node n=*this;
+        ++(*this);
+        return n;
+      }
+
+    };
+
+    /// @}
+
+  private:
+
+    // Initialize search options and limits
+    void initOptions() {
+      // Search options
+      _delta_based_restart = true;
+      _restart_delta_limit = 4;
+
+      // Search limits
+      _iteration_limit = 1000;
+      _step_limit = -1;             // this is disabled by default
+      _size_limit = -1;             // this is disabled by default
+    }
+
+    // Adds a node to the current clique
+    void addCliqueNode(int u) {
+      if (_clique[u]) return;
+      _clique[u] = true;
+      _size++;
+      BoolVector &row = _gr[u];
+      for (int i = 0; i != _n; i++) {
+        if (!row[i]) _delta[i]++;
+      }
+    }
+
+    // Removes a node from the current clique
+    void delCliqueNode(int u) {
+      if (!_clique[u]) return;
+      _clique[u] = false;
+      _size--;
+      BoolVector &row = _gr[u];
+      for (int i = 0; i != _n; i++) {
+        if (!row[i]) _delta[i]--;
+      }
+    }
+
+    // Initialize data structures
+    void init() {
+      _n = countNodes(_graph);
+      int ui = 0;
+      for (NodeIt u(_graph); u != INVALID; ++u) {
+        _id[u] = ui++;
+      }
+      _gr.clear();
+      _gr.resize(_n, BoolVector(_n, false));
+      ui = 0;
+      for (NodeIt u(_graph); u != INVALID; ++u) {
+        for (IncEdgeIt e(_graph, u); e != INVALID; ++e) {
+          int vi = _id[_graph.runningNode(e)];
+          _gr[ui][vi] = true;
+          _gr[vi][ui] = true;
+        }
+        ++ui;
+      }
+
+      _clique.clear();
+      _clique.resize(_n, false);
+      _size = 0;
+      _best_clique.clear();
+      _best_clique.resize(_n, false);
+      _best_size = 0;
+      _delta.clear();
+      _delta.resize(_n, 0);
+      _tabu.clear();
+      _tabu.resize(_n, false);
+    }
+
+    // Executes the algorithm
+    template <typename SelectionRuleImpl>
+    TerminationCause start() {
+      if (_n == 0) return SIZE_LIMIT;
+      if (_n == 1) {
+        _best_clique[0] = true;
+        _best_size = 1;
+        return SIZE_LIMIT;
+      }
+
+      // Iterated local search algorithm
+      const int max_size = _size_limit >= 0 ? _size_limit : _n;
+      const int max_restart = _iteration_limit >= 0 ?
+        _iteration_limit : std::numeric_limits<int>::max();
+      const int max_select = _step_limit >= 0 ?
+        _step_limit : std::numeric_limits<int>::max();
+
+      SelectionRuleImpl sel_method(*this);
+      int select = 0, restart = 0;
+      IntVector restart_nodes;
+      while (select < max_select && restart < max_restart) {
+
+        // Perturbation/restart
+        restart++;
+        if (_delta_based_restart) {
+          restart_nodes.clear();
+          for (int i = 0; i != _n; i++) {
+            if (_delta[i] >= _restart_delta_limit)
+              restart_nodes.push_back(i);
+          }
+        }
+        int rs_node = -1;
+        if (restart_nodes.size() > 0) {
+          rs_node = restart_nodes[_rnd[restart_nodes.size()]];
+        } else {
+          rs_node = _rnd[_n];
+        }
+        BoolVector &row = _gr[rs_node];
+        for (int i = 0; i != _n; i++) {
+          if (_clique[i] && !row[i]) delCliqueNode(i);
+        }
+        addCliqueNode(rs_node);
+
+        // Local search
+        _tabu.clear();
+        _tabu.resize(_n, false);
+        bool tabu_empty = true;
+        int max_swap = _size;
+        while (select < max_select) {
+          select++;
+          int u;
+          if ((u = sel_method.nextFeasibleAddNode()) != -1) {
+            // Feasible add move
+            addCliqueNode(u);
+            if (tabu_empty) max_swap = _size;
+          }
+          else if ((u = sel_method.nextFeasibleSwapNode()) != -1) {
+            // Feasible swap move
+            int v = -1;
+            BoolVector &row = _gr[u];
+            for (int i = 0; i != _n; i++) {
+              if (_clique[i] && !row[i]) {
+                v = i;
+                break;
+              }
+            }
+            addCliqueNode(u);
+            delCliqueNode(v);
+            _tabu[v] = true;
+            tabu_empty = false;
+            if (--max_swap <= 0) break;
+          }
+          else if ((u = sel_method.nextAddNode()) != -1) {
+            // Non-feasible add move
+            addCliqueNode(u);
+          }
+          else break;
+        }
+        if (_size > _best_size) {
+          _best_clique = _clique;
+          _best_size = _size;
+          if (_best_size >= max_size) return SIZE_LIMIT;
+        }
+        sel_method.update();
+      }
+
+      return (restart >= max_restart ? ITERATION_LIMIT : STEP_LIMIT);
+    }
+
+  }; //class GrossoLocatelliPullanMc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
diff --git a/lemon/hao_orlin.h b/lemon/hao_orlin.h
new file mode 100644
index 0000000..0eeaff9
--- /dev/null
+++ b/lemon/hao_orlin.h
@@ -0,0 +1,1015 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_HAO_ORLIN_H
+#define LEMON_HAO_ORLIN_H
+
+#include <vector>
+#include <list>
+#include <limits>
+
+#include <lemon/maps.h>
+#include <lemon/core.h>
+#include <lemon/tolerance.h>
+
+/// \file
+/// \ingroup min_cut
+/// \brief Implementation of the Hao-Orlin algorithm.
+///
+/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
+/// in a digraph.
+
+namespace lemon {
+
+  /// \ingroup min_cut
+  ///
+  /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
+  ///
+  /// This class implements the Hao-Orlin algorithm for finding a minimum
+  /// value cut in a directed graph \f$D=(V,A)\f$.
+  /// It takes a fixed node \f$ source \in V \f$ and
+  /// consists of two phases: in the first phase it determines a
+  /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
+  /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal outgoing
+  /// capacity) and in the second phase it determines a minimum cut
+  /// with \f$ source \f$ on the sink-side (i.e. a set
+  /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal outgoing
+  /// capacity). Obviously, the smaller of these two cuts will be a
+  /// minimum cut of \f$ D \f$. The algorithm is a modified
+  /// preflow push-relabel algorithm. Our implementation calculates
+  /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
+  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. A notable
+  /// use of this algorithm is testing network reliability.
+  ///
+  /// For an undirected graph you can run just the first phase of the
+  /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
+  /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$
+  /// time. It is implemented in the NagamochiIbaraki algorithm class.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CAP The type of the arc map containing the capacities,
+  /// which can be any numreric type. The default map type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TOL Tolerance class for handling inexact computations. The
+  /// default tolerance type is \ref Tolerance "Tolerance<CAP::Value>".
+#ifdef DOXYGEN
+  template <typename GR, typename CAP, typename TOL>
+#else
+  template <typename GR,
+            typename CAP = typename GR::template ArcMap<int>,
+            typename TOL = Tolerance<typename CAP::Value> >
+#endif
+  class HaoOrlin {
+  public:
+
+    /// The digraph type of the algorithm
+    typedef GR Digraph;
+    /// The capacity map type of the algorithm
+    typedef CAP CapacityMap;
+    /// The tolerance type of the algorithm
+    typedef TOL Tolerance;
+
+  private:
+
+    typedef typename CapacityMap::Value Value;
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    const Digraph& _graph;
+    const CapacityMap* _capacity;
+
+    typedef typename Digraph::template ArcMap<Value> FlowMap;
+    FlowMap* _flow;
+
+    Node _source;
+
+    int _node_num;
+
+    // Bucketing structure
+    std::vector<Node> _first, _last;
+    typename Digraph::template NodeMap<Node>* _next;
+    typename Digraph::template NodeMap<Node>* _prev;
+    typename Digraph::template NodeMap<bool>* _active;
+    typename Digraph::template NodeMap<int>* _bucket;
+
+    std::vector<bool> _dormant;
+
+    std::list<std::list<int> > _sets;
+    std::list<int>::iterator _highest;
+
+    typedef typename Digraph::template NodeMap<Value> ExcessMap;
+    ExcessMap* _excess;
+
+    typedef typename Digraph::template NodeMap<bool> SourceSetMap;
+    SourceSetMap* _source_set;
+
+    Value _min_cut;
+
+    typedef typename Digraph::template NodeMap<bool> MinCutMap;
+    MinCutMap* _min_cut_map;
+
+    Tolerance _tolerance;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor of the algorithm class.
+    HaoOrlin(const Digraph& graph, const CapacityMap& capacity,
+             const Tolerance& tolerance = Tolerance()) :
+      _graph(graph), _capacity(&capacity), _flow(0), _source(),
+      _node_num(), _first(), _last(), _next(0), _prev(0),
+      _active(0), _bucket(0), _dormant(), _sets(), _highest(),
+      _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
+      _tolerance(tolerance) {}
+
+    ~HaoOrlin() {
+      if (_min_cut_map) {
+        delete _min_cut_map;
+      }
+      if (_source_set) {
+        delete _source_set;
+      }
+      if (_excess) {
+        delete _excess;
+      }
+      if (_next) {
+        delete _next;
+      }
+      if (_prev) {
+        delete _prev;
+      }
+      if (_active) {
+        delete _active;
+      }
+      if (_bucket) {
+        delete _bucket;
+      }
+      if (_flow) {
+        delete _flow;
+      }
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    /// \return <tt>(*this)</tt>
+    HaoOrlin& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+  private:
+
+    void activate(const Node& i) {
+      (*_active)[i] = true;
+
+      int bucket = (*_bucket)[i];
+
+      if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
+      //unlace
+      (*_next)[(*_prev)[i]] = (*_next)[i];
+      if ((*_next)[i] != INVALID) {
+        (*_prev)[(*_next)[i]] = (*_prev)[i];
+      } else {
+        _last[bucket] = (*_prev)[i];
+      }
+      //lace
+      (*_next)[i] = _first[bucket];
+      (*_prev)[_first[bucket]] = i;
+      (*_prev)[i] = INVALID;
+      _first[bucket] = i;
+    }
+
+    void deactivate(const Node& i) {
+      (*_active)[i] = false;
+      int bucket = (*_bucket)[i];
+
+      if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
+
+      //unlace
+      (*_prev)[(*_next)[i]] = (*_prev)[i];
+      if ((*_prev)[i] != INVALID) {
+        (*_next)[(*_prev)[i]] = (*_next)[i];
+      } else {
+        _first[bucket] = (*_next)[i];
+      }
+      //lace
+      (*_prev)[i] = _last[bucket];
+      (*_next)[_last[bucket]] = i;
+      (*_next)[i] = INVALID;
+      _last[bucket] = i;
+    }
+
+    void addItem(const Node& i, int bucket) {
+      (*_bucket)[i] = bucket;
+      if (_last[bucket] != INVALID) {
+        (*_prev)[i] = _last[bucket];
+        (*_next)[_last[bucket]] = i;
+        (*_next)[i] = INVALID;
+        _last[bucket] = i;
+      } else {
+        (*_prev)[i] = INVALID;
+        _first[bucket] = i;
+        (*_next)[i] = INVALID;
+        _last[bucket] = i;
+      }
+    }
+
+    void findMinCutOut() {
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_excess)[n] = 0;
+        (*_source_set)[n] = false;
+      }
+
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        (*_flow)[a] = 0;
+      }
+
+      int bucket_num = 0;
+      std::vector<Node> queue(_node_num);
+      int qfirst = 0, qlast = 0, qsep = 0;
+
+      {
+        typename Digraph::template NodeMap<bool> reached(_graph, false);
+
+        reached[_source] = true;
+        bool first_set = true;
+
+        for (NodeIt t(_graph); t != INVALID; ++t) {
+          if (reached[t]) continue;
+          _sets.push_front(std::list<int>());
+
+          queue[qlast++] = t;
+          reached[t] = true;
+
+          while (qfirst != qlast) {
+            if (qsep == qfirst) {
+              ++bucket_num;
+              _sets.front().push_front(bucket_num);
+              _dormant[bucket_num] = !first_set;
+              _first[bucket_num] = _last[bucket_num] = INVALID;
+              qsep = qlast;
+            }
+
+            Node n = queue[qfirst++];
+            addItem(n, bucket_num);
+
+            for (InArcIt a(_graph, n); a != INVALID; ++a) {
+              Node u = _graph.source(a);
+              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
+                reached[u] = true;
+                queue[qlast++] = u;
+              }
+            }
+          }
+          first_set = false;
+        }
+
+        ++bucket_num;
+        (*_bucket)[_source] = 0;
+        _dormant[0] = true;
+      }
+      (*_source_set)[_source] = true;
+
+      Node target = _last[_sets.back().back()];
+      {
+        for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
+          if (_tolerance.positive((*_capacity)[a])) {
+            Node u = _graph.target(a);
+            (*_flow)[a] = (*_capacity)[a];
+            (*_excess)[u] += (*_capacity)[a];
+            if (!(*_active)[u] && u != _source) {
+              activate(u);
+            }
+          }
+        }
+
+        if ((*_active)[target]) {
+          deactivate(target);
+        }
+
+        _highest = _sets.back().begin();
+        while (_highest != _sets.back().end() &&
+               !(*_active)[_first[*_highest]]) {
+          ++_highest;
+        }
+      }
+
+      while (true) {
+        while (_highest != _sets.back().end()) {
+          Node n = _first[*_highest];
+          Value excess = (*_excess)[n];
+          int next_bucket = _node_num;
+
+          int under_bucket;
+          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
+            under_bucket = -1;
+          } else {
+            under_bucket = *(++std::list<int>::iterator(_highest));
+          }
+
+          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+            Node v = _graph.target(a);
+            if (_dormant[(*_bucket)[v]]) continue;
+            Value rem = (*_capacity)[a] - (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            if ((*_bucket)[v] == under_bucket) {
+              if (!(*_active)[v] && v != target) {
+                activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                (*_flow)[a] += excess;
+                (*_excess)[v] += excess;
+                excess = 0;
+                goto no_more_push;
+              } else {
+                excess -= rem;
+                (*_excess)[v] += rem;
+                (*_flow)[a] = (*_capacity)[a];
+              }
+            } else if (next_bucket > (*_bucket)[v]) {
+              next_bucket = (*_bucket)[v];
+            }
+          }
+
+          for (InArcIt a(_graph, n); a != INVALID; ++a) {
+            Node v = _graph.source(a);
+            if (_dormant[(*_bucket)[v]]) continue;
+            Value rem = (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            if ((*_bucket)[v] == under_bucket) {
+              if (!(*_active)[v] && v != target) {
+                activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                (*_flow)[a] -= excess;
+                (*_excess)[v] += excess;
+                excess = 0;
+                goto no_more_push;
+              } else {
+                excess -= rem;
+                (*_excess)[v] += rem;
+                (*_flow)[a] = 0;
+              }
+            } else if (next_bucket > (*_bucket)[v]) {
+              next_bucket = (*_bucket)[v];
+            }
+          }
+
+        no_more_push:
+
+          (*_excess)[n] = excess;
+
+          if (excess != 0) {
+            if ((*_next)[n] == INVALID) {
+              typename std::list<std::list<int> >::iterator new_set =
+                _sets.insert(--_sets.end(), std::list<int>());
+              new_set->splice(new_set->end(), _sets.back(),
+                              _sets.back().begin(), ++_highest);
+              for (std::list<int>::iterator it = new_set->begin();
+                   it != new_set->end(); ++it) {
+                _dormant[*it] = true;
+              }
+              while (_highest != _sets.back().end() &&
+                     !(*_active)[_first[*_highest]]) {
+                ++_highest;
+              }
+            } else if (next_bucket == _node_num) {
+              _first[(*_bucket)[n]] = (*_next)[n];
+              (*_prev)[(*_next)[n]] = INVALID;
+
+              std::list<std::list<int> >::iterator new_set =
+                _sets.insert(--_sets.end(), std::list<int>());
+
+              new_set->push_front(bucket_num);
+              (*_bucket)[n] = bucket_num;
+              _first[bucket_num] = _last[bucket_num] = n;
+              (*_next)[n] = INVALID;
+              (*_prev)[n] = INVALID;
+              _dormant[bucket_num] = true;
+              ++bucket_num;
+
+              while (_highest != _sets.back().end() &&
+                     !(*_active)[_first[*_highest]]) {
+                ++_highest;
+              }
+            } else {
+              _first[*_highest] = (*_next)[n];
+              (*_prev)[(*_next)[n]] = INVALID;
+
+              while (next_bucket != *_highest) {
+                --_highest;
+              }
+
+              if (_highest == _sets.back().begin()) {
+                _sets.back().push_front(bucket_num);
+                _dormant[bucket_num] = false;
+                _first[bucket_num] = _last[bucket_num] = INVALID;
+                ++bucket_num;
+              }
+              --_highest;
+
+              (*_bucket)[n] = *_highest;
+              (*_next)[n] = _first[*_highest];
+              if (_first[*_highest] != INVALID) {
+                (*_prev)[_first[*_highest]] = n;
+              } else {
+                _last[*_highest] = n;
+              }
+              _first[*_highest] = n;
+            }
+          } else {
+
+            deactivate(n);
+            if (!(*_active)[_first[*_highest]]) {
+              ++_highest;
+              if (_highest != _sets.back().end() &&
+                  !(*_active)[_first[*_highest]]) {
+                _highest = _sets.back().end();
+              }
+            }
+          }
+        }
+
+        if ((*_excess)[target] < _min_cut) {
+          _min_cut = (*_excess)[target];
+          for (NodeIt i(_graph); i != INVALID; ++i) {
+            (*_min_cut_map)[i] = true;
+          }
+          for (std::list<int>::iterator it = _sets.back().begin();
+               it != _sets.back().end(); ++it) {
+            Node n = _first[*it];
+            while (n != INVALID) {
+              (*_min_cut_map)[n] = false;
+              n = (*_next)[n];
+            }
+          }
+        }
+
+        {
+          Node new_target;
+          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
+            if ((*_next)[target] == INVALID) {
+              _last[(*_bucket)[target]] = (*_prev)[target];
+              new_target = (*_prev)[target];
+            } else {
+              (*_prev)[(*_next)[target]] = (*_prev)[target];
+              new_target = (*_next)[target];
+            }
+            if ((*_prev)[target] == INVALID) {
+              _first[(*_bucket)[target]] = (*_next)[target];
+            } else {
+              (*_next)[(*_prev)[target]] = (*_next)[target];
+            }
+          } else {
+            _sets.back().pop_back();
+            if (_sets.back().empty()) {
+              _sets.pop_back();
+              if (_sets.empty())
+                break;
+              for (std::list<int>::iterator it = _sets.back().begin();
+                   it != _sets.back().end(); ++it) {
+                _dormant[*it] = false;
+              }
+            }
+            new_target = _last[_sets.back().back()];
+          }
+
+          (*_bucket)[target] = 0;
+
+          (*_source_set)[target] = true;
+          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
+            Value rem = (*_capacity)[a] - (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.target(a);
+            if (!(*_active)[v] && !(*_source_set)[v]) {
+              activate(v);
+            }
+            (*_excess)[v] += rem;
+            (*_flow)[a] = (*_capacity)[a];
+          }
+
+          for (InArcIt a(_graph, target); a != INVALID; ++a) {
+            Value rem = (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.source(a);
+            if (!(*_active)[v] && !(*_source_set)[v]) {
+              activate(v);
+            }
+            (*_excess)[v] += rem;
+            (*_flow)[a] = 0;
+          }
+
+          target = new_target;
+          if ((*_active)[target]) {
+            deactivate(target);
+          }
+
+          _highest = _sets.back().begin();
+          while (_highest != _sets.back().end() &&
+                 !(*_active)[_first[*_highest]]) {
+            ++_highest;
+          }
+        }
+      }
+    }
+
+    void findMinCutIn() {
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_excess)[n] = 0;
+        (*_source_set)[n] = false;
+      }
+
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        (*_flow)[a] = 0;
+      }
+
+      int bucket_num = 0;
+      std::vector<Node> queue(_node_num);
+      int qfirst = 0, qlast = 0, qsep = 0;
+
+      {
+        typename Digraph::template NodeMap<bool> reached(_graph, false);
+
+        reached[_source] = true;
+
+        bool first_set = true;
+
+        for (NodeIt t(_graph); t != INVALID; ++t) {
+          if (reached[t]) continue;
+          _sets.push_front(std::list<int>());
+
+          queue[qlast++] = t;
+          reached[t] = true;
+
+          while (qfirst != qlast) {
+            if (qsep == qfirst) {
+              ++bucket_num;
+              _sets.front().push_front(bucket_num);
+              _dormant[bucket_num] = !first_set;
+              _first[bucket_num] = _last[bucket_num] = INVALID;
+              qsep = qlast;
+            }
+
+            Node n = queue[qfirst++];
+            addItem(n, bucket_num);
+
+            for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+              Node u = _graph.target(a);
+              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
+                reached[u] = true;
+                queue[qlast++] = u;
+              }
+            }
+          }
+          first_set = false;
+        }
+
+        ++bucket_num;
+        (*_bucket)[_source] = 0;
+        _dormant[0] = true;
+      }
+      (*_source_set)[_source] = true;
+
+      Node target = _last[_sets.back().back()];
+      {
+        for (InArcIt a(_graph, _source); a != INVALID; ++a) {
+          if (_tolerance.positive((*_capacity)[a])) {
+            Node u = _graph.source(a);
+            (*_flow)[a] = (*_capacity)[a];
+            (*_excess)[u] += (*_capacity)[a];
+            if (!(*_active)[u] && u != _source) {
+              activate(u);
+            }
+          }
+        }
+        if ((*_active)[target]) {
+          deactivate(target);
+        }
+
+        _highest = _sets.back().begin();
+        while (_highest != _sets.back().end() &&
+               !(*_active)[_first[*_highest]]) {
+          ++_highest;
+        }
+      }
+
+
+      while (true) {
+        while (_highest != _sets.back().end()) {
+          Node n = _first[*_highest];
+          Value excess = (*_excess)[n];
+          int next_bucket = _node_num;
+
+          int under_bucket;
+          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
+            under_bucket = -1;
+          } else {
+            under_bucket = *(++std::list<int>::iterator(_highest));
+          }
+
+          for (InArcIt a(_graph, n); a != INVALID; ++a) {
+            Node v = _graph.source(a);
+            if (_dormant[(*_bucket)[v]]) continue;
+            Value rem = (*_capacity)[a] - (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            if ((*_bucket)[v] == under_bucket) {
+              if (!(*_active)[v] && v != target) {
+                activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                (*_flow)[a] += excess;
+                (*_excess)[v] += excess;
+                excess = 0;
+                goto no_more_push;
+              } else {
+                excess -= rem;
+                (*_excess)[v] += rem;
+                (*_flow)[a] = (*_capacity)[a];
+              }
+            } else if (next_bucket > (*_bucket)[v]) {
+              next_bucket = (*_bucket)[v];
+            }
+          }
+
+          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+            Node v = _graph.target(a);
+            if (_dormant[(*_bucket)[v]]) continue;
+            Value rem = (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            if ((*_bucket)[v] == under_bucket) {
+              if (!(*_active)[v] && v != target) {
+                activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                (*_flow)[a] -= excess;
+                (*_excess)[v] += excess;
+                excess = 0;
+                goto no_more_push;
+              } else {
+                excess -= rem;
+                (*_excess)[v] += rem;
+                (*_flow)[a] = 0;
+              }
+            } else if (next_bucket > (*_bucket)[v]) {
+              next_bucket = (*_bucket)[v];
+            }
+          }
+
+        no_more_push:
+
+          (*_excess)[n] = excess;
+
+          if (excess != 0) {
+            if ((*_next)[n] == INVALID) {
+              typename std::list<std::list<int> >::iterator new_set =
+                _sets.insert(--_sets.end(), std::list<int>());
+              new_set->splice(new_set->end(), _sets.back(),
+                              _sets.back().begin(), ++_highest);
+              for (std::list<int>::iterator it = new_set->begin();
+                   it != new_set->end(); ++it) {
+                _dormant[*it] = true;
+              }
+              while (_highest != _sets.back().end() &&
+                     !(*_active)[_first[*_highest]]) {
+                ++_highest;
+              }
+            } else if (next_bucket == _node_num) {
+              _first[(*_bucket)[n]] = (*_next)[n];
+              (*_prev)[(*_next)[n]] = INVALID;
+
+              std::list<std::list<int> >::iterator new_set =
+                _sets.insert(--_sets.end(), std::list<int>());
+
+              new_set->push_front(bucket_num);
+              (*_bucket)[n] = bucket_num;
+              _first[bucket_num] = _last[bucket_num] = n;
+              (*_next)[n] = INVALID;
+              (*_prev)[n] = INVALID;
+              _dormant[bucket_num] = true;
+              ++bucket_num;
+
+              while (_highest != _sets.back().end() &&
+                     !(*_active)[_first[*_highest]]) {
+                ++_highest;
+              }
+            } else {
+              _first[*_highest] = (*_next)[n];
+              (*_prev)[(*_next)[n]] = INVALID;
+
+              while (next_bucket != *_highest) {
+                --_highest;
+              }
+              if (_highest == _sets.back().begin()) {
+                _sets.back().push_front(bucket_num);
+                _dormant[bucket_num] = false;
+                _first[bucket_num] = _last[bucket_num] = INVALID;
+                ++bucket_num;
+              }
+              --_highest;
+
+              (*_bucket)[n] = *_highest;
+              (*_next)[n] = _first[*_highest];
+              if (_first[*_highest] != INVALID) {
+                (*_prev)[_first[*_highest]] = n;
+              } else {
+                _last[*_highest] = n;
+              }
+              _first[*_highest] = n;
+            }
+          } else {
+
+            deactivate(n);
+            if (!(*_active)[_first[*_highest]]) {
+              ++_highest;
+              if (_highest != _sets.back().end() &&
+                  !(*_active)[_first[*_highest]]) {
+                _highest = _sets.back().end();
+              }
+            }
+          }
+        }
+
+        if ((*_excess)[target] < _min_cut) {
+          _min_cut = (*_excess)[target];
+          for (NodeIt i(_graph); i != INVALID; ++i) {
+            (*_min_cut_map)[i] = false;
+          }
+          for (std::list<int>::iterator it = _sets.back().begin();
+               it != _sets.back().end(); ++it) {
+            Node n = _first[*it];
+            while (n != INVALID) {
+              (*_min_cut_map)[n] = true;
+              n = (*_next)[n];
+            }
+          }
+        }
+
+        {
+          Node new_target;
+          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
+            if ((*_next)[target] == INVALID) {
+              _last[(*_bucket)[target]] = (*_prev)[target];
+              new_target = (*_prev)[target];
+            } else {
+              (*_prev)[(*_next)[target]] = (*_prev)[target];
+              new_target = (*_next)[target];
+            }
+            if ((*_prev)[target] == INVALID) {
+              _first[(*_bucket)[target]] = (*_next)[target];
+            } else {
+              (*_next)[(*_prev)[target]] = (*_next)[target];
+            }
+          } else {
+            _sets.back().pop_back();
+            if (_sets.back().empty()) {
+              _sets.pop_back();
+              if (_sets.empty())
+                break;
+              for (std::list<int>::iterator it = _sets.back().begin();
+                   it != _sets.back().end(); ++it) {
+                _dormant[*it] = false;
+              }
+            }
+            new_target = _last[_sets.back().back()];
+          }
+
+          (*_bucket)[target] = 0;
+
+          (*_source_set)[target] = true;
+          for (InArcIt a(_graph, target); a != INVALID; ++a) {
+            Value rem = (*_capacity)[a] - (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.source(a);
+            if (!(*_active)[v] && !(*_source_set)[v]) {
+              activate(v);
+            }
+            (*_excess)[v] += rem;
+            (*_flow)[a] = (*_capacity)[a];
+          }
+
+          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
+            Value rem = (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.target(a);
+            if (!(*_active)[v] && !(*_source_set)[v]) {
+              activate(v);
+            }
+            (*_excess)[v] += rem;
+            (*_flow)[a] = 0;
+          }
+
+          target = new_target;
+          if ((*_active)[target]) {
+            deactivate(target);
+          }
+
+          _highest = _sets.back().begin();
+          while (_highest != _sets.back().end() &&
+                 !(*_active)[_first[*_highest]]) {
+            ++_highest;
+          }
+        }
+      }
+    }
+
+  public:
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use
+    /// one of the member functions called \ref run().
+    /// \n
+    /// If you need better control on the execution,
+    /// you have to call one of the \ref init() functions first, then
+    /// \ref calculateOut() and/or \ref calculateIn().
+
+    /// @{
+
+    /// \brief Initialize the internal data structures.
+    ///
+    /// This function initializes the internal data structures. It creates
+    /// the maps and some bucket structures for the algorithm.
+    /// The first node is used as the source node for the push-relabel
+    /// algorithm.
+    void init() {
+      init(NodeIt(_graph));
+    }
+
+    /// \brief Initialize the internal data structures.
+    ///
+    /// This function initializes the internal data structures. It creates
+    /// the maps and some bucket structures for the algorithm.
+    /// The given node is used as the source node for the push-relabel
+    /// algorithm.
+    void init(const Node& source) {
+      _source = source;
+
+      _node_num = countNodes(_graph);
+
+      _first.resize(_node_num);
+      _last.resize(_node_num);
+
+      _dormant.resize(_node_num);
+
+      if (!_flow) {
+        _flow = new FlowMap(_graph);
+      }
+      if (!_next) {
+        _next = new typename Digraph::template NodeMap<Node>(_graph);
+      }
+      if (!_prev) {
+        _prev = new typename Digraph::template NodeMap<Node>(_graph);
+      }
+      if (!_active) {
+        _active = new typename Digraph::template NodeMap<bool>(_graph);
+      }
+      if (!_bucket) {
+        _bucket = new typename Digraph::template NodeMap<int>(_graph);
+      }
+      if (!_excess) {
+        _excess = new ExcessMap(_graph);
+      }
+      if (!_source_set) {
+        _source_set = new SourceSetMap(_graph);
+      }
+      if (!_min_cut_map) {
+        _min_cut_map = new MinCutMap(_graph);
+      }
+
+      _min_cut = std::numeric_limits<Value>::max();
+    }
+
+
+    /// \brief Calculate a minimum cut with \f$ source \f$ on the
+    /// source-side.
+    ///
+    /// This function calculates a minimum cut with \f$ source \f$ on the
+    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
+    /// \f$ source \in X \f$ and minimal outgoing capacity).
+    /// It updates the stored cut if (and only if) the newly found one
+    /// is better.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    void calculateOut() {
+      findMinCutOut();
+    }
+
+    /// \brief Calculate a minimum cut with \f$ source \f$ on the
+    /// sink-side.
+    ///
+    /// This function calculates a minimum cut with \f$ source \f$ on the
+    /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
+    /// \f$ source \notin X \f$ and minimal outgoing capacity).
+    /// It updates the stored cut if (and only if) the newly found one
+    /// is better.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    void calculateIn() {
+      findMinCutIn();
+    }
+
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm. It chooses source node,
+    /// then calls \ref init(), \ref calculateOut()
+    /// and \ref calculateIn().
+    void run() {
+      init();
+      calculateOut();
+      calculateIn();
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm. It calls \ref init(),
+    /// \ref calculateOut() and \ref calculateIn() with the given
+    /// source node.
+    void run(const Node& s) {
+      init(s);
+      calculateOut();
+      calculateIn();
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The result of the %HaoOrlin algorithm
+    /// can be obtained using these functions.\n
+    /// \ref run(), \ref calculateOut() or \ref calculateIn()
+    /// should be called before using them.
+
+    /// @{
+
+    /// \brief Return the value of the minimum cut.
+    ///
+    /// This function returns the value of the best cut found by the
+    /// previously called \ref run(), \ref calculateOut() or \ref
+    /// calculateIn().
+    ///
+    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
+    /// must be called before using this function.
+    Value minCutValue() const {
+      return _min_cut;
+    }
+
+
+    /// \brief Return a minimum cut.
+    ///
+    /// This function gives the best cut found by the
+    /// previously called \ref run(), \ref calculateOut() or \ref
+    /// calculateIn().
+    ///
+    /// It sets \c cutMap to the characteristic vector of the found
+    /// minimum value cut - a non-empty set \f$ X\subsetneq V \f$
+    /// of minimum outgoing capacity (i.e. \c cutMap will be \c true exactly
+    /// for the nodes of \f$ X \f$).
+    ///
+    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
+    /// \c bool (or convertible) value type.
+    ///
+    /// \return The value of the minimum cut.
+    ///
+    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
+    /// must be called before using this function.
+    template <typename CutMap>
+    Value minCutMap(CutMap& cutMap) const {
+      for (NodeIt it(_graph); it != INVALID; ++it) {
+        cutMap.set(it, (*_min_cut_map)[it]);
+      }
+      return _min_cut;
+    }
+
+    /// @}
+
+  }; //class HaoOrlin
+
+} //namespace lemon
+
+#endif //LEMON_HAO_ORLIN_H
diff --git a/lemon/hartmann_orlin_mmc.h b/lemon/hartmann_orlin_mmc.h
new file mode 100644
index 0000000..6b60a85
--- /dev/null
+++ b/lemon/hartmann_orlin_mmc.h
@@ -0,0 +1,654 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_HARTMANN_ORLIN_MMC_H
+#define LEMON_HARTMANN_ORLIN_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of HartmannOrlinMmc class.
+  ///
+  /// Default traits class of HartmannOrlinMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct HartmannOrlinMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct HartmannOrlinMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
+  /// a minimum mean cycle.
+  ///
+  /// This class implements the Hartmann-Orlin algorithm for finding
+  /// a directed cycle of minimum mean cost in a digraph
+  /// \cite hartmann93finding, \cite dasdan98minmeancycle.
+  /// This method is based on \ref KarpMmc "Karp"'s original algorithm, but
+  /// applies an early termination scheme. It makes the algorithm
+  /// significantly faster for some problem instances, but slower for others.
+  /// The algorithm runs in time O(nm) and uses space O(n<sup>2</sup>+m).
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits
+  /// "HartmannOrlinMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> >
+#endif
+  class HartmannOrlinMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref lemon::HartmannOrlinMmcDefaultTraits
+    /// "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// \brief The
+    /// \ref lemon::HartmannOrlinMmcDefaultTraits "traits class"
+    /// of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // Data sturcture for path data
+    struct PathData
+    {
+      LargeCost dist;
+      Arc pred;
+      PathData(LargeCost d, Arc p = INVALID) :
+        dist(d), pred(p) {}
+    };
+
+    typedef typename Digraph::template NodeMap<std::vector<PathData> >
+      PathDataNodeMap;
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
+
+    // Data for the found cycles
+    bool _curr_found, _best_found;
+    LargeCost _curr_cost, _best_cost;
+    int _curr_size, _best_size;
+    Node _curr_node, _best_node;
+    int _curr_level, _best_level;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Node map for storing path data
+    PathDataNodeMap _data;
+    // The processed nodes in the last round
+    std::vector<Node> _process;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    template <typename T>
+    struct SetPath
+      : public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > {
+      typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    HartmannOrlinMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    HartmannOrlinMmc( const Digraph &digraph,
+                      const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
+      _best_found(false), _best_cost(0), _best_size(1),
+      _cycle_path(NULL), _local_path(false), _data(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~HartmannOrlinMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), a local \ref Path "path" structure
+    /// will be allocated. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addFront()
+    /// "addFront()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    HartmannOrlinMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    HartmannOrlinMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findCycleMean() {
+      // Initialization and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        if (!initComponent(comp)) continue;
+        processRounds();
+
+        // Update the best cycle (global minimum mean cycle)
+        if ( _curr_found && (!_best_found ||
+             _curr_cost * _best_size < _best_cost * _curr_size) ) {
+          _best_found = true;
+          _best_cost = _curr_cost;
+          _best_size = _curr_size;
+          _best_node = _curr_node;
+          _best_level = _curr_level;
+        }
+      }
+      return _best_found;
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (!_best_found) return false;
+      IntNodeMap reached(_gr, -1);
+      int r = _best_level + 1;
+      Node u = _best_node;
+      while (reached[u] < 0) {
+        reached[u] = --r;
+        u = _gr.source(_data[u][r].pred);
+      }
+      r = reached[u];
+      Arc e = _data[u][r].pred;
+      _cycle_path->addFront(e);
+      _best_cost = _cost[e];
+      _best_size = 1;
+      Node v;
+      while ((v = _gr.source(e)) != u) {
+        e = _data[v][--r].pred;
+        _cycle_path->addFront(e);
+        _best_cost += _cost[e];
+        ++_best_size;
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The algorithm should be executed before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_best_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _best_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_best_cost) / _best_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialization
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _cycle_path->clear();
+      _best_found = false;
+      _best_cost = 0;
+      _best_size = 1;
+      _cycle_path->clear();
+      for (NodeIt u(_gr); u != INVALID; ++u)
+        _data[u].clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _out_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            _out_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Initialize path data for the current component
+    bool initComponent(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      int n = _nodes->size();
+      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < n; ++i) {
+        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
+      }
+      return true;
+    }
+
+    // Process all rounds of computing path data for the current component.
+    // _data[v][k] is the cost of a shortest directed walk from the root
+    // node to node v containing exactly k arcs.
+    void processRounds() {
+      Node start = (*_nodes)[0];
+      _data[start][0] = PathData(0);
+      _process.clear();
+      _process.push_back(start);
+
+      int k, n = _nodes->size();
+      int next_check = 4;
+      bool terminate = false;
+      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
+        processNextBuildRound(k);
+        if (k == next_check || k == n) {
+          terminate = checkTermination(k);
+          next_check = next_check * 3 / 2;
+        }
+      }
+      for ( ; k <= n && !terminate; ++k) {
+        processNextFullRound(k);
+        if (k == next_check || k == n) {
+          terminate = checkTermination(k);
+          next_check = next_check * 3 / 2;
+        }
+      }
+    }
+
+    // Process one round and rebuild _process
+    void processNextBuildRound(int k) {
+      std::vector<Node> next;
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        u = _process[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            if (_data[v][k].dist == INF) next.push_back(v);
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+      _process.swap(next);
+    }
+
+    // Process one round using _nodes instead of _process
+    void processNextFullRound(int k) {
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+    }
+
+    // Check early termination
+    bool checkTermination(int k) {
+      typedef std::pair<int, int> Pair;
+      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
+      typename GR::template NodeMap<LargeCost> pi(_gr);
+      int n = _nodes->size();
+      LargeCost cost;
+      int size;
+      Node u;
+
+      // Search for cycles that are already found
+      _curr_found = false;
+      for (int i = 0; i < n; ++i) {
+        u = (*_nodes)[i];
+        if (_data[u][k].dist == INF) continue;
+        for (int j = k; j >= 0; --j) {
+          if (level[u].first == i && level[u].second > 0) {
+            // A cycle is found
+            cost = _data[u][level[u].second].dist - _data[u][j].dist;
+            size = level[u].second - j;
+            if (!_curr_found || cost * _curr_size < _curr_cost * size) {
+              _curr_cost = cost;
+              _curr_size = size;
+              _curr_node = u;
+              _curr_level = level[u].second;
+              _curr_found = true;
+            }
+          }
+          level[u] = Pair(i, j);
+          if (j != 0) {
+            u = _gr.source(_data[u][j].pred);
+          }
+        }
+      }
+
+      // If at least one cycle is found, check the optimality condition
+      LargeCost d;
+      if (_curr_found && k < n) {
+        // Find node potentials
+        for (int i = 0; i < n; ++i) {
+          u = (*_nodes)[i];
+          pi[u] = INF;
+          for (int j = 0; j <= k; ++j) {
+            if (_data[u][j].dist < INF) {
+              d = _data[u][j].dist * _curr_size - j * _curr_cost;
+              if (_tolerance.less(d, pi[u])) pi[u] = d;
+            }
+          }
+        }
+
+        // Check the optimality condition for all arcs
+        bool done = true;
+        for (ArcIt a(_gr); a != INVALID; ++a) {
+          if (_tolerance.less(_cost[a] * _curr_size - _curr_cost,
+                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
+            done = false;
+            break;
+          }
+        }
+        return done;
+      }
+      return (k == n);
+    }
+
+  }; //class HartmannOrlinMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_HARTMANN_ORLIN_MMC_H
diff --git a/lemon/howard_mmc.h b/lemon/howard_mmc.h
new file mode 100644
index 0000000..6902363
--- /dev/null
+++ b/lemon/howard_mmc.h
@@ -0,0 +1,651 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_HOWARD_MMC_H
+#define LEMON_HOWARD_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Howard's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of HowardMmc class.
+  ///
+  /// Default traits class of HowardMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct HowardMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct HowardMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of Howard's algorithm for finding a minimum
+  /// mean cycle.
+  ///
+  /// This class implements Howard's policy iteration algorithm for finding
+  /// a directed cycle of minimum mean cost in a digraph
+  /// \cite dasdan98minmeancycle, \cite dasdan04experimental.
+  /// This class provides the most efficient algorithm for the
+  /// minimum mean cycle problem, though the best known theoretical
+  /// bound on its running time is exponential.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref HowardMmcDefaultTraits
+  /// "HowardMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = HowardMmcDefaultTraits<GR, CM> >
+#endif
+  class HowardMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref lemon::HowardMmcDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref lemon::HowardMmcDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+    /// \brief Constants for the causes of search termination.
+    ///
+    /// Enum type containing constants for the different causes of search
+    /// termination. The \ref findCycleMean() function returns one of
+    /// these values.
+    enum TerminationCause {
+
+      /// No directed cycle can be found in the digraph.
+      NO_CYCLE = 0,
+
+      /// Optimal solution (minimum cycle mean) is found.
+      OPTIMAL = 1,
+
+      /// The iteration count limit is reached.
+      ITERATION_LIMIT
+    };
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for the found cycles
+    bool _curr_found, _best_found;
+    LargeCost _curr_cost, _best_cost;
+    int _curr_size, _best_size;
+    Node _curr_node, _best_node;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Internal data used by the algorithm
+    typename Digraph::template NodeMap<Arc> _policy;
+    typename Digraph::template NodeMap<bool> _reached;
+    typename Digraph::template NodeMap<int> _level;
+    typename Digraph::template NodeMap<LargeCost> _dist;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
+
+    // Queue used for BFS search
+    std::vector<Node> _queue;
+    int _qfront, _qback;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public HowardMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef HowardMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    template <typename T>
+    struct SetPath
+      : public HowardMmc<GR, CM, SetPathTraits<T> > {
+      typedef HowardMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    HowardMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    HowardMmc( const Digraph &digraph,
+               const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _best_found(false),
+      _best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false),
+      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
+      _comp(digraph), _in_arcs(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~HowardMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), a local \ref Path "path" structure
+    /// will be allocated. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addBack()
+    /// "addBack()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    HowardMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    HowardMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean (or an upper bound).
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph (or an upper bound for it).
+    ///
+    /// By default, the function finds the exact minimum cycle mean,
+    /// but an optional limit can also be specified for the number of
+    /// iterations performed during the search process.
+    /// The return value indicates if the optimal solution is found
+    /// or the iteration limit is reached. In the latter case, an
+    /// approximate solution is provided, which corresponds to a directed
+    /// cycle whose mean cost is relatively small, but not necessarily
+    /// minimal.
+    ///
+    /// \param limit  The maximum allowed number of iterations during
+    /// the search process. Its default value implies that the algorithm
+    /// runs until it finds the exact optimal solution.
+    ///
+    /// \return The termination cause of the search process.
+    /// For more information, see \ref TerminationCause.
+    TerminationCause findCycleMean(int limit =
+                                   std::numeric_limits<int>::max()) {
+      // Initialize and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      int iter_count = 0;
+      bool iter_limit_reached = false;
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        // Find the minimum mean cycle in the current component
+        if (!buildPolicyGraph(comp)) continue;
+        while (true) {
+          if (++iter_count > limit) {
+            iter_limit_reached = true;
+            break;
+          }
+          findPolicyCycle();
+          if (!computeNodeDistances()) break;
+        }
+
+        // Update the best cycle (global minimum mean cycle)
+        if ( _curr_found && (!_best_found ||
+             _curr_cost * _best_size < _best_cost * _curr_size) ) {
+          _best_found = true;
+          _best_cost = _curr_cost;
+          _best_size = _curr_size;
+          _best_node = _curr_node;
+        }
+
+        if (iter_limit_reached) break;
+      }
+
+      if (iter_limit_reached) {
+        return ITERATION_LIMIT;
+      } else {
+        return _best_found ? OPTIMAL : NO_CYCLE;
+      }
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (!_best_found) return false;
+      _cycle_path->addBack(_policy[_best_node]);
+      for ( Node v = _best_node;
+            (v = _gr.target(_policy[v])) != _best_node; ) {
+        _cycle_path->addBack(_policy[v]);
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The algorithm should be executed before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_best_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _best_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_best_cost) / _best_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialize
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _queue.resize(countNodes(_gr));
+      _best_found = false;
+      _best_cost = 0;
+      _best_size = 1;
+      _cycle_path->clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _in_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _in_arcs[n].clear();
+          for (InArcIt a(_gr, n); a != INVALID; ++a) {
+            _in_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _in_arcs[n].clear();
+          for (InArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Build the policy graph in the given strongly connected component
+    // (the out-degree of every node is 1)
+    bool buildPolicyGraph(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      if (_nodes->size() < 1 ||
+          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _dist[(*_nodes)[i]] = INF;
+      }
+      Node u, v;
+      Arc e;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        v = (*_nodes)[i];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (_cost[e] < _dist[u]) {
+            _dist[u] = _cost[e];
+            _policy[u] = e;
+          }
+        }
+      }
+      return true;
+    }
+
+    // Find the minimum mean cycle in the policy graph
+    void findPolicyCycle() {
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _level[(*_nodes)[i]] = -1;
+      }
+      LargeCost ccost;
+      int csize;
+      Node u, v;
+      _curr_found = false;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        if (_level[u] >= 0) continue;
+        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
+          _level[u] = i;
+        }
+        if (_level[u] == i) {
+          // A cycle is found
+          ccost = _cost[_policy[u]];
+          csize = 1;
+          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
+            ccost += _cost[_policy[v]];
+            ++csize;
+          }
+          if ( !_curr_found ||
+               (ccost * _curr_size < _curr_cost * csize) ) {
+            _curr_found = true;
+            _curr_cost = ccost;
+            _curr_size = csize;
+            _curr_node = u;
+          }
+        }
+      }
+    }
+
+    // Contract the policy graph and compute node distances
+    bool computeNodeDistances() {
+      // Find the component of the main cycle and compute node distances
+      // using reverse BFS
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _reached[(*_nodes)[i]] = false;
+      }
+      _qfront = _qback = 0;
+      _queue[0] = _curr_node;
+      _reached[_curr_node] = true;
+      _dist[_curr_node] = 0;
+      Node u, v;
+      Arc e;
+      while (_qfront <= _qback) {
+        v = _queue[_qfront++];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (_policy[u] == e && !_reached[u]) {
+            _reached[u] = true;
+            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+            _queue[++_qback] = u;
+          }
+        }
+      }
+
+      // Connect all other nodes to this component and compute node
+      // distances using reverse BFS
+      _qfront = 0;
+      while (_qback < int(_nodes->size())-1) {
+        v = _queue[_qfront++];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (!_reached[u]) {
+            _reached[u] = true;
+            _policy[u] = e;
+            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+            _queue[++_qback] = u;
+          }
+        }
+      }
+
+      // Improve node distances
+      bool improved = false;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        v = (*_nodes)[i];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+          if (_tolerance.less(delta, _dist[u])) {
+            _dist[u] = delta;
+            _policy[u] = e;
+            improved = true;
+          }
+        }
+      }
+      return improved;
+    }
+
+  }; //class HowardMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_HOWARD_MMC_H
diff --git a/lemon/hypercube_graph.h b/lemon/hypercube_graph.h
new file mode 100644
index 0000000..2cf37ad
--- /dev/null
+++ b/lemon/hypercube_graph.h
@@ -0,0 +1,459 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef HYPERCUBE_GRAPH_H
+#define HYPERCUBE_GRAPH_H
+
+#include <vector>
+#include <lemon/core.h>
+#include <lemon/assert.h>
+#include <lemon/bits/graph_extender.h>
+
+///\ingroup graphs
+///\file
+///\brief HypercubeGraph class.
+
+namespace lemon {
+
+  class HypercubeGraphBase {
+
+  public:
+
+    typedef HypercubeGraphBase Graph;
+
+    class Node;
+    class Edge;
+    class Arc;
+
+  public:
+
+    HypercubeGraphBase() {}
+
+  protected:
+
+    void construct(int dim) {
+      LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
+      _dim = dim;
+      _node_num = 1 << dim;
+      _edge_num = dim * (1 << (dim-1));
+    }
+
+  public:
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return _node_num; }
+    int edgeNum() const { return _edge_num; }
+    int arcNum() const { return 2 * _edge_num; }
+
+    int maxNodeId() const { return _node_num - 1; }
+    int maxEdgeId() const { return _edge_num - 1; }
+    int maxArcId() const { return 2 * _edge_num - 1; }
+
+    static Node nodeFromId(int id) { return Node(id); }
+    static Edge edgeFromId(int id) { return Edge(id); }
+    static Arc arcFromId(int id) { return Arc(id); }
+
+    static int id(Node node) { return node._id; }
+    static int id(Edge edge) { return edge._id; }
+    static int id(Arc arc) { return arc._id; }
+
+    Node u(Edge edge) const {
+      int base = edge._id & ((1 << (_dim-1)) - 1);
+      int k = edge._id >> (_dim-1);
+      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1));
+    }
+
+    Node v(Edge edge) const {
+      int base = edge._id & ((1 << (_dim-1)) - 1);
+      int k = edge._id >> (_dim-1);
+      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k);
+    }
+
+    Node source(Arc arc) const {
+      return (arc._id & 1) == 1 ? u(arc) : v(arc);
+    }
+
+    Node target(Arc arc) const {
+      return (arc._id & 1) == 1 ? v(arc) : u(arc);
+    }
+
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      if (prev != INVALID) return INVALID;
+      int d = u._id ^ v._id;
+      int k = 0;
+      if (d == 0) return INVALID;
+      for ( ; (d & 1) == 0; d >>= 1) ++k;
+      if (d >> 1 != 0) return INVALID;
+      return (k << (_dim-1)) | ((u._id >> (k+1)) << k) |
+        (u._id & ((1 << k) - 1));
+    }
+
+    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
+      Edge edge = findEdge(u, v, prev);
+      if (edge == INVALID) return INVALID;
+      int k = edge._id >> (_dim-1);
+      return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
+    }
+
+    class Node {
+      friend class HypercubeGraphBase;
+
+    protected:
+      int _id;
+      Node(int id) : _id(id) {}
+    public:
+      Node() {}
+      Node (Invalid) : _id(-1) {}
+      bool operator==(const Node node) const {return _id == node._id;}
+      bool operator!=(const Node node) const {return _id != node._id;}
+      bool operator<(const Node node) const {return _id < node._id;}
+    };
+
+    class Edge {
+      friend class HypercubeGraphBase;
+      friend class Arc;
+
+    protected:
+      int _id;
+
+      Edge(int id) : _id(id) {}
+
+    public:
+      Edge() {}
+      Edge (Invalid) : _id(-1) {}
+      bool operator==(const Edge edge) const {return _id == edge._id;}
+      bool operator!=(const Edge edge) const {return _id != edge._id;}
+      bool operator<(const Edge edge) const {return _id < edge._id;}
+    };
+
+    class Arc {
+      friend class HypercubeGraphBase;
+
+    protected:
+      int _id;
+
+      Arc(int id) : _id(id) {}
+
+    public:
+      Arc() {}
+      Arc (Invalid) : _id(-1) {}
+      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
+      bool operator==(const Arc arc) const {return _id == arc._id;}
+      bool operator!=(const Arc arc) const {return _id != arc._id;}
+      bool operator<(const Arc arc) const {return _id < arc._id;}
+    };
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Edge& edge) const {
+      edge._id = _edge_num - 1;
+    }
+
+    static void next(Edge& edge) {
+      --edge._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = 2 * _edge_num - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void firstInc(Edge& edge, bool& dir, const Node& node) const {
+      edge._id = node._id >> 1;
+      dir = (node._id & 1) == 0;
+    }
+
+    void nextInc(Edge& edge, bool& dir) const {
+      Node n = dir ? u(edge) : v(edge);
+      int k = (edge._id >> (_dim-1)) + 1;
+      if (k < _dim) {
+        edge._id = (k << (_dim-1)) |
+          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
+        dir = ((n._id >> k) & 1) == 0;
+      } else {
+        edge._id = -1;
+        dir = true;
+      }
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
+    }
+
+    void nextOut(Arc& arc) const {
+      Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
+      int k = (arc._id >> _dim) + 1;
+      if (k < _dim) {
+        arc._id = (k << (_dim-1)) |
+          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
+        arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
+      } else {
+        arc._id = -1;
+      }
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
+    }
+
+    void nextIn(Arc& arc) const {
+      Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
+      int k = (arc._id >> _dim) + 1;
+      if (k < _dim) {
+        arc._id = (k << (_dim-1)) |
+          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
+        arc._id = (arc._id << 1) | ((n._id >> k) & 1);
+      } else {
+        arc._id = -1;
+      }
+    }
+
+    static bool direction(Arc arc) {
+      return (arc._id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc((edge._id << 1) | (dir ? 1 : 0));
+    }
+
+    int dimension() const {
+      return _dim;
+    }
+
+    bool projection(Node node, int n) const {
+      return static_cast<bool>(node._id & (1 << n));
+    }
+
+    int dimension(Edge edge) const {
+      return edge._id >> (_dim-1);
+    }
+
+    int dimension(Arc arc) const {
+      return arc._id >> _dim;
+    }
+
+    static int index(Node node) {
+      return node._id;
+    }
+
+    Node operator()(int ix) const {
+      return Node(ix);
+    }
+
+  private:
+    int _dim;
+    int _node_num, _edge_num;
+  };
+
+
+  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief Hypercube graph class
+  ///
+  /// 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).
+  class HypercubeGraph : public ExtendedHypercubeGraphBase {
+    typedef ExtendedHypercubeGraphBase Parent;
+
+  public:
+
+    /// \brief Constructs a hypercube graph with \c dim dimensions.
+    ///
+    /// 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.
+    ///
+    /// Gives back the number of dimensions.
+    int dimension() const {
+      return Parent::dimension();
+    }
+
+    /// \brief Returns \c true if the n'th bit of the node is one.
+    ///
+    /// Returns \c true if the n'th bit of the node is one.
+    bool projection(Node node, int n) const {
+      return Parent::projection(node, n);
+    }
+
+    /// \brief The dimension id of an edge.
+    ///
+    /// Gives back the dimension id of the given edge.
+    /// It is in the range <tt>[0..dim-1]</tt>.
+    int dimension(Edge edge) const {
+      return Parent::dimension(edge);
+    }
+
+    /// \brief The dimension id of an arc.
+    ///
+    /// Gives back the dimension id of the given arc.
+    /// It is in the range <tt>[0..dim-1]</tt>.
+    int dimension(Arc arc) const {
+      return Parent::dimension(arc);
+    }
+
+    /// \brief The index of a node.
+    ///
+    /// Gives back the index of the given node.
+    /// The lower bits of the integer describes the node.
+    static int index(Node node) {
+      return Parent::index(node);
+    }
+
+    /// \brief Gives back a node by its index.
+    ///
+    /// Gives back a node by its index.
+    Node operator()(int ix) const {
+      return Parent::operator()(ix);
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
+    /// \brief Number of arcs.
+    int arcNum() const { return Parent::arcNum(); }
+
+    /// \brief Linear combination map.
+    ///
+    /// This map makes possible to give back a linear combination
+    /// for each node. It works like the \c std::accumulate function,
+    /// so it accumulates the \c bf binary function with the \c fv first
+    /// value. The map accumulates only on that positions (dimensions)
+    /// where the index of the node is one. The values that have to be
+    /// accumulated should be given by the \c begin and \c end iterators
+    /// and the length of this range should be equal to the dimension
+    /// number of the graph.
+    ///
+    ///\code
+    /// const int DIM = 3;
+    /// HypercubeGraph graph(DIM);
+    /// dim2::Point<double> base[DIM];
+    /// for (int k = 0; k < DIM; ++k) {
+    ///   base[k].x = rnd();
+    ///   base[k].y = rnd();
+    /// }
+    /// HypercubeGraph::HyperMap<dim2::Point<double> >
+    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
+    ///\endcode
+    ///
+    /// \see HypercubeGraph
+    template <typename T, typename BF = std::plus<T> >
+    class HyperMap {
+    public:
+
+      /// \brief The key type of the map
+      typedef Node Key;
+      /// \brief The value type of the map
+      typedef T Value;
+
+      /// \brief Constructor for HyperMap.
+      ///
+      /// Construct a HyperMap for the given graph. The values that have
+      /// to be accumulated should be given by the \c begin and \c end
+      /// iterators and the length of this range should be equal to the
+      /// dimension number of the graph.
+      ///
+      /// This map accumulates the \c bf binary function with the \c fv
+      /// first value on that positions (dimensions) where the index of
+      /// the node is one.
+      template <typename It>
+      HyperMap(const Graph& graph, It begin, It end,
+               T fv = 0, const BF& bf = BF())
+        : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
+      {
+        LEMON_ASSERT(_values.size() == graph.dimension(),
+                     "Wrong size of range");
+      }
+
+      /// \brief The partial accumulated value.
+      ///
+      /// Gives back the partial accumulated value.
+      Value operator[](const Key& k) const {
+        Value val = _first_value;
+        int id = _graph.index(k);
+        int n = 0;
+        while (id != 0) {
+          if (id & 1) {
+            val = _bin_func(val, _values[n]);
+          }
+          id >>= 1;
+          ++n;
+        }
+        return val;
+      }
+
+    private:
+      const Graph& _graph;
+      std::vector<T> _values;
+      T _first_value;
+      BF _bin_func;
+    };
+
+  };
+
+}
+
+#endif
diff --git a/lemon/insertion_tsp.h b/lemon/insertion_tsp.h
new file mode 100644
index 0000000..fa16825
--- /dev/null
+++ b/lemon/insertion_tsp.h
@@ -0,0 +1,533 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_INSERTION_TSP_H
+#define LEMON_INSERTION_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief Insertion algorithm for symmetric TSP
+
+#include <vector>
+#include <functional>
+#include <lemon/full_graph.h>
+#include <lemon/maps.h>
+#include <lemon/random.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief Insertion algorithm for symmetric TSP.
+  ///
+  /// InsertionTsp implements the insertion heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This is a fast and effective tour construction method that has
+  /// many variants.
+  /// It starts with a subtour containing a few nodes of the graph and it
+  /// iteratively inserts the other nodes into this subtour according to a
+  /// certain node selection rule.
+  ///
+  /// This method is among the fastest TSP algorithms, and it typically
+  /// provides quite good solutions (usually much better than
+  /// \ref NearestNeighborTsp and \ref GreedyTsp).
+  ///
+  /// InsertionTsp implements four different node selection rules,
+  /// from which the most effective one (\e farthest \e node \e selection)
+  /// is used by default.
+  /// With this choice, the algorithm runs in O(n<sup>2</sup>) time.
+  /// For more information, see \ref SelectionRule.
+  ///
+  /// \tparam CM Type of the cost map.
+  template <typename CM>
+  class InsertionTsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      std::vector<Node> _notused;
+      std::vector<Node> _tour;
+      Cost _sum;
+
+    public:
+
+      /// \brief Constants for specifying the node selection rule.
+      ///
+      /// Enum type containing constants for specifying the node selection
+      /// rule for the \ref run() function.
+      ///
+      /// During the algorithm, nodes are selected for addition to the current
+      /// subtour according to the applied rule.
+      /// The FARTHEST method is one of the fastest selection rules, and
+      /// it is typically the most effective, thus it is the default
+      /// option. The RANDOM rule usually gives slightly worse results,
+      /// but it is more robust.
+      ///
+      /// The desired selection rule can be specified as a parameter of the
+      /// \ref run() function.
+      enum SelectionRule {
+
+        /// An unvisited node having minimum distance from the current
+        /// subtour is selected at each step.
+        /// The algorithm runs in O(n<sup>2</sup>) time using this
+        /// selection rule.
+        NEAREST,
+
+        /// An unvisited node having maximum distance from the current
+        /// subtour is selected at each step.
+        /// The algorithm runs in O(n<sup>2</sup>) time using this
+        /// selection rule.
+        FARTHEST,
+
+        /// An unvisited node whose insertion results in the least
+        /// increase of the subtour's total cost is selected at each step.
+        /// The algorithm runs in O(n<sup>3</sup>) time using this
+        /// selection rule, but in most cases, it is almost as fast as
+        /// with other rules.
+        CHEAPEST,
+
+        /// An unvisited node is selected randomly without any evaluation
+        /// at each step.
+        /// The global \ref rnd "random number generator instance" is used.
+        /// You can seed it before executing the algorithm, if you
+        /// would like to.
+        /// The algorithm runs in O(n<sup>2</sup>) time using this
+        /// selection rule.
+        RANDOM
+      };
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      InsertionTsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm.
+      ///
+      /// This function runs the algorithm.
+      ///
+      /// \param rule The node selection rule. For more information, see
+      /// \ref SelectionRule.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run(SelectionRule rule = FARTHEST) {
+        _tour.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _tour.push_back(_gr(0));
+          return _sum = 0;
+        }
+
+        switch (rule) {
+          case NEAREST:
+            init(true);
+            start<ComparingSelection<std::less<Cost> >,
+                  DefaultInsertion>();
+            break;
+          case FARTHEST:
+            init(false);
+            start<ComparingSelection<std::greater<Cost> >,
+                  DefaultInsertion>();
+            break;
+          case CHEAPEST:
+            init(true);
+            start<CheapestSelection, CheapestInsertion>();
+            break;
+          case RANDOM:
+            init(true);
+            start<RandomSelection, DefaultInsertion>();
+            break;
+        }
+        return _sum;
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _tour;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_tour.begin(), _tour.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_tour.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_tour[i], _tour[i+1]));
+        }
+        if (int(_tour.size()) >= 2) {
+          path.addBack(_gr.arc(_tour.back(), _tour.front()));
+        }
+      }
+
+      /// @}
+
+    private:
+
+      // Initializes the algorithm
+      void init(bool min) {
+        Edge min_edge = min ? mapMin(_gr, _cost) : mapMax(_gr, _cost);
+
+        _tour.clear();
+        _tour.push_back(_gr.u(min_edge));
+        _tour.push_back(_gr.v(min_edge));
+
+        _notused.clear();
+        for (NodeIt n(_gr); n!=INVALID; ++n) {
+          if (n != _gr.u(min_edge) && n != _gr.v(min_edge)) {
+            _notused.push_back(n);
+          }
+        }
+
+        _sum = _cost[min_edge] * 2;
+      }
+
+      // Executes the algorithm
+      template <class SelectionFunctor, class InsertionFunctor>
+      void start() {
+        SelectionFunctor selectNode(_gr, _cost, _tour, _notused);
+        InsertionFunctor insertNode(_gr, _cost, _tour, _sum);
+
+        for (int i=0; i<_gr.nodeNum()-2; ++i) {
+          insertNode.insert(selectNode.select());
+        }
+
+        _sum = _cost[_gr.edge(_tour.back(), _tour.front())];
+        for (int i = 0; i < int(_tour.size())-1; ++i) {
+          _sum += _cost[_gr.edge(_tour[i], _tour[i+1])];
+        }
+      }
+
+
+      // Implementation of the nearest and farthest selection rule
+      template <typename Comparator>
+      class ComparingSelection {
+        public:
+          ComparingSelection(const FullGraph &gr, const CostMap &cost,
+                  std::vector<Node> &tour, std::vector<Node> &notused)
+            : _gr(gr), _cost(cost), _tour(tour), _notused(notused),
+              _dist(gr, 0), _compare()
+          {
+            // Compute initial distances for the unused nodes
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Node u = _notused[i];
+              Cost min_dist = _cost[_gr.edge(u, _tour[0])];
+              for (unsigned int j=1; j<_tour.size(); ++j) {
+                Cost curr = _cost[_gr.edge(u, _tour[j])];
+                if (curr < min_dist) {
+                  min_dist = curr;
+                }
+              }
+              _dist[u] = min_dist;
+            }
+          }
+
+          Node select() {
+
+            // Select an used node with minimum distance
+            Cost ins_dist = 0;
+            int ins_node = -1;
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Cost curr = _dist[_notused[i]];
+              if (_compare(curr, ins_dist) || ins_node == -1) {
+                ins_dist = curr;
+                ins_node = i;
+              }
+            }
+
+            // Remove the selected node from the unused vector
+            Node sn = _notused[ins_node];
+            _notused[ins_node] = _notused.back();
+            _notused.pop_back();
+
+            // Update the distances of the remaining nodes
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Node u = _notused[i];
+              Cost nc = _cost[_gr.edge(sn, u)];
+              if (nc < _dist[u]) {
+                _dist[u] = nc;
+              }
+            }
+
+            return sn;
+          }
+
+        private:
+          const FullGraph &_gr;
+          const CostMap &_cost;
+          std::vector<Node> &_tour;
+          std::vector<Node> &_notused;
+          FullGraph::NodeMap<Cost> _dist;
+          Comparator _compare;
+      };
+
+      // Implementation of the cheapest selection rule
+      class CheapestSelection {
+        private:
+          Cost costDiff(Node u, Node v, Node w) const {
+            return
+              _cost[_gr.edge(u, w)] +
+              _cost[_gr.edge(v, w)] -
+              _cost[_gr.edge(u, v)];
+          }
+
+        public:
+          CheapestSelection(const FullGraph &gr, const CostMap &cost,
+                            std::vector<Node> &tour, std::vector<Node> &notused)
+            : _gr(gr), _cost(cost), _tour(tour), _notused(notused),
+              _ins_cost(gr, 0), _ins_pos(gr, -1)
+          {
+            // Compute insertion cost and position for the unused nodes
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Node u = _notused[i];
+              Cost min_cost = costDiff(_tour.back(), _tour.front(), u);
+              int min_pos = 0;
+              for (unsigned int j=1; j<_tour.size(); ++j) {
+                Cost curr_cost = costDiff(_tour[j-1], _tour[j], u);
+                if (curr_cost < min_cost) {
+                  min_cost = curr_cost;
+                  min_pos = j;
+                }
+              }
+              _ins_cost[u] = min_cost;
+              _ins_pos[u] = min_pos;
+            }
+          }
+
+          Cost select() {
+
+            // Select an used node with minimum insertion cost
+            Cost min_cost = 0;
+            int min_node = -1;
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Cost curr_cost = _ins_cost[_notused[i]];
+              if (curr_cost < min_cost || min_node == -1) {
+                min_cost = curr_cost;
+                min_node = i;
+              }
+            }
+
+            // Remove the selected node from the unused vector
+            Node sn = _notused[min_node];
+            _notused[min_node] = _notused.back();
+            _notused.pop_back();
+
+            // Insert the selected node into the tour
+            const int ipos = _ins_pos[sn];
+            _tour.insert(_tour.begin() + ipos, sn);
+
+            // Update the insertion cost and position of the remaining nodes
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Node u = _notused[i];
+              Cost curr_cost = _ins_cost[u];
+              int curr_pos = _ins_pos[u];
+
+              int ipos_prev = ipos == 0 ? _tour.size()-1 : ipos-1;
+              int ipos_next = ipos == int(_tour.size())-1 ? 0 : ipos+1;
+              Cost nc1 = costDiff(_tour[ipos_prev], _tour[ipos], u);
+              Cost nc2 = costDiff(_tour[ipos], _tour[ipos_next], u);
+
+              if (nc1 <= curr_cost || nc2 <= curr_cost) {
+                // A new position is better than the old one
+                if (nc1 <= nc2) {
+                  curr_cost = nc1;
+                  curr_pos = ipos;
+                } else {
+                  curr_cost = nc2;
+                  curr_pos = ipos_next;
+                }
+              }
+              else {
+                if (curr_pos == ipos) {
+                  // The minimum should be found again
+                  curr_cost = costDiff(_tour.back(), _tour.front(), u);
+                  curr_pos = 0;
+                  for (unsigned int j=1; j<_tour.size(); ++j) {
+                    Cost tmp_cost = costDiff(_tour[j-1], _tour[j], u);
+                    if (tmp_cost < curr_cost) {
+                      curr_cost = tmp_cost;
+                      curr_pos = j;
+                    }
+                  }
+                }
+                else if (curr_pos > ipos) {
+                  ++curr_pos;
+                }
+              }
+
+              _ins_cost[u] = curr_cost;
+              _ins_pos[u] = curr_pos;
+            }
+
+            return min_cost;
+          }
+
+        private:
+          const FullGraph &_gr;
+          const CostMap &_cost;
+          std::vector<Node> &_tour;
+          std::vector<Node> &_notused;
+          FullGraph::NodeMap<Cost> _ins_cost;
+          FullGraph::NodeMap<int> _ins_pos;
+      };
+
+      // Implementation of the random selection rule
+      class RandomSelection {
+        public:
+          RandomSelection(const FullGraph &, const CostMap &,
+                          std::vector<Node> &, std::vector<Node> &notused)
+            : _notused(notused) {}
+
+          Node select() const {
+            const int index = rnd[_notused.size()];
+            Node n = _notused[index];
+            _notused[index] = _notused.back();
+            _notused.pop_back();
+            return n;
+          }
+
+        private:
+          std::vector<Node> &_notused;
+      };
+
+
+      // Implementation of the default insertion method
+      class DefaultInsertion {
+        private:
+          Cost costDiff(Node u, Node v, Node w) const {
+            return
+              _cost[_gr.edge(u, w)] +
+              _cost[_gr.edge(v, w)] -
+              _cost[_gr.edge(u, v)];
+          }
+
+        public:
+          DefaultInsertion(const FullGraph &gr, const CostMap &cost,
+                           std::vector<Node> &tour, Cost &total_cost) :
+            _gr(gr), _cost(cost), _tour(tour), _total(total_cost) {}
+
+          void insert(Node n) const {
+            int min = 0;
+            Cost min_val =
+              costDiff(_tour.front(), _tour.back(), n);
+
+            for (unsigned int i=1; i<_tour.size(); ++i) {
+              Cost tmp = costDiff(_tour[i-1], _tour[i], n);
+              if (tmp < min_val) {
+                min = i;
+                min_val = tmp;
+              }
+            }
+
+            _tour.insert(_tour.begin()+min, n);
+            _total += min_val;
+          }
+
+        private:
+          const FullGraph &_gr;
+          const CostMap &_cost;
+          std::vector<Node> &_tour;
+          Cost &_total;
+      };
+
+      // Implementation of a special insertion method for the cheapest
+      // selection rule
+      class CheapestInsertion {
+        TEMPLATE_GRAPH_TYPEDEFS(FullGraph);
+        public:
+          CheapestInsertion(const FullGraph &, const CostMap &,
+                            std::vector<Node> &, Cost &total_cost) :
+            _total(total_cost) {}
+
+          void insert(Cost diff) const {
+            _total += diff;
+          }
+
+        private:
+          Cost &_total;
+      };
+
+  };
+
+}; // namespace lemon
+
+#endif
diff --git a/lemon/karp_mmc.h b/lemon/karp_mmc.h
new file mode 100644
index 0000000..1f05d43
--- /dev/null
+++ b/lemon/karp_mmc.h
@@ -0,0 +1,590 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_KARP_MMC_H
+#define LEMON_KARP_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Karp's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of KarpMmc class.
+  ///
+  /// Default traits class of KarpMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct KarpMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct KarpMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of Karp's algorithm for finding a minimum
+  /// mean cycle.
+  ///
+  /// This class implements Karp's algorithm for finding a directed
+  /// cycle of minimum mean cost in a digraph
+  /// \cite karp78characterization, \cite dasdan98minmeancycle.
+  /// It runs in time O(nm) and uses space O(n<sup>2</sup>+m).
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref KarpMmcDefaultTraits
+  /// "KarpMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = KarpMmcDefaultTraits<GR, CM> >
+#endif
+  class KarpMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref lemon::KarpMmcDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref lemon::KarpMmcDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // Data sturcture for path data
+    struct PathData
+    {
+      LargeCost dist;
+      Arc pred;
+      PathData(LargeCost d, Arc p = INVALID) :
+        dist(d), pred(p) {}
+    };
+
+    typedef typename Digraph::template NodeMap<std::vector<PathData> >
+      PathDataNodeMap;
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
+
+    // Data for the found cycle
+    LargeCost _cycle_cost;
+    int _cycle_size;
+    Node _cycle_node;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Node map for storing path data
+    PathDataNodeMap _data;
+    // The processed nodes in the last round
+    std::vector<Node> _process;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public KarpMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef KarpMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    template <typename T>
+    struct SetPath
+      : public KarpMmc<GR, CM, SetPathTraits<T> > {
+      typedef KarpMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    KarpMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    KarpMmc( const Digraph &digraph,
+             const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
+      _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID),
+      _cycle_path(NULL), _local_path(false), _data(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~KarpMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), a local \ref Path "path" structure
+    /// will be allocated. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addFront()
+    /// "addFront()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    KarpMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    KarpMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findCycleMean() {
+      // Initialization and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        if (!initComponent(comp)) continue;
+        processRounds();
+        updateMinMean();
+      }
+      return (_cycle_node != INVALID);
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (_cycle_node == INVALID) return false;
+      IntNodeMap reached(_gr, -1);
+      int r = _data[_cycle_node].size();
+      Node u = _cycle_node;
+      while (reached[u] < 0) {
+        reached[u] = --r;
+        u = _gr.source(_data[u][r].pred);
+      }
+      r = reached[u];
+      Arc e = _data[u][r].pred;
+      _cycle_path->addFront(e);
+      _cycle_cost = _cost[e];
+      _cycle_size = 1;
+      Node v;
+      while ((v = _gr.source(e)) != u) {
+        e = _data[v][--r].pred;
+        _cycle_path->addFront(e);
+        _cycle_cost += _cost[e];
+        ++_cycle_size;
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The algorithm should be executed before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_cycle_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _cycle_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_cycle_cost) / _cycle_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialization
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _cycle_path->clear();
+      _cycle_cost = 0;
+      _cycle_size = 1;
+      _cycle_node = INVALID;
+      for (NodeIt u(_gr); u != INVALID; ++u)
+        _data[u].clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _out_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            _out_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Initialize path data for the current component
+    bool initComponent(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      int n = _nodes->size();
+      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < n; ++i) {
+        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
+      }
+      return true;
+    }
+
+    // Process all rounds of computing path data for the current component.
+    // _data[v][k] is the cost of a shortest directed walk from the root
+    // node to node v containing exactly k arcs.
+    void processRounds() {
+      Node start = (*_nodes)[0];
+      _data[start][0] = PathData(0);
+      _process.clear();
+      _process.push_back(start);
+
+      int k, n = _nodes->size();
+      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
+        processNextBuildRound(k);
+      }
+      for ( ; k <= n; ++k) {
+        processNextFullRound(k);
+      }
+    }
+
+    // Process one round and rebuild _process
+    void processNextBuildRound(int k) {
+      std::vector<Node> next;
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        u = _process[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            if (_data[v][k].dist == INF) next.push_back(v);
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+      _process.swap(next);
+    }
+
+    // Process one round using _nodes instead of _process
+    void processNextFullRound(int k) {
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+    }
+
+    // Update the minimum cycle mean
+    void updateMinMean() {
+      int n = _nodes->size();
+      for (int i = 0; i < n; ++i) {
+        Node u = (*_nodes)[i];
+        if (_data[u][n].dist == INF) continue;
+        LargeCost cost, max_cost = 0;
+        int size, max_size = 1;
+        bool found_curr = false;
+        for (int k = 0; k < n; ++k) {
+          if (_data[u][k].dist == INF) continue;
+          cost = _data[u][n].dist - _data[u][k].dist;
+          size = n - k;
+          if (!found_curr || cost * max_size > max_cost * size) {
+            found_curr = true;
+            max_cost = cost;
+            max_size = size;
+          }
+        }
+        if ( found_curr && (_cycle_node == INVALID ||
+             max_cost * _cycle_size < _cycle_cost * max_size) ) {
+          _cycle_cost = max_cost;
+          _cycle_size = max_size;
+          _cycle_node = u;
+        }
+      }
+    }
+
+  }; //class KarpMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_KARP_MMC_H
diff --git a/lemon/kruskal.h b/lemon/kruskal.h
new file mode 100644
index 0000000..04c2ddb
--- /dev/null
+++ b/lemon/kruskal.h
@@ -0,0 +1,324 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_KRUSKAL_H
+#define LEMON_KRUSKAL_H
+
+#include <algorithm>
+#include <vector>
+#include <lemon/unionfind.h>
+#include <lemon/maps.h>
+
+#include <lemon/core.h>
+#include <lemon/bits/traits.h>
+
+///\ingroup spantree
+///\file
+///\brief Kruskal's algorithm to compute a minimum cost spanning tree
+
+namespace lemon {
+
+  namespace _kruskal_bits {
+
+    // Kruskal for directed graphs.
+
+    template <typename Digraph, typename In, typename Out>
+    typename disable_if<lemon::UndirectedTagIndicator<Digraph>,
+                       typename In::value_type::second_type >::type
+    kruskal(const Digraph& digraph, const In& in, Out& out,dummy<0> = 0) {
+      typedef typename In::value_type::second_type Value;
+      typedef typename Digraph::template NodeMap<int> IndexMap;
+      typedef typename Digraph::Node Node;
+
+      IndexMap index(digraph);
+      UnionFind<IndexMap> uf(index);
+      for (typename Digraph::NodeIt it(digraph); it != INVALID; ++it) {
+        uf.insert(it);
+      }
+
+      Value tree_value = 0;
+      for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) {
+        if (uf.join(digraph.target(it->first),digraph.source(it->first))) {
+          out.set(it->first, true);
+          tree_value += it->second;
+        }
+        else {
+          out.set(it->first, false);
+        }
+      }
+      return tree_value;
+    }
+
+    // Kruskal for undirected graphs.
+
+    template <typename Graph, typename In, typename Out>
+    typename enable_if<lemon::UndirectedTagIndicator<Graph>,
+                       typename In::value_type::second_type >::type
+    kruskal(const Graph& graph, const In& in, Out& out,dummy<1> = 1) {
+      typedef typename In::value_type::second_type Value;
+      typedef typename Graph::template NodeMap<int> IndexMap;
+      typedef typename Graph::Node Node;
+
+      IndexMap index(graph);
+      UnionFind<IndexMap> uf(index);
+      for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
+        uf.insert(it);
+      }
+
+      Value tree_value = 0;
+      for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) {
+        if (uf.join(graph.u(it->first),graph.v(it->first))) {
+          out.set(it->first, true);
+          tree_value += it->second;
+        }
+        else {
+          out.set(it->first, false);
+        }
+      }
+      return tree_value;
+    }
+
+
+    template <typename Sequence>
+    struct PairComp {
+      typedef typename Sequence::value_type Value;
+      bool operator()(const Value& left, const Value& right) {
+        return left.second < right.second;
+      }
+    };
+
+    template <typename In, typename Enable = void>
+    struct SequenceInputIndicator {
+      static const bool value = false;
+    };
+
+    template <typename In>
+    struct SequenceInputIndicator<In,
+      typename exists<typename In::value_type::first_type>::type> {
+      static const bool value = true;
+    };
+
+    template <typename In, typename Enable = void>
+    struct MapInputIndicator {
+      static const bool value = false;
+    };
+
+    template <typename In>
+    struct MapInputIndicator<In,
+      typename exists<typename In::Value>::type> {
+      static const bool value = true;
+    };
+
+    template <typename In, typename Enable = void>
+    struct SequenceOutputIndicator {
+      static const bool value = false;
+    };
+
+    template <typename Out>
+    struct SequenceOutputIndicator<Out,
+      typename exists<typename Out::value_type>::type> {
+      static const bool value = true;
+    };
+
+    template <typename Out, typename Enable = void>
+    struct MapOutputIndicator {
+      static const bool value = false;
+    };
+
+    template <typename Out>
+    struct MapOutputIndicator<Out,
+      typename exists<typename Out::Value>::type> {
+      static const bool value = true;
+    };
+
+    template <typename In, typename InEnable = void>
+    struct KruskalValueSelector {};
+
+    template <typename In>
+    struct KruskalValueSelector<In,
+      typename enable_if<SequenceInputIndicator<In>, void>::type>
+    {
+      typedef typename In::value_type::second_type Value;
+    };
+
+    template <typename In>
+    struct KruskalValueSelector<In,
+      typename enable_if<MapInputIndicator<In>, void>::type>
+    {
+      typedef typename In::Value Value;
+    };
+
+    template <typename Graph, typename In, typename Out,
+              typename InEnable = void>
+    struct KruskalInputSelector {};
+
+    template <typename Graph, typename In, typename Out,
+              typename InEnable = void>
+    struct KruskalOutputSelector {};
+
+    template <typename Graph, typename In, typename Out>
+    struct KruskalInputSelector<Graph, In, Out,
+      typename enable_if<SequenceInputIndicator<In>, void>::type >
+    {
+      typedef typename In::value_type::second_type Value;
+
+      static Value kruskal(const Graph& graph, const In& in, Out& out) {
+        return KruskalOutputSelector<Graph, In, Out>::
+          kruskal(graph, in, out);
+      }
+
+    };
+
+    template <typename Graph, typename In, typename Out>
+    struct KruskalInputSelector<Graph, In, Out,
+      typename enable_if<MapInputIndicator<In>, void>::type >
+    {
+      typedef typename In::Value Value;
+      static Value kruskal(const Graph& graph, const In& in, Out& out) {
+        typedef typename In::Key MapArc;
+        typedef typename In::Value Value;
+        typedef typename ItemSetTraits<Graph, MapArc>::ItemIt MapArcIt;
+        typedef std::vector<std::pair<MapArc, Value> > Sequence;
+        Sequence seq;
+
+        for (MapArcIt it(graph); it != INVALID; ++it) {
+          seq.push_back(std::make_pair(it, in[it]));
+        }
+
+        std::sort(seq.begin(), seq.end(), PairComp<Sequence>());
+        return KruskalOutputSelector<Graph, Sequence, Out>::
+          kruskal(graph, seq, out);
+      }
+    };
+
+    template <typename T>
+    struct RemoveConst {
+      typedef T type;
+    };
+
+    template <typename T>
+    struct RemoveConst<const T> {
+      typedef T type;
+    };
+
+    template <typename Graph, typename In, typename Out>
+    struct KruskalOutputSelector<Graph, In, Out,
+      typename enable_if<SequenceOutputIndicator<Out>, void>::type >
+    {
+      typedef typename In::value_type::second_type Value;
+
+      static Value kruskal(const Graph& graph, const In& in, Out& out) {
+        typedef LoggerBoolMap<typename RemoveConst<Out>::type> Map;
+        Map map(out);
+        return _kruskal_bits::kruskal(graph, in, map);
+      }
+
+    };
+
+    template <typename Graph, typename In, typename Out>
+    struct KruskalOutputSelector<Graph, In, Out,
+      typename enable_if<MapOutputIndicator<Out>, void>::type >
+    {
+      typedef typename In::value_type::second_type Value;
+
+      static Value kruskal(const Graph& graph, const In& in, Out& out) {
+        return _kruskal_bits::kruskal(graph, in, out);
+      }
+    };
+
+  }
+
+  /// \ingroup spantree
+  ///
+  /// \brief Kruskal's algorithm for finding a minimum cost spanning tree of
+  /// a graph.
+  ///
+  /// This function runs Kruskal's algorithm to find a minimum cost
+  /// spanning tree of a graph.
+  /// Due to some C++ hacking, it accepts various input and output types.
+  ///
+  /// \param g The graph the algorithm runs on.
+  /// It can be either \ref concepts::Digraph "directed" or
+  /// \ref concepts::Graph "undirected".
+  /// If the graph is directed, the algorithm consider it to be
+  /// undirected by disregarding the direction of the arcs.
+  ///
+  /// \param in This object is used to describe the arc/edge costs.
+  /// It can be one of the following choices.
+  /// - An STL compatible 'Forward Container' with
+  /// <tt>std::pair<GR::Arc,C></tt> or
+  /// <tt>std::pair<GR::Edge,C></tt> as its <tt>value_type</tt>, where
+  /// \c C is the type of the costs. The pairs indicates the arcs/edges
+  /// along with the assigned cost. <em>They must be in a
+  /// cost-ascending order.</em>
+  /// - Any readable arc/edge map. The values of the map indicate the
+  /// arc/edge costs.
+  ///
+  /// \retval out Here we also have a choice.
+  /// - It can be a writable arc/edge map with \c bool value type. After
+  /// running the algorithm it will contain the found minimum cost spanning
+  /// tree: the value of an arc/edge will be set to \c true if it belongs
+  /// to the tree, otherwise it will be set to \c false. The value of
+  /// each arc/edge will be set exactly once.
+  /// - It can also be an iteraror of an STL Container with
+  /// <tt>GR::Arc</tt> or <tt>GR::Edge</tt> as its
+  /// <tt>value_type</tt>.  The algorithm copies the elements of the
+  /// found tree into this sequence.  For example, if we know that the
+  /// spanning tree of the graph \c g has say 53 arcs, then we can
+  /// put its arcs into an STL vector \c tree with a code like this.
+  ///\code
+  /// std::vector<Arc> tree(53);
+  /// kruskal(g,cost,tree.begin());
+  ///\endcode
+  /// Or if we don't know in advance the size of the tree, we can
+  /// write this.
+  ///\code
+  /// std::vector<Arc> tree;
+  /// kruskal(g,cost,std::back_inserter(tree));
+  ///\endcode
+  ///
+  /// \return The total cost of the found spanning tree.
+  ///
+  /// \note If the input graph is not (weakly) connected, a spanning
+  /// forest is calculated instead of a spanning tree.
+
+#ifdef DOXYGEN
+  template <typename Graph, typename In, typename Out>
+  Value kruskal(const Graph& g, const In& in, Out& out)
+#else
+  template <class Graph, class In, class Out>
+  inline typename _kruskal_bits::KruskalValueSelector<In>::Value
+  kruskal(const Graph& graph, const In& in, Out& out)
+#endif
+  {
+    return _kruskal_bits::KruskalInputSelector<Graph, In, Out>::
+      kruskal(graph, in, out);
+  }
+
+
+  template <class Graph, class In, class Out>
+  inline typename _kruskal_bits::KruskalValueSelector<In>::Value
+  kruskal(const Graph& graph, const In& in, const Out& out)
+  {
+    return _kruskal_bits::KruskalInputSelector<Graph, In, const Out>::
+      kruskal(graph, in, out);
+  }
+
+} //namespace lemon
+
+#endif //LEMON_KRUSKAL_H
diff --git a/lemon/lemon.pc.in b/lemon/lemon.pc.in
new file mode 100644
index 0000000..e85bf76
--- /dev/null
+++ b/lemon/lemon.pc.in
@@ -0,0 +1,10 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
+libdir=@CMAKE_INSTALL_PREFIX@/lib
+includedir=@CMAKE_INSTALL_PREFIX@/include
+
+Name: @PROJECT_NAME@
+Description: Library for Efficient Modeling and Optimization in Networks
+Version: @PROJECT_VERSION@
+Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
+Cflags: -I${includedir}
diff --git a/lemon/lgf_reader.h b/lemon/lgf_reader.h
new file mode 100644
index 0000000..2f49fa2
--- /dev/null
+++ b/lemon/lgf_reader.h
@@ -0,0 +1,3854 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup lemon_io
+///\file
+///\brief \ref lgf-format "LEMON Graph Format" reader.
+
+
+#ifndef LEMON_LGF_READER_H
+#define LEMON_LGF_READER_H
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <set>
+#include <map>
+
+#include <lemon/core.h>
+
+#include <lemon/lgf_writer.h>
+
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
+
+namespace lemon {
+
+  namespace _reader_bits {
+
+    template <typename Value>
+    struct DefaultConverter {
+      Value operator()(const std::string& str) {
+        std::istringstream is(str);
+        Value value;
+        if (!(is >> value)) {
+          throw FormatError("Cannot read token");
+        }
+
+        char c;
+        if (is >> std::ws >> c) {
+          throw FormatError("Remaining characters in token");
+        }
+        return value;
+      }
+    };
+
+    template <>
+    struct DefaultConverter<std::string> {
+      std::string operator()(const std::string& str) {
+        return str;
+      }
+    };
+
+    template <typename _Item>
+    class MapStorageBase {
+    public:
+      typedef _Item Item;
+
+    public:
+      MapStorageBase() {}
+      virtual ~MapStorageBase() {}
+
+      virtual void set(const Item& item, const std::string& value) = 0;
+
+    };
+
+    template <typename _Item, typename _Map,
+              typename _Converter = DefaultConverter<typename _Map::Value> >
+    class MapStorage : public MapStorageBase<_Item> {
+    public:
+      typedef _Map Map;
+      typedef _Converter Converter;
+      typedef _Item Item;
+
+    private:
+      Map& _map;
+      Converter _converter;
+
+    public:
+      MapStorage(Map& map, const Converter& converter = Converter())
+        : _map(map), _converter(converter) {}
+      virtual ~MapStorage() {}
+
+      virtual void set(const Item& item ,const std::string& value) {
+        _map.set(item, _converter(value));
+      }
+    };
+
+    template <typename _GR, bool _dir, typename _Map,
+              typename _Converter = DefaultConverter<typename _Map::Value> >
+    class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
+    public:
+      typedef _Map Map;
+      typedef _Converter Converter;
+      typedef _GR GR;
+      typedef typename GR::Edge Item;
+      static const bool dir = _dir;
+
+    private:
+      const GR& _graph;
+      Map& _map;
+      Converter _converter;
+
+    public:
+      GraphArcMapStorage(const GR& graph, Map& map,
+                         const Converter& converter = Converter())
+        : _graph(graph), _map(map), _converter(converter) {}
+      virtual ~GraphArcMapStorage() {}
+
+      virtual void set(const Item& item ,const std::string& value) {
+        _map.set(_graph.direct(item, dir), _converter(value));
+      }
+    };
+
+    class ValueStorageBase {
+    public:
+      ValueStorageBase() {}
+      virtual ~ValueStorageBase() {}
+
+      virtual void set(const std::string&) = 0;
+    };
+
+    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
+    class ValueStorage : public ValueStorageBase {
+    public:
+      typedef _Value Value;
+      typedef _Converter Converter;
+
+    private:
+      Value& _value;
+      Converter _converter;
+
+    public:
+      ValueStorage(Value& value, const Converter& converter = Converter())
+        : _value(value), _converter(converter) {}
+
+      virtual void set(const std::string& value) {
+        _value = _converter(value);
+      }
+    };
+
+    template <typename Value,
+              typename Map = std::map<std::string, Value> >
+    struct MapLookUpConverter {
+      const Map& _map;
+
+      MapLookUpConverter(const Map& map)
+        : _map(map) {}
+
+      Value operator()(const std::string& str) {
+        typename Map::const_iterator it = _map.find(str);
+        if (it == _map.end()) {
+          std::ostringstream msg;
+          msg << "Item not found: " << str;
+          throw FormatError(msg.str());
+        }
+        return it->second;
+      }
+    };
+
+    template <typename Value,
+              typename Map1 = std::map<std::string, Value>,
+              typename Map2 = std::map<std::string, Value> >
+    struct DoubleMapLookUpConverter {
+      const Map1& _map1;
+      const Map2& _map2;
+
+      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
+        : _map1(map1), _map2(map2) {}
+
+      Value operator()(const std::string& str) {
+        typename Map1::const_iterator it1 = _map1.find(str);
+        typename Map2::const_iterator it2 = _map2.find(str);
+        if (it1 == _map1.end()) {
+          if (it2 == _map2.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << str;
+            throw FormatError(msg.str());
+          } else {
+            return it2->second;
+          }
+        } else {
+          if (it2 == _map2.end()) {
+            return it1->second;
+          } else {
+            std::ostringstream msg;
+            msg << "Item is ambigous: " << str;
+            throw FormatError(msg.str());
+          }
+        }
+      }
+    };
+
+    template <typename GR>
+    struct GraphArcLookUpConverter {
+      const GR& _graph;
+      const std::map<std::string, typename GR::Edge>& _map;
+
+      GraphArcLookUpConverter(const GR& graph,
+                              const std::map<std::string,
+                                             typename GR::Edge>& map)
+        : _graph(graph), _map(map) {}
+
+      typename GR::Arc operator()(const std::string& str) {
+        if (str.empty() || (str[0] != '+' && str[0] != '-')) {
+          throw FormatError("Item must start with '+' or '-'");
+        }
+        typename std::map<std::string, typename GR::Edge>
+          ::const_iterator it = _map.find(str.substr(1));
+        if (it == _map.end()) {
+          throw FormatError("Item not found");
+        }
+        return _graph.direct(it->second, str[0] == '+');
+      }
+    };
+
+    inline bool isWhiteSpace(char c) {
+      return c == ' ' || c == '\t' || c == '\v' ||
+        c == '\n' || c == '\r' || c == '\f';
+    }
+
+    inline bool isOct(char c) {
+      return '0' <= c && c <='7';
+    }
+
+    inline int valueOct(char c) {
+      LEMON_ASSERT(isOct(c), "The character is not octal.");
+      return c - '0';
+    }
+
+    inline bool isHex(char c) {
+      return ('0' <= c && c <= '9') ||
+        ('a' <= c && c <= 'z') ||
+        ('A' <= c && c <= 'Z');
+    }
+
+    inline int valueHex(char c) {
+      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
+      if ('0' <= c && c <= '9') return c - '0';
+      if ('a' <= c && c <= 'z') return c - 'a' + 10;
+      return c - 'A' + 10;
+    }
+
+    inline bool isIdentifierFirstChar(char c) {
+      return ('a' <= c && c <= 'z') ||
+        ('A' <= c && c <= 'Z') || c == '_';
+    }
+
+    inline bool isIdentifierChar(char c) {
+      return isIdentifierFirstChar(c) ||
+        ('0' <= c && c <= '9');
+    }
+
+    inline char readEscape(std::istream& is) {
+      char c;
+      if (!is.get(c))
+        throw FormatError("Escape format error");
+
+      switch (c) {
+      case '\\':
+        return '\\';
+      case '\"':
+        return '\"';
+      case '\'':
+        return '\'';
+      case '\?':
+        return '\?';
+      case 'a':
+        return '\a';
+      case 'b':
+        return '\b';
+      case 'f':
+        return '\f';
+      case 'n':
+        return '\n';
+      case 'r':
+        return '\r';
+      case 't':
+        return '\t';
+      case 'v':
+        return '\v';
+      case 'x':
+        {
+          int code;
+          if (!is.get(c) || !isHex(c))
+            throw FormatError("Escape format error");
+          else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
+          else code = code * 16 + valueHex(c);
+          return code;
+        }
+      default:
+        {
+          int code;
+          if (!isOct(c))
+            throw FormatError("Escape format error");
+          else if (code = valueOct(c), !is.get(c) || !isOct(c))
+            is.putback(c);
+          else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
+            is.putback(c);
+          else code = code * 8 + valueOct(c);
+          return code;
+        }
+      }
+    }
+
+    inline std::istream& readToken(std::istream& is, std::string& str) {
+      std::ostringstream os;
+
+      char c;
+      is >> std::ws;
+
+      if (!is.get(c))
+        return is;
+
+      if (c == '\"') {
+        while (is.get(c) && c != '\"') {
+          if (c == '\\')
+            c = readEscape(is);
+          os << c;
+        }
+        if (!is)
+          throw FormatError("Quoted format error");
+      } else {
+        is.putback(c);
+        while (is.get(c) && !isWhiteSpace(c)) {
+          if (c == '\\')
+            c = readEscape(is);
+          os << c;
+        }
+        if (!is) {
+          is.clear();
+        } else {
+          is.putback(c);
+        }
+      }
+      str = os.str();
+      return is;
+    }
+
+    class Section {
+    public:
+      virtual ~Section() {}
+      virtual void process(std::istream& is, int& line_num) = 0;
+    };
+
+    template <typename Functor>
+    class LineSection : public Section {
+    private:
+
+      Functor _functor;
+
+    public:
+
+      LineSection(const Functor& functor) : _functor(functor) {}
+      virtual ~LineSection() {}
+
+      virtual void process(std::istream& is, int& line_num) {
+        char c;
+        std::string line;
+        while (is.get(c) && c != '@') {
+          if (c == '\n') {
+            ++line_num;
+          } else if (c == '#') {
+            getline(is, line);
+            ++line_num;
+          } else if (!isWhiteSpace(c)) {
+            is.putback(c);
+            getline(is, line);
+            _functor(line);
+            ++line_num;
+          }
+        }
+        if (is) is.putback(c);
+        else if (is.eof()) is.clear();
+      }
+    };
+
+    template <typename Functor>
+    class StreamSection : public Section {
+    private:
+
+      Functor _functor;
+
+    public:
+
+      StreamSection(const Functor& functor) : _functor(functor) {}
+      virtual ~StreamSection() {}
+
+      virtual void process(std::istream& is, int& line_num) {
+        _functor(is, line_num);
+        char c;
+        std::string line;
+        while (is.get(c) && c != '@') {
+          if (c == '\n') {
+            ++line_num;
+          } else if (!isWhiteSpace(c)) {
+            getline(is, line);
+            ++line_num;
+          }
+        }
+        if (is) is.putback(c);
+        else if (is.eof()) is.clear();
+      }
+    };
+
+  }
+
+  template <typename DGR>
+  class DigraphReader;
+
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" reader for directed graphs
+  ///
+  /// This utility reads an \ref lgf-format "LGF" file.
+  ///
+  /// The reading method does a batch processing. The user creates a
+  /// reader object, then various reading rules can be added to the
+  /// reader, and eventually the reading is executed with the \c run()
+  /// member function. A map reading rule can be added to the reader
+  /// with the \c nodeMap() or \c arcMap() members. An optional
+  /// converter parameter can also be added as a standard functor
+  /// converting from \c std::string to the value type of the map. If it
+  /// is set, it will determine how the tokens in the file should be
+  /// converted to the value type of the map. If the functor is not set,
+  /// then a default conversion will be used. One map can be read into
+  /// multiple map objects at the same time. The \c attribute(), \c
+  /// node() and \c arc() functions are used to add attribute reading
+  /// rules.
+  ///
+  ///\code
+  /// DigraphReader<DGR>(digraph, std::cin).
+  ///   nodeMap("coordinates", coord_map).
+  ///   arcMap("capacity", cap_map).
+  ///   node("source", src).
+  ///   node("target", trg).
+  ///   attribute("caption", caption).
+  ///   run();
+  ///\endcode
+  ///
+  /// 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
+  /// \c nodes(), \c arcs() or \c attributes() functions.
+  ///
+  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
+  /// that the nodes or arcs should not be constructed (added to the
+  /// graph) during the reading, but instead the label map of the items
+  /// are given as a parameter of these functions. An
+  /// application of these functions is multipass reading, which is
+  /// important if two \c \@arcs sections must be read from the
+  /// file. In this case the first phase would read the node set and one
+  /// of the arc sets, while the second phase would read the second arc
+  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
+  /// The previously read label node map should be passed to the \c
+  /// useNodes() functions. Another application of multipass reading when
+  /// paths are given as a node map or an arc map.
+  /// It is impossible to read this in
+  /// a single pass, because the arcs are not constructed when the node
+  /// maps are read.
+  template <typename DGR>
+  class DigraphReader {
+  public:
+
+    typedef DGR Digraph;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
+
+    std::istream* _is;
+    bool local_is;
+    std::string _filename;
+
+    DGR& _digraph;
+
+    std::string _nodes_caption;
+    std::string _arcs_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<std::string, Node> NodeIndex;
+    NodeIndex _node_index;
+    typedef std::map<std::string, Arc> ArcIndex;
+    ArcIndex _arc_index;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
+    NodeMaps _node_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
+    ArcMaps _arc_maps;
+
+    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
+      Attributes;
+    Attributes _attributes;
+
+    bool _use_nodes;
+    bool _use_arcs;
+
+    bool _skip_nodes;
+    bool _skip_arcs;
+
+    int line_num;
+    std::istringstream line;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct a directed graph reader, which reads from the given
+    /// input stream.
+    DigraphReader(DGR& digraph, std::istream& is = std::cin)
+      : _is(&is), local_is(false), _digraph(digraph),
+        _use_nodes(false), _use_arcs(false),
+        _skip_nodes(false), _skip_arcs(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a directed graph reader, which reads from the given
+    /// file.
+    DigraphReader(DGR& digraph, const std::string& fn)
+      : _is(new std::ifstream(fn.c_str())), local_is(true),
+        _filename(fn), _digraph(digraph),
+        _use_nodes(false), _use_arcs(false),
+        _skip_nodes(false), _skip_arcs(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct a directed graph reader, which reads from the given
+    /// file.
+    DigraphReader(DGR& digraph, const char* fn)
+      : _is(new std::ifstream(fn)), local_is(true),
+        _filename(fn), _digraph(digraph),
+        _use_nodes(false), _use_arcs(false),
+        _skip_nodes(false), _skip_arcs(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~DigraphReader() {
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename ArcMaps::iterator it = _arc_maps.begin();
+           it != _arc_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_is) {
+        delete _is;
+      }
+
+    }
+
+  private:
+
+    template <typename TDGR>
+    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
+    template <typename TDGR>
+    friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
+                                             const std::string& fn);
+    template <typename TDGR>
+    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
+
+    DigraphReader(DigraphReader& other)
+      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
+        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
+        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
+
+      other._is = 0;
+      other.local_is = false;
+
+      _node_index.swap(other._node_index);
+      _arc_index.swap(other._arc_index);
+
+      _node_maps.swap(other._node_maps);
+      _arc_maps.swap(other._arc_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _arcs_caption = other._arcs_caption;
+      _attributes_caption = other._attributes_caption;
+
+    }
+
+    DigraphReader& operator=(const DigraphReader&);
+
+  public:
+
+    /// \name Reading Rules
+    /// @{
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule to the reader.
+    template <typename Map>
+    DigraphReader& nodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map>(map);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    DigraphReader& nodeMap(const std::string& caption, Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule to the reader.
+    template <typename Map>
+    DigraphReader& arcMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Arc>* storage =
+        new _reader_bits::MapStorage<Arc, Map>(map);
+      _arc_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    DigraphReader& arcMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Arc>* storage =
+        new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
+      _arc_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute reading rule
+    ///
+    /// Add an attribute reading rule to the reader.
+    template <typename Value>
+    DigraphReader& attribute(const std::string& caption, Value& value) {
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Value>(value);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute reading rule
+    ///
+    /// Add an attribute reading rule with specialized converter to the
+    /// reader.
+    template <typename Value, typename Converter>
+    DigraphReader& attribute(const std::string& caption, Value& value,
+                             const Converter& converter = Converter()) {
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node reading rule
+    ///
+    /// Add a node reading rule to reader.
+    DigraphReader& node(const std::string& caption, Node& node) {
+      typedef _reader_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc reading rule
+    ///
+    /// Add an arc reading rule to reader.
+    DigraphReader& arc(const std::string& caption, Arc& arc) {
+      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
+      Converter converter(_arc_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Select Section by Name
+    /// @{
+
+    /// \brief Set \c \@nodes section to be read
+    ///
+    /// Set \c \@nodes section to be read
+    DigraphReader& nodes(const std::string& caption) {
+      _nodes_caption = caption;
+      return *this;
+    }
+
+    /// \brief Set \c \@arcs section to be read
+    ///
+    /// Set \c \@arcs section to be read
+    DigraphReader& arcs(const std::string& caption) {
+      _arcs_caption = caption;
+      return *this;
+    }
+
+    /// \brief Set \c \@attributes section to be read
+    ///
+    /// Set \c \@attributes section to be read
+    DigraphReader& attributes(const std::string& caption) {
+      _attributes_caption = caption;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Using Previously Constructed Node or Arc Set
+    /// @{
+
+    /// \brief Use previously constructed node set
+    ///
+    /// Use previously constructed node set, and specify the node
+    /// label map.
+    template <typename Map>
+    DigraphReader& useNodes(const Map& map) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
+      _use_nodes = true;
+      _writer_bits::DefaultConverter<typename Map::Value> converter;
+      for (NodeIt n(_digraph); n != INVALID; ++n) {
+        _node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed node set
+    ///
+    /// Use previously constructed node set, and specify the node
+    /// label map and a functor which converts the label map values to
+    /// \c std::string.
+    template <typename Map, typename Converter>
+    DigraphReader& useNodes(const Map& map,
+                            const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
+      _use_nodes = true;
+      for (NodeIt n(_digraph); n != INVALID; ++n) {
+        _node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed arc set
+    ///
+    /// Use previously constructed arc set, and specify the arc
+    /// label map.
+    template <typename Map>
+    DigraphReader& useArcs(const Map& map) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
+      _use_arcs = true;
+      _writer_bits::DefaultConverter<typename Map::Value> converter;
+      for (ArcIt a(_digraph); a != INVALID; ++a) {
+        _arc_index.insert(std::make_pair(converter(map[a]), a));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed arc set
+    ///
+    /// Use previously constructed arc set, and specify the arc
+    /// label map and a functor which converts the label map values to
+    /// \c std::string.
+    template <typename Map, typename Converter>
+    DigraphReader& useArcs(const Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
+      _use_arcs = true;
+      for (ArcIt a(_digraph); a != INVALID; ++a) {
+        _arc_index.insert(std::make_pair(converter(map[a]), a));
+      }
+      return *this;
+    }
+
+    /// \brief Skips the reading of node section
+    ///
+    /// Omit the reading of the node section. This implies that each node
+    /// map reading rule will be abandoned, and the nodes of the graph
+    /// will not be constructed, which usually cause that the arc set
+    /// could not be read due to lack of node name resolving.
+    /// Therefore \c skipArcs() function should also be used, or
+    /// \c useNodes() should be used to specify the label of the nodes.
+    DigraphReader& skipNodes() {
+      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
+      _skip_nodes = true;
+      return *this;
+    }
+
+    /// \brief Skips the reading of arc section
+    ///
+    /// Omit the reading of the arc section. This implies that each arc
+    /// map reading rule will be abandoned, and the arcs of the graph
+    /// will not be constructed.
+    DigraphReader& skipArcs() {
+      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
+      _skip_arcs = true;
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    bool readLine() {
+      std::string str;
+      while(++line_num, std::getline(*_is, str)) {
+        line.clear(); line.str(str);
+        char c;
+        if (line >> std::ws >> c && c != '#') {
+          line.putback(c);
+          return true;
+        }
+      }
+      return false;
+    }
+
+    bool readSuccess() {
+      return static_cast<bool>(*_is);
+    }
+
+    void skipSection() {
+      char c;
+      while (readSuccess() && line >> c && c != '@') {
+        readLine();
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readNodes() {
+
+      std::vector<int> map_index(_node_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_node_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of node map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_node_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _node_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        Node n;
+        if (!_use_nodes) {
+          n = _digraph.addNode();
+          if (label_index != -1)
+            _node_index.insert(std::make_pair(tokens[label_index], n));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, Node>::iterator it =
+            _node_index.find(tokens[label_index]);
+          if (it == _node_index.end()) {
+            std::ostringstream msg;
+            msg << "Node with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          n = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
+          _node_maps[i].second->set(n, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readArcs() {
+
+      std::vector<int> map_index(_arc_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_arc_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if(map == "-") {
+              if(index!=0)
+                throw FormatError("'-' is not allowed as a map name");
+              else if (line >> std::ws >> c)
+                throw FormatError("Extra character at the end of line");
+              else break;
+            }
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of arc map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_arc_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _arc_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::string source_token;
+        std::string target_token;
+
+        if (!_reader_bits::readToken(line, source_token))
+          throw FormatError("Source not found");
+
+        if (!_reader_bits::readToken(line, target_token))
+          throw FormatError("Target not found");
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        Arc a;
+        if (!_use_arcs) {
+
+          typename NodeIndex::iterator it;
+
+          it = _node_index.find(source_token);
+          if (it == _node_index.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << source_token;
+            throw FormatError(msg.str());
+          }
+          Node source = it->second;
+
+          it = _node_index.find(target_token);
+          if (it == _node_index.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << target_token;
+            throw FormatError(msg.str());
+          }
+          Node target = it->second;
+
+          a = _digraph.addArc(source, target);
+          if (label_index != -1)
+            _arc_index.insert(std::make_pair(tokens[label_index], a));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, Arc>::iterator it =
+            _arc_index.find(tokens[label_index]);
+          if (it == _arc_index.end()) {
+            std::ostringstream msg;
+            msg << "Arc with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          a = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
+          _arc_maps[i].second->set(a, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readAttributes() {
+
+      std::set<std::string> read_attr;
+
+      char c;
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::string attr, token;
+        if (!_reader_bits::readToken(line, attr))
+          throw FormatError("Attribute name not found");
+        if (!_reader_bits::readToken(line, token))
+          throw FormatError("Attribute value not found");
+        if (line >> c)
+          throw FormatError("Extra character at the end of line");
+
+        {
+          std::set<std::string>::iterator it = read_attr.find(attr);
+          if (it != read_attr.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of attribute: " << attr;
+            throw FormatError(msg.str());
+          }
+          read_attr.insert(attr);
+        }
+
+        {
+          typename Attributes::iterator it = _attributes.lower_bound(attr);
+          while (it != _attributes.end() && it->first == attr) {
+            it->second->set(token);
+            ++it;
+          }
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        if (read_attr.find(it->first) == read_attr.end()) {
+          std::ostringstream msg;
+          msg << "Attribute not found: " << it->first;
+          throw FormatError(msg.str());
+        }
+      }
+    }
+
+  public:
+
+    /// \name Execution of the Reader
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing
+    void run() {
+      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
+
+      bool nodes_done = _skip_nodes;
+      bool arcs_done = _skip_arcs;
+      bool attributes_done = false;
+
+      line_num = 0;
+      readLine();
+      skipSection();
+
+      while (readSuccess()) {
+        try {
+          char c;
+          std::string section, caption;
+          line >> c;
+          _reader_bits::readToken(line, section);
+          _reader_bits::readToken(line, caption);
+
+          if (line >> c)
+            throw FormatError("Extra character at the end of line");
+
+          if (section == "nodes" && !nodes_done) {
+            if (_nodes_caption.empty() || _nodes_caption == caption) {
+              readNodes();
+              nodes_done = true;
+            }
+          } else if ((section == "arcs" || section == "edges") &&
+                     !arcs_done) {
+            if (_arcs_caption.empty() || _arcs_caption == caption) {
+              readArcs();
+              arcs_done = true;
+            }
+          } else if (section == "attributes" && !attributes_done) {
+            if (_attributes_caption.empty() || _attributes_caption == caption) {
+              readAttributes();
+              attributes_done = true;
+            }
+          } else {
+            readLine();
+            skipSection();
+          }
+        } catch (FormatError& error) {
+          error.line(line_num);
+          error.file(_filename);
+          throw;
+        }
+      }
+
+      if (!nodes_done) {
+        throw FormatError("Section @nodes not found");
+      }
+
+      if (!arcs_done) {
+        throw FormatError("Section @arcs not found");
+      }
+
+      if (!attributes_done && !_attributes.empty()) {
+        throw FormatError("Section @attributes not found");
+      }
+
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref lemon::DigraphReader "DigraphReader" class
+  ///
+  /// This function just returns a \ref lemon::DigraphReader
+  /// "DigraphReader" class.
+  ///
+  /// With this function a digraph can be read from an
+  /// \ref lgf-format "LGF" file or input stream with several maps and
+  /// attributes. For example, there is network flow problem on a
+  /// digraph, i.e. a digraph with a \e capacity map on the arcs and
+  /// \e source and \e target nodes. This digraph can be read with the
+  /// following code:
+  ///
+  ///\code
+  ///ListDigraph digraph;
+  ///ListDigraph::ArcMap<int> cm(digraph);
+  ///ListDigraph::Node src, trg;
+  ///digraphReader(digraph, std::cin).
+  ///  arcMap("capacity", cap).
+  ///  node("source", src).
+  ///  node("target", trg).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the
+  /// \ref lemon::DigraphReader "DigraphReader"
+  /// class documentation.
+  /// \warning Don't forget to put the \ref lemon::DigraphReader::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates DigraphReader
+  /// \sa digraphReader(TDGR& digraph, const std::string& fn)
+  /// \sa digraphReader(TDGR& digraph, const char* fn)
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
+    DigraphReader<TDGR> tmp(digraph, is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  /// \relates DigraphReader
+  /// \sa digraphReader(TDGR& digraph, std::istream& is)
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
+    DigraphReader<TDGR> tmp(digraph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  /// \relates DigraphReader
+  /// \sa digraphReader(TDGR& digraph, std::istream& is)
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
+    DigraphReader<TDGR> tmp(digraph, fn);
+    return tmp;
+  }
+
+  template <typename GR>
+  class GraphReader;
+
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, const char *fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" reader for undirected graphs
+  ///
+  /// This utility reads an \ref lgf-format "LGF" file.
+  ///
+  /// It can be used almost the same way as \c DigraphReader.
+  /// The only difference is that this class can handle edges and
+  /// edge maps as well as arcs and arc maps.
+  ///
+  /// The columns in the \c \@edges (or \c \@arcs) section are the
+  /// edge maps. However, if there are two maps with the same name
+  /// prefixed with \c '+' and \c '-', then these can be read into an
+  /// arc map.  Similarly, an attribute can be read into an arc, if
+  /// it's value is an edge label prefixed with \c '+' or \c '-'.
+  template <typename GR>
+  class GraphReader {
+  public:
+
+    typedef GR Graph;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(GR);
+
+    std::istream* _is;
+    bool local_is;
+    std::string _filename;
+
+    GR& _graph;
+
+    std::string _nodes_caption;
+    std::string _edges_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<std::string, Node> NodeIndex;
+    NodeIndex _node_index;
+    typedef std::map<std::string, Edge> EdgeIndex;
+    EdgeIndex _edge_index;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
+    NodeMaps _node_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
+    EdgeMaps _edge_maps;
+
+    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
+      Attributes;
+    Attributes _attributes;
+
+    bool _use_nodes;
+    bool _use_edges;
+
+    bool _skip_nodes;
+    bool _skip_edges;
+
+    int line_num;
+    std::istringstream line;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// input stream.
+    GraphReader(GR& graph, std::istream& is = std::cin)
+      : _is(&is), local_is(false), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// file.
+    GraphReader(GR& graph, const std::string& fn)
+      : _is(new std::ifstream(fn.c_str())), local_is(true),
+        _filename(fn), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// file.
+    GraphReader(GR& graph, const char* fn)
+      : _is(new std::ifstream(fn)), local_is(true),
+        _filename(fn), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~GraphReader() {
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_is) {
+        delete _is;
+      }
+
+    }
+
+  private:
+    template <typename TGR>
+    friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
+    template <typename TGR>
+    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
+    template <typename TGR>
+    friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
+
+    GraphReader(GraphReader& other)
+      : _is(other._is), local_is(other.local_is), _graph(other._graph),
+        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
+        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
+
+      other._is = 0;
+      other.local_is = false;
+
+      _node_index.swap(other._node_index);
+      _edge_index.swap(other._edge_index);
+
+      _node_maps.swap(other._node_maps);
+      _edge_maps.swap(other._edge_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _edges_caption = other._edges_caption;
+      _attributes_caption = other._attributes_caption;
+
+    }
+
+    GraphReader& operator=(const GraphReader&);
+
+  public:
+
+    /// \name Reading Rules
+    /// @{
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule to the reader.
+    template <typename Map>
+    GraphReader& nodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map>(map);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    GraphReader& nodeMap(const std::string& caption, Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map reading rule
+    ///
+    /// Add an edge map reading rule to the reader.
+    template <typename Map>
+    GraphReader& edgeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* storage =
+        new _reader_bits::MapStorage<Edge, Map>(map);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map reading rule
+    ///
+    /// Add an edge map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    GraphReader& edgeMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* storage =
+        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule to the reader.
+    template <typename Map>
+    GraphReader& arcMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* forward_storage =
+        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _reader_bits::MapStorageBase<Edge>* backward_storage =
+        new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    GraphReader& arcMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* forward_storage =
+        new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _reader_bits::MapStorageBase<Edge>* backward_storage =
+        new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Attribute reading rule
+    ///
+    /// Add an attribute reading rule to the reader.
+    template <typename Value>
+    GraphReader& attribute(const std::string& caption, Value& value) {
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Value>(value);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute reading rule
+    ///
+    /// Add an attribute reading rule with specialized converter to the
+    /// reader.
+    template <typename Value, typename Converter>
+    GraphReader& attribute(const std::string& caption, Value& value,
+                             const Converter& converter = Converter()) {
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node reading rule
+    ///
+    /// Add a node reading rule to reader.
+    GraphReader& node(const std::string& caption, Node& node) {
+      typedef _reader_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge reading rule
+    ///
+    /// Add an edge reading rule to reader.
+    GraphReader& edge(const std::string& caption, Edge& edge) {
+      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
+      Converter converter(_edge_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc reading rule
+    ///
+    /// Add an arc reading rule to reader.
+    GraphReader& arc(const std::string& caption, Arc& arc) {
+      typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
+      Converter converter(_graph, _edge_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Select Section by Name
+    /// @{
+
+    /// \brief Set \c \@nodes section to be read
+    ///
+    /// Set \c \@nodes section to be read.
+    GraphReader& nodes(const std::string& caption) {
+      _nodes_caption = caption;
+      return *this;
+    }
+
+    /// \brief Set \c \@edges section to be read
+    ///
+    /// Set \c \@edges section to be read.
+    GraphReader& edges(const std::string& caption) {
+      _edges_caption = caption;
+      return *this;
+    }
+
+    /// \brief Set \c \@attributes section to be read
+    ///
+    /// Set \c \@attributes section to be read.
+    GraphReader& attributes(const std::string& caption) {
+      _attributes_caption = caption;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Using Previously Constructed Node or Edge Set
+    /// @{
+
+    /// \brief Use previously constructed node set
+    ///
+    /// Use previously constructed node set, and specify the node
+    /// label map.
+    template <typename Map>
+    GraphReader& useNodes(const Map& map) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
+      _use_nodes = true;
+      _writer_bits::DefaultConverter<typename Map::Value> converter;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed node set
+    ///
+    /// Use previously constructed node set, and specify the node
+    /// label map and a functor which converts the label map values to
+    /// \c std::string.
+    template <typename Map, typename Converter>
+    GraphReader& useNodes(const Map& map,
+                            const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
+      _use_nodes = true;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed edge set
+    ///
+    /// Use previously constructed edge set, and specify the edge
+    /// label map.
+    template <typename Map>
+    GraphReader& useEdges(const Map& map) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
+      _use_edges = true;
+      _writer_bits::DefaultConverter<typename Map::Value> converter;
+      for (EdgeIt a(_graph); a != INVALID; ++a) {
+        _edge_index.insert(std::make_pair(converter(map[a]), a));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed edge set
+    ///
+    /// Use previously constructed edge set, and specify the edge
+    /// label map and a functor which converts the label map values to
+    /// \c std::string.
+    template <typename Map, typename Converter>
+    GraphReader& useEdges(const Map& map,
+                            const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
+      _use_edges = true;
+      for (EdgeIt a(_graph); a != INVALID; ++a) {
+        _edge_index.insert(std::make_pair(converter(map[a]), a));
+      }
+      return *this;
+    }
+
+    /// \brief Skip the reading of node section
+    ///
+    /// Omit the reading of the node section. This implies that each node
+    /// map reading rule will be abandoned, and the nodes of the graph
+    /// will not be constructed, which usually cause that the edge set
+    /// could not be read due to lack of node name
+    /// could not be read due to lack of node name resolving.
+    /// Therefore \c skipEdges() function should also be used, or
+    /// \c useNodes() should be used to specify the label of the nodes.
+    GraphReader& skipNodes() {
+      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
+      _skip_nodes = true;
+      return *this;
+    }
+
+    /// \brief Skip the reading of edge section
+    ///
+    /// Omit the reading of the edge section. This implies that each edge
+    /// map reading rule will be abandoned, and the edges of the graph
+    /// will not be constructed.
+    GraphReader& skipEdges() {
+      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
+      _skip_edges = true;
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    bool readLine() {
+      std::string str;
+      while(++line_num, std::getline(*_is, str)) {
+        line.clear(); line.str(str);
+        char c;
+        if (line >> std::ws >> c && c != '#') {
+          line.putback(c);
+          return true;
+        }
+      }
+      return false;
+    }
+
+    bool readSuccess() {
+      return static_cast<bool>(*_is);
+    }
+
+    void skipSection() {
+      char c;
+      while (readSuccess() && line >> c && c != '@') {
+        readLine();
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readNodes() {
+
+      std::vector<int> map_index(_node_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_node_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of node map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_node_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _node_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        Node n;
+        if (!_use_nodes) {
+          n = _graph.addNode();
+          if (label_index != -1)
+            _node_index.insert(std::make_pair(tokens[label_index], n));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, Node>::iterator it =
+            _node_index.find(tokens[label_index]);
+          if (it == _node_index.end()) {
+            std::ostringstream msg;
+            msg << "Node with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          n = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
+          _node_maps[i].second->set(n, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readEdges() {
+
+      std::vector<int> map_index(_edge_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_edge_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if(map == "-") {
+              if(index!=0)
+                throw FormatError("'-' is not allowed as a map name");
+              else if (line >> std::ws >> c)
+                throw FormatError("Extra character at the end of line");
+              else break;
+            }
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of edge map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_edge_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _edge_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::string source_token;
+        std::string target_token;
+
+        if (!_reader_bits::readToken(line, source_token))
+          throw FormatError("Node u not found");
+
+        if (!_reader_bits::readToken(line, target_token))
+          throw FormatError("Node v not found");
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        Edge e;
+        if (!_use_edges) {
+
+          typename NodeIndex::iterator it;
+
+          it = _node_index.find(source_token);
+          if (it == _node_index.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << source_token;
+            throw FormatError(msg.str());
+          }
+          Node source = it->second;
+
+          it = _node_index.find(target_token);
+          if (it == _node_index.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << target_token;
+            throw FormatError(msg.str());
+          }
+          Node target = it->second;
+
+          e = _graph.addEdge(source, target);
+          if (label_index != -1)
+            _edge_index.insert(std::make_pair(tokens[label_index], e));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, Edge>::iterator it =
+            _edge_index.find(tokens[label_index]);
+          if (it == _edge_index.end()) {
+            std::ostringstream msg;
+            msg << "Edge with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          e = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
+          _edge_maps[i].second->set(e, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readAttributes() {
+
+      std::set<std::string> read_attr;
+
+      char c;
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::string attr, token;
+        if (!_reader_bits::readToken(line, attr))
+          throw FormatError("Attribute name not found");
+        if (!_reader_bits::readToken(line, token))
+          throw FormatError("Attribute value not found");
+        if (line >> c)
+          throw FormatError("Extra character at the end of line");
+
+        {
+          std::set<std::string>::iterator it = read_attr.find(attr);
+          if (it != read_attr.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of attribute: " << attr;
+            throw FormatError(msg.str());
+          }
+          read_attr.insert(attr);
+        }
+
+        {
+          typename Attributes::iterator it = _attributes.lower_bound(attr);
+          while (it != _attributes.end() && it->first == attr) {
+            it->second->set(token);
+            ++it;
+          }
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        if (read_attr.find(it->first) == read_attr.end()) {
+          std::ostringstream msg;
+          msg << "Attribute not found: " << it->first;
+          throw FormatError(msg.str());
+        }
+      }
+    }
+
+  public:
+
+    /// \name Execution of the Reader
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing
+    void run() {
+
+      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
+
+      bool nodes_done = _skip_nodes;
+      bool edges_done = _skip_edges;
+      bool attributes_done = false;
+
+      line_num = 0;
+      readLine();
+      skipSection();
+
+      while (readSuccess()) {
+        try {
+          char c;
+          std::string section, caption;
+          line >> c;
+          _reader_bits::readToken(line, section);
+          _reader_bits::readToken(line, caption);
+
+          if (line >> c)
+            throw FormatError("Extra character at the end of line");
+
+          if (section == "nodes" && !nodes_done) {
+            if (_nodes_caption.empty() || _nodes_caption == caption) {
+              readNodes();
+              nodes_done = true;
+            }
+          } else if ((section == "edges" || section == "arcs") &&
+                     !edges_done) {
+            if (_edges_caption.empty() || _edges_caption == caption) {
+              readEdges();
+              edges_done = true;
+            }
+          } else if (section == "attributes" && !attributes_done) {
+            if (_attributes_caption.empty() || _attributes_caption == caption) {
+              readAttributes();
+              attributes_done = true;
+            }
+          } else {
+            readLine();
+            skipSection();
+          }
+        } catch (FormatError& error) {
+          error.line(line_num);
+          error.file(_filename);
+          throw;
+        }
+      }
+
+      if (!nodes_done) {
+        throw FormatError("Section @nodes not found");
+      }
+
+      if (!edges_done) {
+        throw FormatError("Section @edges not found");
+      }
+
+      if (!attributes_done && !_attributes.empty()) {
+        throw FormatError("Section @attributes not found");
+      }
+
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref lemon::GraphReader "GraphReader" class
+  ///
+  /// This function just returns a \ref lemon::GraphReader "GraphReader" class.
+  ///
+  /// With this function a graph can be read from an
+  /// \ref lgf-format "LGF" file or input stream with several maps and
+  /// attributes. For example, there is weighted matching problem on a
+  /// graph, i.e. a graph with a \e weight map on the edges. This
+  /// graph can be read with the following code:
+  ///
+  ///\code
+  ///ListGraph graph;
+  ///ListGraph::EdgeMap<int> weight(graph);
+  ///graphReader(graph, std::cin).
+  ///  edgeMap("weight", weight).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the
+  /// \ref lemon::GraphReader "GraphReader"
+  /// class documentation.
+  /// \warning Don't forget to put the \ref lemon::GraphReader::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates GraphReader
+  /// \sa graphReader(TGR& graph, const std::string& fn)
+  /// \sa graphReader(TGR& graph, const char* fn)
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
+    GraphReader<TGR> tmp(graph, is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref GraphReader class
+  ///
+  /// This function just returns a \ref GraphReader class.
+  /// \relates GraphReader
+  /// \sa graphReader(TGR& graph, std::istream& is)
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
+    GraphReader<TGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref GraphReader class
+  ///
+  /// This function just returns a \ref GraphReader class.
+  /// \relates GraphReader
+  /// \sa graphReader(TGR& graph, std::istream& is)
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
+    GraphReader<TGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  template <typename BGR>
+  class BpGraphReader;
+
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin);
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn);
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" reader for bipartite graphs
+  ///
+  /// This utility reads an \ref lgf-format "LGF" file.
+  ///
+  /// It can be used almost the same way as \c GraphReader, but it
+  /// reads the red and blue nodes from separate sections, and these
+  /// sections can contain different set of maps.
+  ///
+  /// The red and blue node maps are read from the corresponding
+  /// sections. If a map is defined with the same name in both of
+  /// these sections, then it can be read as a node map.
+  template <typename BGR>
+  class BpGraphReader {
+  public:
+
+    typedef BGR Graph;
+
+  private:
+
+    TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
+
+    std::istream* _is;
+    bool local_is;
+    std::string _filename;
+
+    BGR& _graph;
+
+    std::string _nodes_caption;
+    std::string _edges_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<std::string, RedNode> RedNodeIndex;
+    RedNodeIndex _red_node_index;
+    typedef std::map<std::string, BlueNode> BlueNodeIndex;
+    BlueNodeIndex _blue_node_index;
+    typedef std::map<std::string, Edge> EdgeIndex;
+    EdgeIndex _edge_index;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<RedNode>*> > RedNodeMaps;
+    RedNodeMaps _red_node_maps;
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<BlueNode>*> > BlueNodeMaps;
+    BlueNodeMaps _blue_node_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
+    EdgeMaps _edge_maps;
+
+    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
+      Attributes;
+    Attributes _attributes;
+
+    bool _use_nodes;
+    bool _use_edges;
+
+    bool _skip_nodes;
+    bool _skip_edges;
+
+    int line_num;
+    std::istringstream line;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// input stream.
+    BpGraphReader(BGR& graph, std::istream& is = std::cin)
+      : _is(&is), local_is(false), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// file.
+    BpGraphReader(BGR& graph, const std::string& fn)
+      : _is(new std::ifstream(fn.c_str())), local_is(true),
+        _filename(fn), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// file.
+    BpGraphReader(BGR& graph, const char* fn)
+      : _is(new std::ifstream(fn)), local_is(true),
+        _filename(fn), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~BpGraphReader() {
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_is) {
+        delete _is;
+      }
+
+    }
+
+  private:
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is);
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph,
+                                             const std::string& fn);
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
+
+    BpGraphReader(BpGraphReader& other)
+      : _is(other._is), local_is(other.local_is), _graph(other._graph),
+        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
+        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
+
+      other._is = 0;
+      other.local_is = false;
+
+      _red_node_index.swap(other._red_node_index);
+      _blue_node_index.swap(other._blue_node_index);
+      _edge_index.swap(other._edge_index);
+
+      _red_node_maps.swap(other._red_node_maps);
+      _blue_node_maps.swap(other._blue_node_maps);
+      _edge_maps.swap(other._edge_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _edges_caption = other._edges_caption;
+      _attributes_caption = other._attributes_caption;
+
+    }
+
+    BpGraphReader& operator=(const BpGraphReader&);
+
+  public:
+
+    /// \name Reading Rules
+    /// @{
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& nodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* red_storage =
+        new _reader_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _reader_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _reader_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& nodeMap(const std::string& caption, Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* red_storage =
+        new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _reader_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// Add a red node map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& redNodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* storage =
+        new _reader_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node map reading rule
+    ///
+    /// Add a red node map node reading rule with specialized converter to
+    /// the reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& redNodeMap(const std::string& caption, Map& map,
+                              const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* storage =
+        new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// Add a blue node map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& blueNodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<BlueNode>* storage =
+        new _reader_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node map reading rule
+    ///
+    /// Add a blue node map reading rule with specialized converter to
+    /// the reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& blueNodeMap(const std::string& caption, Map& map,
+                               const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<BlueNode>* storage =
+        new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map reading rule
+    ///
+    /// Add an edge map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& edgeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* storage =
+        new _reader_bits::MapStorage<Edge, Map>(map);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map reading rule
+    ///
+    /// Add an edge map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& edgeMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* storage =
+        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& arcMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* forward_storage =
+        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _reader_bits::MapStorageBase<Edge>* backward_storage =
+        new _reader_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& arcMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* forward_storage =
+        new _reader_bits::GraphArcMapStorage<BGR, true, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _reader_bits::MapStorageBase<Edge>* backward_storage =
+        new _reader_bits::GraphArcMapStorage<BGR, false, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Attribute reading rule
+    ///
+    /// Add an attribute reading rule to the reader.
+    template <typename Value>
+    BpGraphReader& attribute(const std::string& caption, Value& value) {
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Value>(value);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute reading rule
+    ///
+    /// Add an attribute reading rule with specialized converter to the
+    /// reader.
+    template <typename Value, typename Converter>
+    BpGraphReader& attribute(const std::string& caption, Value& value,
+                             const Converter& converter = Converter()) {
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node reading rule
+    ///
+    /// Add a node reading rule to reader.
+    BpGraphReader& node(const std::string& caption, Node& node) {
+      typedef _reader_bits::DoubleMapLookUpConverter<
+        Node, RedNodeIndex, BlueNodeIndex> Converter;
+      Converter converter(_red_node_index, _blue_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node reading rule
+    ///
+    /// Add a red node reading rule to reader.
+    BpGraphReader& redNode(const std::string& caption, RedNode& node) {
+      typedef _reader_bits::MapLookUpConverter<RedNode> Converter;
+      Converter converter(_red_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<RedNode, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node reading rule
+    ///
+    /// Add a blue node reading rule to reader.
+    BpGraphReader& blueNode(const std::string& caption, BlueNode& node) {
+      typedef _reader_bits::MapLookUpConverter<BlueNode> Converter;
+      Converter converter(_blue_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<BlueNode, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge reading rule
+    ///
+    /// Add an edge reading rule to reader.
+    BpGraphReader& edge(const std::string& caption, Edge& edge) {
+      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
+      Converter converter(_edge_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc reading rule
+    ///
+    /// Add an arc reading rule to reader.
+    BpGraphReader& arc(const std::string& caption, Arc& arc) {
+      typedef _reader_bits::GraphArcLookUpConverter<BGR> Converter;
+      Converter converter(_graph, _edge_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Select Section by Name
+    /// @{
+
+    /// \brief Set \c \@nodes section to be read
+    ///
+    /// Set \c \@nodes section to be read.
+    BpGraphReader& nodes(const std::string& caption) {
+      _nodes_caption = caption;
+      return *this;
+    }
+
+    /// \brief Set \c \@edges section to be read
+    ///
+    /// Set \c \@edges section to be read.
+    BpGraphReader& edges(const std::string& caption) {
+      _edges_caption = caption;
+      return *this;
+    }
+
+    /// \brief Set \c \@attributes section to be read
+    ///
+    /// Set \c \@attributes section to be read.
+    BpGraphReader& attributes(const std::string& caption) {
+      _attributes_caption = caption;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Using Previously Constructed Node or Edge Set
+    /// @{
+
+    /// \brief Use previously constructed node set
+    ///
+    /// Use previously constructed node set, and specify the node
+    /// label map.
+    template <typename Map>
+    BpGraphReader& useNodes(const Map& map) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
+      _use_nodes = true;
+      _writer_bits::DefaultConverter<typename Map::Value> converter;
+      for (RedNodeIt n(_graph); n != INVALID; ++n) {
+        _red_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+        _blue_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed node set
+    ///
+    /// Use previously constructed node set, and specify the node
+    /// label map and a functor which converts the label map values to
+    /// \c std::string.
+    template <typename Map, typename Converter>
+    BpGraphReader& useNodes(const Map& map,
+                            const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
+      _use_nodes = true;
+      for (RedNodeIt n(_graph); n != INVALID; ++n) {
+        _red_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+        _blue_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed edge set
+    ///
+    /// Use previously constructed edge set, and specify the edge
+    /// label map.
+    template <typename Map>
+    BpGraphReader& useEdges(const Map& map) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
+      _use_edges = true;
+      _writer_bits::DefaultConverter<typename Map::Value> converter;
+      for (EdgeIt a(_graph); a != INVALID; ++a) {
+        _edge_index.insert(std::make_pair(converter(map[a]), a));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed edge set
+    ///
+    /// Use previously constructed edge set, and specify the edge
+    /// label map and a functor which converts the label map values to
+    /// \c std::string.
+    template <typename Map, typename Converter>
+    BpGraphReader& useEdges(const Map& map,
+                            const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
+      _use_edges = true;
+      for (EdgeIt a(_graph); a != INVALID; ++a) {
+        _edge_index.insert(std::make_pair(converter(map[a]), a));
+      }
+      return *this;
+    }
+
+    /// \brief Skip the reading of node section
+    ///
+    /// Omit the reading of the node section. This implies that each node
+    /// map reading rule will be abandoned, and the nodes of the graph
+    /// will not be constructed, which usually cause that the edge set
+    /// could not be read due to lack of node name
+    /// could not be read due to lack of node name resolving.
+    /// Therefore \c skipEdges() function should also be used, or
+    /// \c useNodes() should be used to specify the label of the nodes.
+    BpGraphReader& skipNodes() {
+      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
+      _skip_nodes = true;
+      return *this;
+    }
+
+    /// \brief Skip the reading of edge section
+    ///
+    /// Omit the reading of the edge section. This implies that each edge
+    /// map reading rule will be abandoned, and the edges of the graph
+    /// will not be constructed.
+    BpGraphReader& skipEdges() {
+      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
+      _skip_edges = true;
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    bool readLine() {
+      std::string str;
+      while(++line_num, std::getline(*_is, str)) {
+        line.clear(); line.str(str);
+        char c;
+        if (line >> std::ws >> c && c != '#') {
+          line.putback(c);
+          return true;
+        }
+      }
+      return false;
+    }
+
+    bool readSuccess() {
+      return static_cast<bool>(*_is);
+    }
+
+    void skipSection() {
+      char c;
+      while (readSuccess() && line >> c && c != '@') {
+        readLine();
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readRedNodes() {
+
+      std::vector<int> map_index(_red_node_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_red_node_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of red node map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_red_node_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _red_node_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        RedNode n;
+        if (!_use_nodes) {
+          n = _graph.addRedNode();
+          if (label_index != -1)
+            _red_node_index.insert(std::make_pair(tokens[label_index], n));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, RedNode>::iterator it =
+            _red_node_index.find(tokens[label_index]);
+          if (it == _red_node_index.end()) {
+            std::ostringstream msg;
+            msg << "Node with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          n = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
+          _red_node_maps[i].second->set(n, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readBlueNodes() {
+
+      std::vector<int> map_index(_blue_node_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_blue_node_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of blue node map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_blue_node_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _blue_node_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        BlueNode n;
+        if (!_use_nodes) {
+          n = _graph.addBlueNode();
+          if (label_index != -1)
+            _blue_node_index.insert(std::make_pair(tokens[label_index], n));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, BlueNode>::iterator it =
+            _blue_node_index.find(tokens[label_index]);
+          if (it == _blue_node_index.end()) {
+            std::ostringstream msg;
+            msg << "Node with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          n = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
+          _blue_node_maps[i].second->set(n, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readEdges() {
+
+      std::vector<int> map_index(_edge_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_edge_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of edge map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_edge_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _edge_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::string source_token;
+        std::string target_token;
+
+        if (!_reader_bits::readToken(line, source_token))
+          throw FormatError("Red node not found");
+
+        if (!_reader_bits::readToken(line, target_token))
+          throw FormatError("Blue node not found");
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        Edge e;
+        if (!_use_edges) {
+          typename RedNodeIndex::iterator rit =
+            _red_node_index.find(source_token);
+          if (rit == _red_node_index.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << source_token;
+            throw FormatError(msg.str());
+          }
+          RedNode source = rit->second;
+          typename BlueNodeIndex::iterator it =
+            _blue_node_index.find(target_token);
+          if (it == _blue_node_index.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << target_token;
+            throw FormatError(msg.str());
+          }
+          BlueNode target = it->second;
+
+          // It is checked that source is red and
+          // target is blue, so this should be safe:
+          e = _graph.addEdge(source, target);
+          if (label_index != -1)
+            _edge_index.insert(std::make_pair(tokens[label_index], e));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, Edge>::iterator it =
+            _edge_index.find(tokens[label_index]);
+          if (it == _edge_index.end()) {
+            std::ostringstream msg;
+            msg << "Edge with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          e = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
+          _edge_maps[i].second->set(e, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readAttributes() {
+
+      std::set<std::string> read_attr;
+
+      char c;
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::string attr, token;
+        if (!_reader_bits::readToken(line, attr))
+          throw FormatError("Attribute name not found");
+        if (!_reader_bits::readToken(line, token))
+          throw FormatError("Attribute value not found");
+        if (line >> c)
+          throw FormatError("Extra character at the end of line");
+
+        {
+          std::set<std::string>::iterator it = read_attr.find(attr);
+          if (it != read_attr.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of attribute: " << attr;
+            throw FormatError(msg.str());
+          }
+          read_attr.insert(attr);
+        }
+
+        {
+          typename Attributes::iterator it = _attributes.lower_bound(attr);
+          while (it != _attributes.end() && it->first == attr) {
+            it->second->set(token);
+            ++it;
+          }
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        if (read_attr.find(it->first) == read_attr.end()) {
+          std::ostringstream msg;
+          msg << "Attribute not found: " << it->first;
+          throw FormatError(msg.str());
+        }
+      }
+    }
+
+  public:
+
+    /// \name Execution of the Reader
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing
+    void run() {
+
+      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
+
+      bool red_nodes_done = _skip_nodes;
+      bool blue_nodes_done = _skip_nodes;
+      bool edges_done = _skip_edges;
+      bool attributes_done = false;
+
+      line_num = 0;
+      readLine();
+      skipSection();
+
+      while (readSuccess()) {
+        try {
+          char c;
+          std::string section, caption;
+          line >> c;
+          _reader_bits::readToken(line, section);
+          _reader_bits::readToken(line, caption);
+
+          if (line >> c)
+            throw FormatError("Extra character at the end of line");
+
+          if (section == "red_nodes" && !red_nodes_done) {
+            if (_nodes_caption.empty() || _nodes_caption == caption) {
+              readRedNodes();
+              red_nodes_done = true;
+            }
+          } else if (section == "blue_nodes" && !blue_nodes_done) {
+            if (_nodes_caption.empty() || _nodes_caption == caption) {
+              readBlueNodes();
+              blue_nodes_done = true;
+            }
+          } else if ((section == "edges" || section == "arcs") &&
+                     !edges_done) {
+            if (_edges_caption.empty() || _edges_caption == caption) {
+              readEdges();
+              edges_done = true;
+            }
+          } else if (section == "attributes" && !attributes_done) {
+            if (_attributes_caption.empty() || _attributes_caption == caption) {
+              readAttributes();
+              attributes_done = true;
+            }
+          } else {
+            readLine();
+            skipSection();
+          }
+        } catch (FormatError& error) {
+          error.line(line_num);
+          error.file(_filename);
+          throw;
+        }
+      }
+
+      if (!red_nodes_done) {
+        throw FormatError("Section @red_nodes not found");
+      }
+
+      if (!blue_nodes_done) {
+        throw FormatError("Section @blue_nodes not found");
+      }
+
+      if (!edges_done) {
+        throw FormatError("Section @edges not found");
+      }
+
+      if (!attributes_done && !_attributes.empty()) {
+        throw FormatError("Section @attributes not found");
+      }
+
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref lemon::BpGraphReader "BpGraphReader" class
+  ///
+  /// This function just returns a \ref lemon::BpGraphReader
+  /// "BpGraphReader" class.
+  ///
+  /// With this function a graph can be read from an
+  /// \ref lgf-format "LGF" file or input stream with several maps and
+  /// attributes. For example, there is bipartite weighted matching problem
+  /// on a graph, i.e. a graph with a \e weight map on the edges. This
+  /// graph can be read with the following code:
+  ///
+  ///\code
+  ///ListBpGraph graph;
+  ///ListBpGraph::EdgeMap<int> weight(graph);
+  ///bpGraphReader(graph, std::cin).
+  ///  edgeMap("weight", weight).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the
+  /// \ref lemon::BpGraphReader "BpGraphReader"
+  /// class documentation.
+  /// \warning Don't forget to put the \ref lemon::BpGraphReader::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, const std::string& fn)
+  /// \sa bpGraphReader(TBGR& graph, const char* fn)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) {
+    BpGraphReader<TBGR> tmp(graph, is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphReader class
+  ///
+  /// This function just returns a \ref BpGraphReader class.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, std::istream& is)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) {
+    BpGraphReader<TBGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphReader class
+  ///
+  /// This function just returns a \ref BpGraphReader class.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, std::istream& is)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) {
+    BpGraphReader<TBGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  class SectionReader;
+
+  SectionReader sectionReader(std::istream& is);
+  SectionReader sectionReader(const std::string& fn);
+  SectionReader sectionReader(const char* fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Section reader class
+  ///
+  /// In the \ref lgf-format "LGF" file extra sections can be placed,
+  /// which contain any data in arbitrary format. Such sections can be
+  /// read with this class. A reading rule can be added to the class
+  /// with two different functions. With the \c sectionLines() function a
+  /// functor can process the section line-by-line, while with the \c
+  /// sectionStream() member the section can be read from an input
+  /// stream.
+  class SectionReader {
+  private:
+
+    std::istream* _is;
+    bool local_is;
+    std::string _filename;
+
+    typedef std::map<std::string, _reader_bits::Section*> Sections;
+    Sections _sections;
+
+    int line_num;
+    std::istringstream line;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct a section reader, which reads from the given input
+    /// stream.
+    SectionReader(std::istream& is)
+      : _is(&is), local_is(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a section reader, which reads from the given file.
+    SectionReader(const std::string& fn)
+      : _is(new std::ifstream(fn.c_str())), local_is(true),
+        _filename(fn) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct a section reader, which reads from the given file.
+    SectionReader(const char* fn)
+      : _is(new std::ifstream(fn)), local_is(true),
+        _filename(fn) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~SectionReader() {
+      for (Sections::iterator it = _sections.begin();
+           it != _sections.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_is) {
+        delete _is;
+      }
+
+    }
+
+  private:
+
+    friend SectionReader sectionReader(std::istream& is);
+    friend SectionReader sectionReader(const std::string& fn);
+    friend SectionReader sectionReader(const char* fn);
+
+    SectionReader(SectionReader& other)
+      : _is(other._is), local_is(other.local_is) {
+
+      other._is = 0;
+      other.local_is = false;
+
+      _sections.swap(other._sections);
+    }
+
+    SectionReader& operator=(const SectionReader&);
+
+  public:
+
+    /// \name Section Readers
+    /// @{
+
+    /// \brief Add a section processor with line oriented reading
+    ///
+    /// The first parameter is the type descriptor of the section, the
+    /// second is a functor, which takes just one \c std::string
+    /// parameter. At the reading process, each line of the section
+    /// will be given to the functor object. However, the empty lines
+    /// and the comment lines are filtered out, and the leading
+    /// whitespaces are trimmed from each processed string.
+    ///
+    /// For example, let's see a section, which contain several
+    /// integers, which should be inserted into a vector.
+    ///\code
+    ///  @numbers
+    ///  12 45 23
+    ///  4
+    ///  23 6
+    ///\endcode
+    ///
+    /// The functor is implemented as a struct:
+    ///\code
+    ///  struct NumberSection {
+    ///    std::vector<int>& _data;
+    ///    NumberSection(std::vector<int>& data) : _data(data) {}
+    ///    void operator()(const std::string& line) {
+    ///      std::istringstream ls(line);
+    ///      int value;
+    ///      while (ls >> value) _data.push_back(value);
+    ///    }
+    ///  };
+    ///
+    ///  // ...
+    ///
+    ///  reader.sectionLines("numbers", NumberSection(vec));
+    ///\endcode
+    template <typename Functor>
+    SectionReader& sectionLines(const std::string& type, Functor functor) {
+      LEMON_ASSERT(!type.empty(), "Type is empty.");
+      LEMON_ASSERT(_sections.find(type) == _sections.end(),
+                   "Multiple reading of section.");
+      _sections.insert(std::make_pair(type,
+        new _reader_bits::LineSection<Functor>(functor)));
+      return *this;
+    }
+
+
+    /// \brief Add a section processor with stream oriented reading
+    ///
+    /// The first parameter is the type of the section, the second is
+    /// a functor, which takes an \c std::istream& and an \c int&
+    /// parameter, the latter regard to the line number of stream. The
+    /// functor can read the input while the section go on, and the
+    /// line number should be modified accordingly.
+    template <typename Functor>
+    SectionReader& sectionStream(const std::string& type, Functor functor) {
+      LEMON_ASSERT(!type.empty(), "Type is empty.");
+      LEMON_ASSERT(_sections.find(type) == _sections.end(),
+                   "Multiple reading of section.");
+      _sections.insert(std::make_pair(type,
+         new _reader_bits::StreamSection<Functor>(functor)));
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    bool readLine() {
+      std::string str;
+      while(++line_num, std::getline(*_is, str)) {
+        line.clear(); line.str(str);
+        char c;
+        if (line >> std::ws >> c && c != '#') {
+          line.putback(c);
+          return true;
+        }
+      }
+      return false;
+    }
+
+    bool readSuccess() {
+      return static_cast<bool>(*_is);
+    }
+
+    void skipSection() {
+      char c;
+      while (readSuccess() && line >> c && c != '@') {
+        readLine();
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+  public:
+
+
+    /// \name Execution of the Reader
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing.
+    void run() {
+
+      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
+
+      std::set<std::string> extra_sections;
+
+      line_num = 0;
+      readLine();
+      skipSection();
+
+      while (readSuccess()) {
+        try {
+          char c;
+          std::string section, caption;
+          line >> c;
+          _reader_bits::readToken(line, section);
+          _reader_bits::readToken(line, caption);
+
+          if (line >> c)
+            throw FormatError("Extra character at the end of line");
+
+          if (extra_sections.find(section) != extra_sections.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of section: " << section;
+            throw FormatError(msg.str());
+          }
+          Sections::iterator it = _sections.find(section);
+          if (it != _sections.end()) {
+            extra_sections.insert(section);
+            it->second->process(*_is, line_num);
+          }
+          readLine();
+          skipSection();
+        } catch (FormatError& error) {
+          error.line(line_num);
+          error.file(_filename);
+          throw;
+        }
+      }
+      for (Sections::iterator it = _sections.begin();
+           it != _sections.end(); ++it) {
+        if (extra_sections.find(it->first) == extra_sections.end()) {
+          std::ostringstream os;
+          os << "Cannot find section: " << it->first;
+          throw FormatError(os.str());
+        }
+      }
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref SectionReader class
+  ///
+  /// This function just returns a \ref SectionReader class.
+  ///
+  /// Please see SectionReader documentation about the custom section
+  /// input.
+  ///
+  /// \relates SectionReader
+  /// \sa sectionReader(const std::string& fn)
+  /// \sa sectionReader(const char *fn)
+  inline SectionReader sectionReader(std::istream& is) {
+    SectionReader tmp(is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref SectionReader class
+  ///
+  /// This function just returns a \ref SectionReader class.
+  /// \relates SectionReader
+  /// \sa sectionReader(std::istream& is)
+  inline SectionReader sectionReader(const std::string& fn) {
+    SectionReader tmp(fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref SectionReader class
+  ///
+  /// This function just returns a \ref SectionReader class.
+  /// \relates SectionReader
+  /// \sa sectionReader(std::istream& is)
+  inline SectionReader sectionReader(const char* fn) {
+    SectionReader tmp(fn);
+    return tmp;
+  }
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
+  ///
+  /// This class can be used to read the sections, the map names and
+  /// the attributes from a file. Usually, the LEMON programs know
+  /// that, which type of graph, which maps and which attributes
+  /// should be read from a file, but in general tools (like glemon)
+  /// the contents of an LGF file should be guessed somehow. This class
+  /// reads the graph and stores the appropriate information for
+  /// reading the graph.
+  ///
+  ///\code
+  /// LgfContents contents("graph.lgf");
+  /// contents.run();
+  ///
+  /// // Does it contain any node section and arc section?
+  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
+  ///   std::cerr << "Failure, cannot find graph." << std::endl;
+  ///   return -1;
+  /// }
+  /// std::cout << "The name of the default node section: "
+  ///           << contents.nodeSection(0) << std::endl;
+  /// std::cout << "The number of the arc maps: "
+  ///           << contents.arcMaps(0).size() << std::endl;
+  /// std::cout << "The name of second arc map: "
+  ///           << contents.arcMaps(0)[1] << std::endl;
+  ///\endcode
+  class LgfContents {
+  private:
+
+    std::istream* _is;
+    bool local_is;
+
+    std::vector<std::string> _node_sections;
+    std::vector<std::string> _edge_sections;
+    std::vector<std::string> _attribute_sections;
+    std::vector<std::string> _extra_sections;
+
+    std::vector<bool> _arc_sections;
+
+    std::vector<std::vector<std::string> > _node_maps;
+    std::vector<std::vector<std::string> > _edge_maps;
+
+    std::vector<std::vector<std::string> > _attributes;
+
+
+    int line_num;
+    std::istringstream line;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct an \e LGF contents reader, which reads from the given
+    /// input stream.
+    LgfContents(std::istream& is)
+      : _is(&is), local_is(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct an \e LGF contents reader, which reads from the given
+    /// file.
+    LgfContents(const std::string& fn)
+      : _is(new std::ifstream(fn.c_str())), local_is(true) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct an \e LGF contents reader, which reads from the given
+    /// file.
+    LgfContents(const char* fn)
+      : _is(new std::ifstream(fn)), local_is(true) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~LgfContents() {
+      if (local_is) delete _is;
+    }
+
+  private:
+
+    LgfContents(const LgfContents&);
+    LgfContents& operator=(const LgfContents&);
+
+  public:
+
+
+    /// \name Node Sections
+    /// @{
+
+    /// \brief Gives back the number of node sections in the file.
+    ///
+    /// Gives back the number of node sections in the file.
+    int nodeSectionNum() const {
+      return _node_sections.size();
+    }
+
+    /// \brief Returns the node section name at the given position.
+    ///
+    /// Returns the node section name at the given position.
+    const std::string& nodeSection(int i) const {
+      return _node_sections[i];
+    }
+
+    /// \brief Gives back the node maps for the given section.
+    ///
+    /// Gives back the node maps for the given section.
+    const std::vector<std::string>& nodeMapNames(int i) const {
+      return _node_maps[i];
+    }
+
+    /// @}
+
+    /// \name Arc/Edge Sections
+    /// @{
+
+    /// \brief Gives back the number of arc/edge sections in the file.
+    ///
+    /// Gives back the number of arc/edge sections in the file.
+    /// \note It is synonym of \c edgeSectionNum().
+    int arcSectionNum() const {
+      return _edge_sections.size();
+    }
+
+    /// \brief Returns the arc/edge section name at the given position.
+    ///
+    /// Returns the arc/edge section name at the given position.
+    /// \note It is synonym of \c edgeSection().
+    const std::string& arcSection(int i) const {
+      return _edge_sections[i];
+    }
+
+    /// \brief Gives back the arc/edge maps for the given section.
+    ///
+    /// Gives back the arc/edge maps for the given section.
+    /// \note It is synonym of \c edgeMapNames().
+    const std::vector<std::string>& arcMapNames(int i) const {
+      return _edge_maps[i];
+    }
+
+    /// @}
+
+    /// \name Synonyms
+    /// @{
+
+    /// \brief Gives back the number of arc/edge sections in the file.
+    ///
+    /// Gives back the number of arc/edge sections in the file.
+    /// \note It is synonym of \c arcSectionNum().
+    int edgeSectionNum() const {
+      return _edge_sections.size();
+    }
+
+    /// \brief Returns the section name at the given position.
+    ///
+    /// Returns the section name at the given position.
+    /// \note It is synonym of \c arcSection().
+    const std::string& edgeSection(int i) const {
+      return _edge_sections[i];
+    }
+
+    /// \brief Gives back the edge maps for the given section.
+    ///
+    /// Gives back the edge maps for the given section.
+    /// \note It is synonym of \c arcMapNames().
+    const std::vector<std::string>& edgeMapNames(int i) const {
+      return _edge_maps[i];
+    }
+
+    /// @}
+
+    /// \name Attribute Sections
+    /// @{
+
+    /// \brief Gives back the number of attribute sections in the file.
+    ///
+    /// Gives back the number of attribute sections in the file.
+    int attributeSectionNum() const {
+      return _attribute_sections.size();
+    }
+
+    /// \brief Returns the attribute section name at the given position.
+    ///
+    /// Returns the attribute section name at the given position.
+    const std::string& attributeSectionNames(int i) const {
+      return _attribute_sections[i];
+    }
+
+    /// \brief Gives back the attributes for the given section.
+    ///
+    /// Gives back the attributes for the given section.
+    const std::vector<std::string>& attributes(int i) const {
+      return _attributes[i];
+    }
+
+    /// @}
+
+    /// \name Extra Sections
+    /// @{
+
+    /// \brief Gives back the number of extra sections in the file.
+    ///
+    /// Gives back the number of extra sections in the file.
+    int extraSectionNum() const {
+      return _extra_sections.size();
+    }
+
+    /// \brief Returns the extra section type at the given position.
+    ///
+    /// Returns the section type at the given position.
+    const std::string& extraSection(int i) const {
+      return _extra_sections[i];
+    }
+
+    /// @}
+
+  private:
+
+    bool readLine() {
+      std::string str;
+      while(++line_num, std::getline(*_is, str)) {
+        line.clear(); line.str(str);
+        char c;
+        if (line >> std::ws >> c && c != '#') {
+          line.putback(c);
+          return true;
+        }
+      }
+      return false;
+    }
+
+    bool readSuccess() {
+      return static_cast<bool>(*_is);
+    }
+
+    void skipSection() {
+      char c;
+      while (readSuccess() && line >> c && c != '@') {
+        readLine();
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readMaps(std::vector<std::string>& maps) {
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        return;
+      }
+      line.putback(c);
+      std::string map;
+      while (_reader_bits::readToken(line, map)) {
+        maps.push_back(map);
+      }
+    }
+
+    void readAttributes(std::vector<std::string>& attrs) {
+      readLine();
+      char c;
+      while (readSuccess() && line >> c && c != '@') {
+        line.putback(c);
+        std::string attr;
+        _reader_bits::readToken(line, attr);
+        attrs.push_back(attr);
+        readLine();
+      }
+      line.putback(c);
+    }
+
+  public:
+
+    /// \name Execution of the Contents Reader
+    /// @{
+
+    /// \brief Starts the reading
+    ///
+    /// This function starts the reading.
+    void run() {
+
+      readLine();
+      skipSection();
+
+      while (readSuccess()) {
+
+        char c;
+        line >> c;
+
+        std::string section, caption;
+        _reader_bits::readToken(line, section);
+        _reader_bits::readToken(line, caption);
+
+        if (section == "nodes") {
+          _node_sections.push_back(caption);
+          _node_maps.push_back(std::vector<std::string>());
+          readMaps(_node_maps.back());
+          readLine(); skipSection();
+        } else if (section == "arcs" || section == "edges") {
+          _edge_sections.push_back(caption);
+          _arc_sections.push_back(section == "arcs");
+          _edge_maps.push_back(std::vector<std::string>());
+          readMaps(_edge_maps.back());
+          readLine(); skipSection();
+        } else if (section == "attributes") {
+          _attribute_sections.push_back(caption);
+          _attributes.push_back(std::vector<std::string>());
+          readAttributes(_attributes.back());
+        } else {
+          _extra_sections.push_back(section);
+          readLine(); skipSection();
+        }
+      }
+    }
+
+    /// @}
+
+  };
+}
+
+#endif
diff --git a/lemon/lgf_writer.h b/lemon/lgf_writer.h
new file mode 100644
index 0000000..0695287
--- /dev/null
+++ b/lemon/lgf_writer.h
@@ -0,0 +1,2687 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup lemon_io
+///\file
+///\brief \ref lgf-format "LEMON Graph Format" writer.
+
+
+#ifndef LEMON_LGF_WRITER_H
+#define LEMON_LGF_WRITER_H
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <algorithm>
+
+#include <vector>
+#include <functional>
+
+#include <lemon/core.h>
+#include <lemon/maps.h>
+
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
+
+namespace lemon {
+
+  namespace _writer_bits {
+
+    template <typename Value>
+    struct DefaultConverter {
+      std::string operator()(const Value& value) {
+        std::ostringstream os;
+        os << value;
+        return os.str();
+      }
+    };
+
+    template <typename T>
+    bool operator<(const T&, const T&) {
+      throw FormatError("Label map is not comparable");
+    }
+
+    template <typename _Map>
+    class MapLess {
+    public:
+      typedef _Map Map;
+      typedef typename Map::Key Item;
+
+    private:
+      const Map& _map;
+
+    public:
+      MapLess(const Map& map) : _map(map) {}
+
+      bool operator()(const Item& left, const Item& right) {
+        return _map[left] < _map[right];
+      }
+    };
+
+    template <typename _Graph, bool _dir, typename _Map>
+    class GraphArcMapLess {
+    public:
+      typedef _Map Map;
+      typedef _Graph Graph;
+      typedef typename Graph::Edge Item;
+
+    private:
+      const Graph& _graph;
+      const Map& _map;
+
+    public:
+      GraphArcMapLess(const Graph& graph, const Map& map)
+        : _graph(graph), _map(map) {}
+
+      bool operator()(const Item& left, const Item& right) {
+        return _map[_graph.direct(left, _dir)] <
+          _map[_graph.direct(right, _dir)];
+      }
+    };
+
+    template <typename _Item>
+    class MapStorageBase {
+    public:
+      typedef _Item Item;
+
+    public:
+      MapStorageBase() {}
+      virtual ~MapStorageBase() {}
+
+      virtual std::string get(const Item& item) = 0;
+      virtual void sort(std::vector<Item>&) = 0;
+    };
+
+    template <typename _Item, typename _Map,
+              typename _Converter = DefaultConverter<typename _Map::Value> >
+    class MapStorage : public MapStorageBase<_Item> {
+    public:
+      typedef _Map Map;
+      typedef _Converter Converter;
+      typedef _Item Item;
+
+    private:
+      const Map& _map;
+      Converter _converter;
+
+    public:
+      MapStorage(const Map& map, const Converter& converter = Converter())
+        : _map(map), _converter(converter) {}
+      virtual ~MapStorage() {}
+
+      virtual std::string get(const Item& item) {
+        return _converter(_map[item]);
+      }
+      virtual void sort(std::vector<Item>& items) {
+        MapLess<Map> less(_map);
+        std::sort(items.begin(), items.end(), less);
+      }
+    };
+
+    template <typename _Graph, bool _dir, typename _Map,
+              typename _Converter = DefaultConverter<typename _Map::Value> >
+    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
+    public:
+      typedef _Map Map;
+      typedef _Converter Converter;
+      typedef _Graph Graph;
+      typedef typename Graph::Edge Item;
+      static const bool dir = _dir;
+
+    private:
+      const Graph& _graph;
+      const Map& _map;
+      Converter _converter;
+
+    public:
+      GraphArcMapStorage(const Graph& graph, const Map& map,
+                         const Converter& converter = Converter())
+        : _graph(graph), _map(map), _converter(converter) {}
+      virtual ~GraphArcMapStorage() {}
+
+      virtual std::string get(const Item& item) {
+        return _converter(_map[_graph.direct(item, dir)]);
+      }
+      virtual void sort(std::vector<Item>& items) {
+        GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
+        std::sort(items.begin(), items.end(), less);
+      }
+    };
+
+    class ValueStorageBase {
+    public:
+      ValueStorageBase() {}
+      virtual ~ValueStorageBase() {}
+
+      virtual std::string get() = 0;
+    };
+
+    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
+    class ValueStorage : public ValueStorageBase {
+    public:
+      typedef _Value Value;
+      typedef _Converter Converter;
+
+    private:
+      const Value& _value;
+      Converter _converter;
+
+    public:
+      ValueStorage(const Value& value, const Converter& converter = Converter())
+        : _value(value), _converter(converter) {}
+
+      virtual std::string get() {
+        return _converter(_value);
+      }
+    };
+
+    template <typename Value,
+              typename Map = std::map<Value, std::string> >
+    struct MapLookUpConverter {
+      const Map& _map;
+
+      MapLookUpConverter(const Map& map)
+        : _map(map) {}
+
+      std::string operator()(const Value& value) {
+        typename Map::const_iterator it = _map.find(value);
+        if (it == _map.end()) {
+          throw FormatError("Item not found");
+        }
+        return it->second;
+      }
+    };
+
+    template <typename Value,
+              typename Map1 = std::map<Value, std::string>,
+              typename Map2 = std::map<Value, std::string> >
+    struct DoubleMapLookUpConverter {
+      const Map1& _map1;
+      const Map2& _map2;
+
+      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
+        : _map1(map1), _map2(map2) {}
+
+      std::string operator()(const Value& value) {
+        typename Map1::const_iterator it1 = _map1.find(value);
+        typename Map1::const_iterator it2 = _map2.find(value);
+        if (it1 == _map1.end()) {
+          if (it2 == _map2.end()) {
+            throw FormatError("Item not found");
+          } else {
+            return it2->second;
+          }
+        } else {
+          if (it2 == _map2.end()) {
+            return it1->second;
+          } else {
+            throw FormatError("Item is ambigous");
+          }
+        }
+      }
+    };
+
+    template <typename Graph>
+    struct GraphArcLookUpConverter {
+      const Graph& _graph;
+      const std::map<typename Graph::Edge, std::string>& _map;
+
+      GraphArcLookUpConverter(const Graph& graph,
+                              const std::map<typename Graph::Edge,
+                                             std::string>& map)
+        : _graph(graph), _map(map) {}
+
+      std::string operator()(const typename Graph::Arc& val) {
+        typename std::map<typename Graph::Edge, std::string>
+          ::const_iterator it = _map.find(val);
+        if (it == _map.end()) {
+          throw FormatError("Item not found");
+        }
+        return (_graph.direction(val) ? '+' : '-') + it->second;
+      }
+    };
+
+    inline bool isWhiteSpace(char c) {
+      return c == ' ' || c == '\t' || c == '\v' ||
+        c == '\n' || c == '\r' || c == '\f';
+    }
+
+    inline bool isEscaped(char c) {
+      return c == '\\' || c == '\"' || c == '\'' ||
+        c == '\a' || c == '\b';
+    }
+
+    inline static void writeEscape(std::ostream& os, char c) {
+      switch (c) {
+      case '\\':
+        os << "\\\\";
+        return;
+      case '\"':
+        os << "\\\"";
+        return;
+      case '\a':
+        os << "\\a";
+        return;
+      case '\b':
+        os << "\\b";
+        return;
+      case '\f':
+        os << "\\f";
+        return;
+      case '\r':
+        os << "\\r";
+        return;
+      case '\n':
+        os << "\\n";
+        return;
+      case '\t':
+        os << "\\t";
+        return;
+      case '\v':
+        os << "\\v";
+        return;
+      default:
+        if (c < 0x20) {
+          std::ios::fmtflags flags = os.flags();
+          os << '\\' << std::oct << static_cast<int>(c);
+          os.flags(flags);
+        } else {
+          os << c;
+        }
+        return;
+      }
+    }
+
+    inline bool requireEscape(const std::string& str) {
+      if (str.empty() || str[0] == '@') return true;
+      std::istringstream is(str);
+      char c;
+      while (is.get(c)) {
+        if (isWhiteSpace(c) || isEscaped(c)) {
+          return true;
+        }
+      }
+      return false;
+    }
+
+    inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
+
+      if (requireEscape(str)) {
+        os << '\"';
+        for (std::string::const_iterator it = str.begin();
+             it != str.end(); ++it) {
+          writeEscape(os, *it);
+        }
+        os << '\"';
+      } else {
+        os << str;
+      }
+      return os;
+    }
+
+    class Section {
+    public:
+      virtual ~Section() {}
+      virtual void process(std::ostream& os) = 0;
+    };
+
+    template <typename Functor>
+    class LineSection : public Section {
+    private:
+
+      Functor _functor;
+
+    public:
+
+      LineSection(const Functor& functor) : _functor(functor) {}
+      virtual ~LineSection() {}
+
+      virtual void process(std::ostream& os) {
+        std::string line;
+        while (!(line = _functor()).empty()) os << line << std::endl;
+      }
+    };
+
+    template <typename Functor>
+    class StreamSection : public Section {
+    private:
+
+      Functor _functor;
+
+    public:
+
+      StreamSection(const Functor& functor) : _functor(functor) {}
+      virtual ~StreamSection() {}
+
+      virtual void process(std::ostream& os) {
+        _functor(os);
+      }
+    };
+
+  }
+
+  template <typename DGR>
+  class DigraphWriter;
+
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                   std::ostream& os = std::cout);
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
+
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn);
+
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" writer for directed graphs
+  ///
+  /// This utility writes an \ref lgf-format "LGF" file.
+  ///
+  /// The writing method does a batch processing. The user creates a
+  /// writer object, then various writing rules can be added to the
+  /// writer, and eventually the writing is executed with the \c run()
+  /// member function. A map writing rule can be added to the writer
+  /// with the \c nodeMap() or \c arcMap() members. An optional
+  /// converter parameter can also be added as a standard functor
+  /// converting from the value type of the map to \c std::string. If it
+  /// is set, it will determine how the value type of the map is written to
+  /// the output stream. If the functor is not set, then a default
+  /// conversion will be used. The \c attribute(), \c node() and \c
+  /// arc() functions are used to add attribute writing rules.
+  ///
+  ///\code
+  /// DigraphWriter<DGR>(digraph, std::cout).
+  ///   nodeMap("coordinates", coord_map).
+  ///   nodeMap("size", size).
+  ///   nodeMap("title", title).
+  ///   arcMap("capacity", cap_map).
+  ///   node("source", src).
+  ///   node("target", trg).
+  ///   attribute("caption", caption).
+  ///   run();
+  ///\endcode
+  ///
+  ///
+  /// By default, the writer does not write additional captions to the
+  /// sections, but they can be give as an optional parameter of
+  /// the \c nodes(), \c arcs() or \c
+  /// attributes() functions.
+  ///
+  /// The \c skipNodes() and \c skipArcs() functions forbid the
+  /// writing of the sections. If two arc sections should be written
+  /// to the output, it can be done in two passes, the first pass
+  /// writes the node section and the first arc section, then the
+  /// second pass skips the node section and writes just the arc
+  /// section to the stream. The output stream can be retrieved with
+  /// the \c ostream() function, hence the second pass can append its
+  /// output to the output of the first pass.
+  template <typename DGR>
+  class DigraphWriter {
+  public:
+
+    typedef DGR Digraph;
+    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
+
+  private:
+
+
+    std::ostream* _os;
+    bool local_os;
+
+    const DGR& _digraph;
+
+    std::string _nodes_caption;
+    std::string _arcs_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<Node, std::string> NodeIndex;
+    NodeIndex _node_index;
+    typedef std::map<Arc, std::string> ArcIndex;
+    ArcIndex _arc_index;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
+    NodeMaps _node_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
+    ArcMaps _arc_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::ValueStorageBase*> > Attributes;
+    Attributes _attributes;
+
+    bool _skip_nodes;
+    bool _skip_arcs;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct a directed graph writer, which writes to the given
+    /// output stream.
+    DigraphWriter(const DGR& digraph, std::ostream& os = std::cout)
+      : _os(&os), local_os(false), _digraph(digraph),
+        _skip_nodes(false), _skip_arcs(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a directed graph writer, which writes to the given
+    /// output file.
+    DigraphWriter(const DGR& digraph, const std::string& fn)
+      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
+        _skip_nodes(false), _skip_arcs(false) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct a directed graph writer, which writes to the given
+    /// output file.
+    DigraphWriter(const DGR& digraph, const char* fn)
+      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
+        _skip_nodes(false), _skip_arcs(false) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~DigraphWriter() {
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename ArcMaps::iterator it = _arc_maps.begin();
+           it != _arc_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_os) {
+        delete _os;
+      }
+    }
+
+  private:
+
+    template <typename TDGR>
+    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                             std::ostream& os);
+    template <typename TDGR>
+    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                             const std::string& fn);
+    template <typename TDGR>
+    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                             const char *fn);
+
+    DigraphWriter(DigraphWriter& other)
+      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
+        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
+
+      other._os = 0;
+      other.local_os = false;
+
+      _node_index.swap(other._node_index);
+      _arc_index.swap(other._arc_index);
+
+      _node_maps.swap(other._node_maps);
+      _arc_maps.swap(other._arc_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _arcs_caption = other._arcs_caption;
+      _attributes_caption = other._attributes_caption;
+    }
+
+    DigraphWriter& operator=(const DigraphWriter&);
+
+  public:
+
+    /// \name Writing Rules
+    /// @{
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule to the writer.
+    template <typename Map>
+    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Node>* storage =
+        new _writer_bits::MapStorage<Node, Map>(map);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Node>* storage =
+        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule to the writer.
+    template <typename Map>
+    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Arc>* storage =
+        new _writer_bits::MapStorage<Arc, Map>(map);
+      _arc_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    DigraphWriter& arcMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Arc>* storage =
+        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
+      _arc_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute writing rule
+    ///
+    /// Add an attribute writing rule to the writer.
+    template <typename Value>
+    DigraphWriter& attribute(const std::string& caption, const Value& value) {
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Value>(value);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute writing rule
+    ///
+    /// Add an attribute writing rule with specialized converter to the
+    /// writer.
+    template <typename Value, typename Converter>
+    DigraphWriter& attribute(const std::string& caption, const Value& value,
+                             const Converter& converter = Converter()) {
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node writing rule
+    ///
+    /// Add a node writing rule to the writer.
+    DigraphWriter& node(const std::string& caption, const Node& node) {
+      typedef _writer_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc writing rule
+    ///
+    /// Add an arc writing rule to writer.
+    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
+      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
+      Converter converter(_arc_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \name Section Captions
+    /// @{
+
+    /// \brief Add an additional caption to the \c \@nodes section
+    ///
+    /// Add an additional caption to the \c \@nodes section.
+    DigraphWriter& nodes(const std::string& caption) {
+      _nodes_caption = caption;
+      return *this;
+    }
+
+    /// \brief Add an additional caption to the \c \@arcs section
+    ///
+    /// Add an additional caption to the \c \@arcs section.
+    DigraphWriter& arcs(const std::string& caption) {
+      _arcs_caption = caption;
+      return *this;
+    }
+
+    /// \brief Add an additional caption to the \c \@attributes section
+    ///
+    /// Add an additional caption to the \c \@attributes section.
+    DigraphWriter& attributes(const std::string& caption) {
+      _attributes_caption = caption;
+      return *this;
+    }
+
+    /// \name Skipping Section
+    /// @{
+
+    /// \brief Skip writing the node set
+    ///
+    /// The \c \@nodes section will not be written to the stream.
+    DigraphWriter& skipNodes() {
+      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
+      _skip_nodes = true;
+      return *this;
+    }
+
+    /// \brief Skip writing arc set
+    ///
+    /// The \c \@arcs section will not be written to the stream.
+    DigraphWriter& skipArcs() {
+      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
+      _skip_arcs = true;
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    void writeNodes() {
+      _writer_bits::MapStorageBase<Node>* label = 0;
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@nodes";
+      if (!_nodes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
+      }
+      *_os << std::endl;
+
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<Node> nodes;
+      for (NodeIt n(_digraph); n != INVALID; ++n) {
+        nodes.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<DGR, Node> id_map(_digraph);
+        _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
+        std::sort(nodes.begin(), nodes.end(), id_less);
+      } else {
+        label->sort(nodes);
+      }
+
+      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
+        Node n = nodes[i];
+        if (label == 0) {
+          std::ostringstream os;
+          os << _digraph.id(n);
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _node_index.insert(std::make_pair(n, os.str()));
+        }
+        for (typename NodeMaps::iterator it = _node_maps.begin();
+             it != _node_maps.end(); ++it) {
+          std::string value = it->second->get(n);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _node_index.insert(std::make_pair(n, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void createNodeIndex() {
+      _writer_bits::MapStorageBase<Node>* label = 0;
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (NodeIt n(_digraph); n != INVALID; ++n) {
+          std::ostringstream os;
+          os << _digraph.id(n);
+          _node_index.insert(std::make_pair(n, os.str()));
+        }
+      } else {
+        for (NodeIt n(_digraph); n != INVALID; ++n) {
+          std::string value = label->get(n);
+          _node_index.insert(std::make_pair(n, value));
+        }
+      }
+    }
+
+    void writeArcs() {
+      _writer_bits::MapStorageBase<Arc>* label = 0;
+      for (typename ArcMaps::iterator it = _arc_maps.begin();
+           it != _arc_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@arcs";
+      if (!_arcs_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _arcs_caption);
+      }
+      *_os << std::endl;
+
+      *_os << '\t' << '\t';
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename ArcMaps::iterator it = _arc_maps.begin();
+           it != _arc_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<Arc> arcs;
+      for (ArcIt n(_digraph); n != INVALID; ++n) {
+        arcs.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<DGR, Arc> id_map(_digraph);
+        _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
+        std::sort(arcs.begin(), arcs.end(), id_less);
+      } else {
+        label->sort(arcs);
+      }
+
+      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
+        Arc a = arcs[i];
+        _writer_bits::writeToken(*_os, _node_index.
+                                 find(_digraph.source(a))->second);
+        *_os << '\t';
+        _writer_bits::writeToken(*_os, _node_index.
+                                 find(_digraph.target(a))->second);
+        *_os << '\t';
+        if (label == 0) {
+          std::ostringstream os;
+          os << _digraph.id(a);
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _arc_index.insert(std::make_pair(a, os.str()));
+        }
+        for (typename ArcMaps::iterator it = _arc_maps.begin();
+             it != _arc_maps.end(); ++it) {
+          std::string value = it->second->get(a);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _arc_index.insert(std::make_pair(a, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void createArcIndex() {
+      _writer_bits::MapStorageBase<Arc>* label = 0;
+      for (typename ArcMaps::iterator it = _arc_maps.begin();
+           it != _arc_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (ArcIt a(_digraph); a != INVALID; ++a) {
+          std::ostringstream os;
+          os << _digraph.id(a);
+          _arc_index.insert(std::make_pair(a, os.str()));
+        }
+      } else {
+        for (ArcIt a(_digraph); a != INVALID; ++a) {
+          std::string value = label->get(a);
+          _arc_index.insert(std::make_pair(a, value));
+        }
+      }
+    }
+
+    void writeAttributes() {
+      if (_attributes.empty()) return;
+      *_os << "@attributes";
+      if (!_attributes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
+      }
+      *_os << std::endl;
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << ' ';
+        _writer_bits::writeToken(*_os, it->second->get());
+        *_os << std::endl;
+      }
+    }
+
+  public:
+
+    /// \name Execution of the Writer
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing.
+    void run() {
+      if (!_skip_nodes) {
+        writeNodes();
+      } else {
+        createNodeIndex();
+      }
+      if (!_skip_arcs) {
+        writeArcs();
+      } else {
+        createArcIndex();
+      }
+      writeAttributes();
+    }
+
+    /// \brief Give back the stream of the writer
+    ///
+    /// Give back the stream of the writer.
+    std::ostream& ostream() {
+      return *_os;
+    }
+
+    /// @}
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref lemon::DigraphWriter "DigraphWriter" class
+  ///
+  /// This function just returns a \ref lemon::DigraphWriter
+  /// "DigraphWriter" class.
+  ///
+  /// With this function a digraph can be write to a file or output
+  /// stream in \ref lgf-format "LGF" format with several maps and
+  /// attributes. For example, with the following code a network flow
+  /// problem can be written to the standard output, i.e. a digraph
+  /// with a \e capacity map on the arcs and \e source and \e target
+  /// nodes:
+  ///
+  ///\code
+  ///ListDigraph digraph;
+  ///ListDigraph::ArcMap<int> cap(digraph);
+  ///ListDigraph::Node src, trg;
+  ///  // Setting the capacity map and source and target nodes
+  ///digraphWriter(digraph, std::cout).
+  ///  arcMap("capacity", cap).
+  ///  node("source", src).
+  ///  node("target", trg).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the
+  /// \ref lemon::DigraphWriter "DigraphWriter"
+  /// class documentation.
+  /// \warning Don't forget to put the \ref lemon::DigraphWriter::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates DigraphWriter
+  /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
+  /// \sa digraphWriter(const TDGR& digraph, const char* fn)
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, std::ostream& os) {
+    DigraphWriter<TDGR> tmp(digraph, os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  /// \relates DigraphWriter
+  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                    const std::string& fn) {
+    DigraphWriter<TDGR> tmp(digraph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  /// \relates DigraphWriter
+  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn) {
+    DigraphWriter<TDGR> tmp(digraph, fn);
+    return tmp;
+  }
+
+  template <typename GR>
+  class GraphWriter;
+
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os = std::cout);
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn);
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" writer for undirected graphs
+  ///
+  /// This utility writes an \ref lgf-format "LGF" file.
+  ///
+  /// It can be used almost the same way as \c DigraphWriter.
+  /// The only difference is that this class can handle edges and
+  /// edge maps as well as arcs and arc maps.
+  ///
+  /// The arc maps are written into the file as two columns, the
+  /// caption of the columns are the name of the map prefixed with \c
+  /// '+' and \c '-'. The arcs are written into the \c \@attributes
+  /// section as a \c '+' or a \c '-' prefix (depends on the direction
+  /// of the arc) and the label of corresponding edge.
+  template <typename GR>
+  class GraphWriter {
+  public:
+
+    typedef GR Graph;
+    TEMPLATE_GRAPH_TYPEDEFS(GR);
+
+  private:
+
+
+    std::ostream* _os;
+    bool local_os;
+
+    const GR& _graph;
+
+    std::string _nodes_caption;
+    std::string _edges_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<Node, std::string> NodeIndex;
+    NodeIndex _node_index;
+    typedef std::map<Edge, std::string> EdgeIndex;
+    EdgeIndex _edge_index;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
+    NodeMaps _node_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
+    EdgeMaps _edge_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::ValueStorageBase*> > Attributes;
+    Attributes _attributes;
+
+    bool _skip_nodes;
+    bool _skip_edges;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph writer, which writes to the
+    /// given output stream.
+    GraphWriter(const GR& graph, std::ostream& os = std::cout)
+      : _os(&os), local_os(false), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a undirected graph writer, which writes to the given
+    /// output file.
+    GraphWriter(const GR& graph, const std::string& fn)
+      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct a undirected graph writer, which writes to the given
+    /// output file.
+    GraphWriter(const GR& graph, const char* fn)
+      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~GraphWriter() {
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_os) {
+        delete _os;
+      }
+    }
+
+  private:
+
+    template <typename TGR>
+    friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
+    template <typename TGR>
+    friend GraphWriter<TGR> graphWriter(const TGR& graph,
+                                        const std::string& fn);
+    template <typename TGR>
+    friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
+
+    GraphWriter(GraphWriter& other)
+      : _os(other._os), local_os(other.local_os), _graph(other._graph),
+        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
+
+      other._os = 0;
+      other.local_os = false;
+
+      _node_index.swap(other._node_index);
+      _edge_index.swap(other._edge_index);
+
+      _node_maps.swap(other._node_maps);
+      _edge_maps.swap(other._edge_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _edges_caption = other._edges_caption;
+      _attributes_caption = other._attributes_caption;
+    }
+
+    GraphWriter& operator=(const GraphWriter&);
+
+  public:
+
+    /// \name Writing Rules
+    /// @{
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule to the writer.
+    template <typename Map>
+    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Node>* storage =
+        new _writer_bits::MapStorage<Node, Map>(map);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    GraphWriter& nodeMap(const std::string& caption, const Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Node>* storage =
+        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map writing rule
+    ///
+    /// Add an edge map writing rule to the writer.
+    template <typename Map>
+    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* storage =
+        new _writer_bits::MapStorage<Edge, Map>(map);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map writing rule
+    ///
+    /// Add an edge map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    GraphWriter& edgeMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* storage =
+        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule to the writer.
+    template <typename Map>
+    GraphWriter& arcMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* forward_storage =
+        new _writer_bits::GraphArcMapStorage<GR, true, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _writer_bits::MapStorageBase<Edge>* backward_storage =
+        new _writer_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    GraphWriter& arcMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* forward_storage =
+        new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _writer_bits::MapStorageBase<Edge>* backward_storage =
+        new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Attribute writing rule
+    ///
+    /// Add an attribute writing rule to the writer.
+    template <typename Value>
+    GraphWriter& attribute(const std::string& caption, const Value& value) {
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Value>(value);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute writing rule
+    ///
+    /// Add an attribute writing rule with specialized converter to the
+    /// writer.
+    template <typename Value, typename Converter>
+    GraphWriter& attribute(const std::string& caption, const Value& value,
+                             const Converter& converter = Converter()) {
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node writing rule
+    ///
+    /// Add a node writing rule to the writer.
+    GraphWriter& node(const std::string& caption, const Node& node) {
+      typedef _writer_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge writing rule
+    ///
+    /// Add an edge writing rule to writer.
+    GraphWriter& edge(const std::string& caption, const Edge& edge) {
+      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
+      Converter converter(_edge_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc writing rule
+    ///
+    /// Add an arc writing rule to writer.
+    GraphWriter& arc(const std::string& caption, const Arc& arc) {
+      typedef _writer_bits::GraphArcLookUpConverter<GR> Converter;
+      Converter converter(_graph, _edge_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \name Section Captions
+    /// @{
+
+    /// \brief Add an additional caption to the \c \@nodes section
+    ///
+    /// Add an additional caption to the \c \@nodes section.
+    GraphWriter& nodes(const std::string& caption) {
+      _nodes_caption = caption;
+      return *this;
+    }
+
+    /// \brief Add an additional caption to the \c \@edges section
+    ///
+    /// Add an additional caption to the \c \@edges section.
+    GraphWriter& edges(const std::string& caption) {
+      _edges_caption = caption;
+      return *this;
+    }
+
+    /// \brief Add an additional caption to the \c \@attributes section
+    ///
+    /// Add an additional caption to the \c \@attributes section.
+    GraphWriter& attributes(const std::string& caption) {
+      _attributes_caption = caption;
+      return *this;
+    }
+
+    /// \name Skipping Section
+    /// @{
+
+    /// \brief Skip writing the node set
+    ///
+    /// The \c \@nodes section will not be written to the stream.
+    GraphWriter& skipNodes() {
+      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
+      _skip_nodes = true;
+      return *this;
+    }
+
+    /// \brief Skip writing edge set
+    ///
+    /// The \c \@edges section will not be written to the stream.
+    GraphWriter& skipEdges() {
+      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
+      _skip_edges = true;
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    void writeNodes() {
+      _writer_bits::MapStorageBase<Node>* label = 0;
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@nodes";
+      if (!_nodes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
+      }
+      *_os << std::endl;
+
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<Node> nodes;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        nodes.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<GR, Node> id_map(_graph);
+        _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
+        std::sort(nodes.begin(), nodes.end(), id_less);
+      } else {
+        label->sort(nodes);
+      }
+
+      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
+        Node n = nodes[i];
+        if (label == 0) {
+          std::ostringstream os;
+          os << _graph.id(n);
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _node_index.insert(std::make_pair(n, os.str()));
+        }
+        for (typename NodeMaps::iterator it = _node_maps.begin();
+             it != _node_maps.end(); ++it) {
+          std::string value = it->second->get(n);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _node_index.insert(std::make_pair(n, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void createNodeIndex() {
+      _writer_bits::MapStorageBase<Node>* label = 0;
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+           it != _node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          std::ostringstream os;
+          os << _graph.id(n);
+          _node_index.insert(std::make_pair(n, os.str()));
+        }
+      } else {
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          std::string value = label->get(n);
+          _node_index.insert(std::make_pair(n, value));
+        }
+      }
+    }
+
+    void writeEdges() {
+      _writer_bits::MapStorageBase<Edge>* label = 0;
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@edges";
+      if (!_edges_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _edges_caption);
+      }
+      *_os << std::endl;
+
+      *_os << '\t' << '\t';
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<Edge> edges;
+      for (EdgeIt n(_graph); n != INVALID; ++n) {
+        edges.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<GR, Edge> id_map(_graph);
+        _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
+        std::sort(edges.begin(), edges.end(), id_less);
+      } else {
+        label->sort(edges);
+      }
+
+      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
+        Edge e = edges[i];
+        _writer_bits::writeToken(*_os, _node_index.
+                                 find(_graph.u(e))->second);
+        *_os << '\t';
+        _writer_bits::writeToken(*_os, _node_index.
+                                 find(_graph.v(e))->second);
+        *_os << '\t';
+        if (label == 0) {
+          std::ostringstream os;
+          os << _graph.id(e);
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _edge_index.insert(std::make_pair(e, os.str()));
+        }
+        for (typename EdgeMaps::iterator it = _edge_maps.begin();
+             it != _edge_maps.end(); ++it) {
+          std::string value = it->second->get(e);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _edge_index.insert(std::make_pair(e, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void createEdgeIndex() {
+      _writer_bits::MapStorageBase<Edge>* label = 0;
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          std::ostringstream os;
+          os << _graph.id(e);
+          _edge_index.insert(std::make_pair(e, os.str()));
+        }
+      } else {
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          std::string value = label->get(e);
+          _edge_index.insert(std::make_pair(e, value));
+        }
+      }
+    }
+
+    void writeAttributes() {
+      if (_attributes.empty()) return;
+      *_os << "@attributes";
+      if (!_attributes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
+      }
+      *_os << std::endl;
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << ' ';
+        _writer_bits::writeToken(*_os, it->second->get());
+        *_os << std::endl;
+      }
+    }
+
+  public:
+
+    /// \name Execution of the Writer
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing.
+    void run() {
+      if (!_skip_nodes) {
+        writeNodes();
+      } else {
+        createNodeIndex();
+      }
+      if (!_skip_edges) {
+        writeEdges();
+      } else {
+        createEdgeIndex();
+      }
+      writeAttributes();
+    }
+
+    /// \brief Give back the stream of the writer
+    ///
+    /// Give back the stream of the writer
+    std::ostream& ostream() {
+      return *_os;
+    }
+
+    /// @}
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref lemon::GraphWriter "GraphWriter" class
+  ///
+  /// This function just returns a \ref lemon::GraphWriter "GraphWriter" class.
+  ///
+  /// With this function a graph can be write to a file or output
+  /// stream in \ref lgf-format "LGF" format with several maps and
+  /// attributes. For example, with the following code a weighted
+  /// matching problem can be written to the standard output, i.e. a
+  /// graph with a \e weight map on the edges:
+  ///
+  ///\code
+  ///ListGraph graph;
+  ///ListGraph::EdgeMap<int> weight(graph);
+  ///  // Setting the weight map
+  ///graphWriter(graph, std::cout).
+  ///  edgeMap("weight", weight).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the
+  /// \ref lemon::GraphWriter "GraphWriter"
+  /// class documentation.
+  /// \warning Don't forget to put the \ref lemon::GraphWriter::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates GraphWriter
+  /// \sa graphWriter(const TGR& graph, const std::string& fn)
+  /// \sa graphWriter(const TGR& graph, const char* fn)
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os) {
+    GraphWriter<TGR> tmp(graph, os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  /// \relates GraphWriter
+  /// \sa graphWriter(const TGR& graph, std::ostream& os)
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn) {
+    GraphWriter<TGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  /// \relates GraphWriter
+  /// \sa graphWriter(const TGR& graph, std::ostream& os)
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
+    GraphWriter<TGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  template <typename BGR>
+  class BpGraphWriter;
+
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
+                                    std::ostream& os = std::cout);
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn);
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" writer for undirected bipartite graphs
+  ///
+  /// This utility writes an \ref lgf-format "LGF" file.
+  ///
+  /// It can be used almost the same way as \c GraphWriter, but it
+  /// reads the red and blue nodes from separate sections, and these
+  /// sections can contain different set of maps.
+  ///
+  /// The red and blue node maps are written to the corresponding
+  /// sections. The node maps are written to both of these sections
+  /// with the same map name.
+  template <typename BGR>
+  class BpGraphWriter {
+  public:
+
+    typedef BGR BpGraph;
+    TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
+
+  private:
+
+
+    std::ostream* _os;
+    bool local_os;
+
+    const BGR& _graph;
+
+    std::string _nodes_caption;
+    std::string _edges_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<Node, std::string> RedNodeIndex;
+    RedNodeIndex _red_node_index;
+    typedef std::map<Node, std::string> BlueNodeIndex;
+    BlueNodeIndex _blue_node_index;
+    typedef std::map<Edge, std::string> EdgeIndex;
+    EdgeIndex _edge_index;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<RedNode>* > > RedNodeMaps;
+    RedNodeMaps _red_node_maps;
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<BlueNode>* > > BlueNodeMaps;
+    BlueNodeMaps _blue_node_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
+    EdgeMaps _edge_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::ValueStorageBase*> > Attributes;
+    Attributes _attributes;
+
+    bool _skip_nodes;
+    bool _skip_edges;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct a bipartite graph writer, which writes to the given
+    /// output stream.
+    BpGraphWriter(const BGR& graph, std::ostream& os = std::cout)
+      : _os(&os), local_os(false), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a bipartite graph writer, which writes to the given
+    /// output file.
+    BpGraphWriter(const BGR& graph, const std::string& fn)
+      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct a bipartite graph writer, which writes to the given
+    /// output file.
+    BpGraphWriter(const BGR& graph, const char* fn)
+      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~BpGraphWriter() {
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_os) {
+        delete _os;
+      }
+    }
+
+  private:
+
+    template <typename TBGR>
+    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
+                                             std::ostream& os);
+    template <typename TBGR>
+    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
+                                             const std::string& fn);
+    template <typename TBGR>
+    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char *fn);
+
+    BpGraphWriter(BpGraphWriter& other)
+      : _os(other._os), local_os(other.local_os), _graph(other._graph),
+        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
+
+      other._os = 0;
+      other.local_os = false;
+
+      _red_node_index.swap(other._red_node_index);
+      _blue_node_index.swap(other._blue_node_index);
+      _edge_index.swap(other._edge_index);
+
+      _red_node_maps.swap(other._red_node_maps);
+      _blue_node_maps.swap(other._blue_node_maps);
+      _edge_maps.swap(other._edge_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _edges_caption = other._edges_caption;
+      _attributes_caption = other._attributes_caption;
+    }
+
+    BpGraphWriter& operator=(const BpGraphWriter&);
+
+  public:
+
+    /// \name Writing Rules
+    /// @{
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& nodeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* red_storage =
+        new _writer_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _writer_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& nodeMap(const std::string& caption, const Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* red_storage =
+        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// \brief Red node map writing rule
+    ///
+    /// Add a red node map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* storage =
+        new _writer_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node map writing rule
+    ///
+    /// Add a red node map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& redNodeMap(const std::string& caption, const Map& map,
+                              const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* storage =
+        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node map writing rule
+    ///
+    /// Add a blue node map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<BlueNode>* storage =
+        new _writer_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node map writing rule
+    ///
+    /// Add a blue node map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map,
+                               const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<BlueNode>* storage =
+        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map writing rule
+    ///
+    /// Add an edge map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& edgeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* storage =
+        new _writer_bits::MapStorage<Edge, Map>(map);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map writing rule
+    ///
+    /// Add an edge map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& edgeMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* storage =
+        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& arcMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* forward_storage =
+        new _writer_bits::GraphArcMapStorage<BGR, true, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _writer_bits::MapStorageBase<Edge>* backward_storage =
+        new _writer_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& arcMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* forward_storage =
+        new _writer_bits::GraphArcMapStorage<BGR, true, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _writer_bits::MapStorageBase<Edge>* backward_storage =
+        new _writer_bits::GraphArcMapStorage<BGR, false, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Attribute writing rule
+    ///
+    /// Add an attribute writing rule to the writer.
+    template <typename Value>
+    BpGraphWriter& attribute(const std::string& caption, const Value& value) {
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Value>(value);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute writing rule
+    ///
+    /// Add an attribute writing rule with specialized converter to the
+    /// writer.
+    template <typename Value, typename Converter>
+    BpGraphWriter& attribute(const std::string& caption, const Value& value,
+                             const Converter& converter = Converter()) {
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node writing rule
+    ///
+    /// Add a node writing rule to the writer.
+    BpGraphWriter& node(const std::string& caption, const Node& node) {
+      typedef _writer_bits::DoubleMapLookUpConverter<
+        Node, RedNodeIndex, BlueNodeIndex> Converter;
+      Converter converter(_red_node_index, _blue_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node writing rule
+    ///
+    /// Add a red node writing rule to the writer.
+    BpGraphWriter& redNode(const std::string& caption, const RedNode& node) {
+      typedef _writer_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_red_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node writing rule
+    ///
+    /// Add a blue node writing rule to the writer.
+    BpGraphWriter& blueNode(const std::string& caption, const BlueNode& node) {
+      typedef _writer_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_blue_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge writing rule
+    ///
+    /// Add an edge writing rule to writer.
+    BpGraphWriter& edge(const std::string& caption, const Edge& edge) {
+      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
+      Converter converter(_edge_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc writing rule
+    ///
+    /// Add an arc writing rule to writer.
+    BpGraphWriter& arc(const std::string& caption, const Arc& arc) {
+      typedef _writer_bits::GraphArcLookUpConverter<BGR> Converter;
+      Converter converter(_graph, _edge_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \name Section Captions
+    /// @{
+
+    /// \brief Add an additional caption to the \c \@red_nodes and
+    /// \c \@blue_nodes section
+    ///
+    /// Add an additional caption to the \c \@red_nodes and \c
+    /// \@blue_nodes section.
+    BpGraphWriter& nodes(const std::string& caption) {
+      _nodes_caption = caption;
+      return *this;
+    }
+
+    /// \brief Add an additional caption to the \c \@edges section
+    ///
+    /// Add an additional caption to the \c \@edges section.
+    BpGraphWriter& edges(const std::string& caption) {
+      _edges_caption = caption;
+      return *this;
+    }
+
+    /// \brief Add an additional caption to the \c \@attributes section
+    ///
+    /// Add an additional caption to the \c \@attributes section.
+    BpGraphWriter& attributes(const std::string& caption) {
+      _attributes_caption = caption;
+      return *this;
+    }
+
+    /// \name Skipping Section
+    /// @{
+
+    /// \brief Skip writing the node set
+    ///
+    /// The \c \@red_nodes and \c \@blue_nodes section will not be
+    /// written to the stream.
+    BpGraphWriter& skipNodes() {
+      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
+      _skip_nodes = true;
+      return *this;
+    }
+
+    /// \brief Skip writing edge set
+    ///
+    /// The \c \@edges section will not be written to the stream.
+    BpGraphWriter& skipEdges() {
+      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
+      _skip_edges = true;
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    void writeRedNodes() {
+      _writer_bits::MapStorageBase<RedNode>* label = 0;
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@red_nodes";
+      if (!_nodes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
+      }
+      *_os << std::endl;
+
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<RedNode> nodes;
+      for (RedNodeIt n(_graph); n != INVALID; ++n) {
+        nodes.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<BGR, Node> id_map(_graph);
+        _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map);
+        std::sort(nodes.begin(), nodes.end(), id_less);
+      } else {
+        label->sort(nodes);
+      }
+
+      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
+        RedNode n = nodes[i];
+        if (label == 0) {
+          std::ostringstream os;
+          os << _graph.id(static_cast<Node>(n));
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _red_node_index.insert(std::make_pair(n, os.str()));
+        }
+        for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+             it != _red_node_maps.end(); ++it) {
+          std::string value = it->second->get(n);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _red_node_index.insert(std::make_pair(n, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void writeBlueNodes() {
+      _writer_bits::MapStorageBase<BlueNode>* label = 0;
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@blue_nodes";
+      if (!_nodes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
+      }
+      *_os << std::endl;
+
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<BlueNode> nodes;
+      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+        nodes.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<BGR, Node> id_map(_graph);
+        _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map);
+        std::sort(nodes.begin(), nodes.end(), id_less);
+      } else {
+        label->sort(nodes);
+      }
+
+      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
+        BlueNode n = nodes[i];
+        if (label == 0) {
+          std::ostringstream os;
+          os << _graph.id(static_cast<Node>(n));
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _blue_node_index.insert(std::make_pair(n, os.str()));
+        }
+        for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+             it != _blue_node_maps.end(); ++it) {
+          std::string value = it->second->get(n);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _blue_node_index.insert(std::make_pair(n, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void createRedNodeIndex() {
+      _writer_bits::MapStorageBase<RedNode>* label = 0;
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (RedNodeIt n(_graph); n != INVALID; ++n) {
+          std::ostringstream os;
+          os << _graph.id(n);
+          _red_node_index.insert(std::make_pair(n, os.str()));
+        }
+      } else {
+        for (RedNodeIt n(_graph); n != INVALID; ++n) {
+          std::string value = label->get(n);
+          _red_node_index.insert(std::make_pair(n, value));
+        }
+      }
+    }
+
+    void createBlueNodeIndex() {
+      _writer_bits::MapStorageBase<BlueNode>* label = 0;
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+          std::ostringstream os;
+          os << _graph.id(n);
+          _blue_node_index.insert(std::make_pair(n, os.str()));
+        }
+      } else {
+        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+          std::string value = label->get(n);
+          _blue_node_index.insert(std::make_pair(n, value));
+        }
+      }
+    }
+
+    void writeEdges() {
+      _writer_bits::MapStorageBase<Edge>* label = 0;
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@edges";
+      if (!_edges_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _edges_caption);
+      }
+      *_os << std::endl;
+
+      *_os << '\t' << '\t';
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<Edge> edges;
+      for (EdgeIt n(_graph); n != INVALID; ++n) {
+        edges.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<BGR, Edge> id_map(_graph);
+        _writer_bits::MapLess<IdMap<BGR, Edge> > id_less(id_map);
+        std::sort(edges.begin(), edges.end(), id_less);
+      } else {
+        label->sort(edges);
+      }
+
+      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
+        Edge e = edges[i];
+        _writer_bits::writeToken(*_os, _red_node_index.
+                                 find(_graph.redNode(e))->second);
+        *_os << '\t';
+        _writer_bits::writeToken(*_os, _blue_node_index.
+                                 find(_graph.blueNode(e))->second);
+        *_os << '\t';
+        if (label == 0) {
+          std::ostringstream os;
+          os << _graph.id(e);
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _edge_index.insert(std::make_pair(e, os.str()));
+        }
+        for (typename EdgeMaps::iterator it = _edge_maps.begin();
+             it != _edge_maps.end(); ++it) {
+          std::string value = it->second->get(e);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _edge_index.insert(std::make_pair(e, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void createEdgeIndex() {
+      _writer_bits::MapStorageBase<Edge>* label = 0;
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          std::ostringstream os;
+          os << _graph.id(e);
+          _edge_index.insert(std::make_pair(e, os.str()));
+        }
+      } else {
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          std::string value = label->get(e);
+          _edge_index.insert(std::make_pair(e, value));
+        }
+      }
+    }
+
+    void writeAttributes() {
+      if (_attributes.empty()) return;
+      *_os << "@attributes";
+      if (!_attributes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
+      }
+      *_os << std::endl;
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << ' ';
+        _writer_bits::writeToken(*_os, it->second->get());
+        *_os << std::endl;
+      }
+    }
+
+  public:
+
+    /// \name Execution of the Writer
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing.
+    void run() {
+      if (!_skip_nodes) {
+        writeRedNodes();
+        writeBlueNodes();
+      } else {
+        createRedNodeIndex();
+        createBlueNodeIndex();
+      }
+      if (!_skip_edges) {
+        writeEdges();
+      } else {
+        createEdgeIndex();
+      }
+      writeAttributes();
+    }
+
+    /// \brief Give back the stream of the writer
+    ///
+    /// Give back the stream of the writer
+    std::ostream& ostream() {
+      return *_os;
+    }
+
+    /// @}
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref lemon::BpGraphWriter "BpGraphWriter" class
+  ///
+  /// This function just returns a \ref lemon::BpGraphWriter
+  /// "BpGraphWriter" class.
+  ///
+  /// With this function a bipartite graph can be write to a file or output
+  /// stream in \ref lgf-format "LGF" format with several maps and
+  /// attributes. For example, with the following code a bipartite
+  /// weighted matching problem can be written to the standard output,
+  /// i.e. a graph with a \e weight map on the edges:
+  ///
+  ///\code
+  ///ListBpGraph graph;
+  ///ListBpGraph::EdgeMap<int> weight(graph);
+  ///  // Setting the weight map
+  ///bpGraphWriter(graph, std::cout).
+  ///  edgeMap("weight", weight).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the
+  /// \ref lemon::BpGraphWriter "BpGraphWriter"
+  /// class documentation.
+  /// \warning Don't forget to put the \ref lemon::BpGraphWriter::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates BpGraphWriter
+  /// \sa bpGraphWriter(const TBGR& graph, const std::string& fn)
+  /// \sa bpGraphWriter(const TBGR& graph, const char* fn)
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, std::ostream& os) {
+    BpGraphWriter<TBGR> tmp(graph, os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphWriter class
+  ///
+  /// This function just returns a \ref BpGraphWriter class.
+  /// \relates BpGraphWriter
+  /// \sa graphWriter(const TBGR& graph, std::ostream& os)
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn) {
+    BpGraphWriter<TBGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphWriter class
+  ///
+  /// This function just returns a \ref BpGraphWriter class.
+  /// \relates BpGraphWriter
+  /// \sa graphWriter(const TBGR& graph, std::ostream& os)
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn) {
+    BpGraphWriter<TBGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  class SectionWriter;
+
+  SectionWriter sectionWriter(std::istream& is);
+  SectionWriter sectionWriter(const std::string& fn);
+  SectionWriter sectionWriter(const char* fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Section writer class
+  ///
+  /// In the \ref lgf-format "LGF" file extra sections can be placed,
+  /// which contain any data in arbitrary format. Such sections can be
+  /// written with this class. A writing rule can be added to the
+  /// class with two different functions. With the \c sectionLines()
+  /// function a generator can write the section line-by-line, while
+  /// with the \c sectionStream() member the section can be written to
+  /// an output stream.
+  class SectionWriter {
+  private:
+
+    std::ostream* _os;
+    bool local_os;
+
+    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
+    Sections;
+
+    Sections _sections;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct a section writer, which writes to the given output
+    /// stream.
+    SectionWriter(std::ostream& os)
+      : _os(&os), local_os(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a section writer, which writes into the given file.
+    SectionWriter(const std::string& fn)
+      : _os(new std::ofstream(fn.c_str())), local_os(true) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct a section writer, which writes into the given file.
+    SectionWriter(const char* fn)
+      : _os(new std::ofstream(fn)), local_os(true) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~SectionWriter() {
+      for (Sections::iterator it = _sections.begin();
+           it != _sections.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_os) {
+        delete _os;
+      }
+
+    }
+
+  private:
+
+    friend SectionWriter sectionWriter(std::ostream& os);
+    friend SectionWriter sectionWriter(const std::string& fn);
+    friend SectionWriter sectionWriter(const char* fn);
+
+    SectionWriter(SectionWriter& other)
+      : _os(other._os), local_os(other.local_os) {
+
+      other._os = 0;
+      other.local_os = false;
+
+      _sections.swap(other._sections);
+    }
+
+    SectionWriter& operator=(const SectionWriter&);
+
+  public:
+
+    /// \name Section Writers
+    /// @{
+
+    /// \brief Add a section writer with line oriented writing
+    ///
+    /// The first parameter is the type descriptor of the section, the
+    /// second is a generator with std::string values. At the writing
+    /// process, the returned \c std::string will be written into the
+    /// output file until it is an empty string.
+    ///
+    /// For example, an integer vector is written into a section.
+    ///\code
+    ///  @numbers
+    ///  12 45 23 78
+    ///  4 28 38 28
+    ///  23 6 16
+    ///\endcode
+    ///
+    /// The generator is implemented as a struct.
+    ///\code
+    ///  struct NumberSection {
+    ///    std::vector<int>::const_iterator _it, _end;
+    ///    NumberSection(const std::vector<int>& data)
+    ///      : _it(data.begin()), _end(data.end()) {}
+    ///    std::string operator()() {
+    ///      int rem_in_line = 4;
+    ///      std::ostringstream ls;
+    ///      while (rem_in_line > 0 && _it != _end) {
+    ///        ls << *(_it++) << ' ';
+    ///        --rem_in_line;
+    ///      }
+    ///      return ls.str();
+    ///    }
+    ///  };
+    ///
+    ///  // ...
+    ///
+    ///  writer.sectionLines("numbers", NumberSection(vec));
+    ///\endcode
+    template <typename Functor>
+    SectionWriter& sectionLines(const std::string& type, Functor functor) {
+      LEMON_ASSERT(!type.empty(), "Type is empty.");
+      _sections.push_back(std::make_pair(type,
+        new _writer_bits::LineSection<Functor>(functor)));
+      return *this;
+    }
+
+
+    /// \brief Add a section writer with stream oriented writing
+    ///
+    /// The first parameter is the type of the section, the second is
+    /// a functor, which takes a \c std::ostream& parameter. The
+    /// functor writes the section to the output stream.
+    /// \warning The last line must be closed with end-line character.
+    template <typename Functor>
+    SectionWriter& sectionStream(const std::string& type, Functor functor) {
+      LEMON_ASSERT(!type.empty(), "Type is empty.");
+      _sections.push_back(std::make_pair(type,
+         new _writer_bits::StreamSection<Functor>(functor)));
+      return *this;
+    }
+
+    /// @}
+
+  public:
+
+
+    /// \name Execution of the Writer
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing.
+    void run() {
+
+      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
+
+      for (Sections::iterator it = _sections.begin();
+           it != _sections.end(); ++it) {
+        (*_os) << '@' << it->first << std::endl;
+        it->second->process(*_os);
+      }
+    }
+
+    /// \brief Give back the stream of the writer
+    ///
+    /// Returns the stream of the writer
+    std::ostream& ostream() {
+      return *_os;
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref SectionWriter class
+  ///
+  /// This function just returns a \ref SectionWriter class.
+  ///
+  /// Please see SectionWriter documentation about the custom section
+  /// output.
+  ///
+  /// \relates SectionWriter
+  /// \sa sectionWriter(const std::string& fn)
+  /// \sa sectionWriter(const char *fn)
+  inline SectionWriter sectionWriter(std::ostream& os) {
+    SectionWriter tmp(os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref SectionWriter class
+  ///
+  /// This function just returns a \ref SectionWriter class.
+  /// \relates SectionWriter
+  /// \sa sectionWriter(std::ostream& os)
+  inline SectionWriter sectionWriter(const std::string& fn) {
+    SectionWriter tmp(fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref SectionWriter class
+  ///
+  /// This function just returns a \ref SectionWriter class.
+  /// \relates SectionWriter
+  /// \sa sectionWriter(std::ostream& os)
+  inline SectionWriter sectionWriter(const char* fn) {
+    SectionWriter tmp(fn);
+    return tmp;
+  }
+}
+
+#endif
diff --git a/lemon/list_graph.h b/lemon/list_graph.h
new file mode 100644
index 0000000..2a236cf
--- /dev/null
+++ b/lemon/list_graph.h
@@ -0,0 +1,2510 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_LIST_GRAPH_H
+#define LEMON_LIST_GRAPH_H
+
+///\ingroup graphs
+///\file
+///\brief ListDigraph and ListGraph classes.
+
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/bits/graph_extender.h>
+
+#include <vector>
+#include <list>
+
+namespace lemon {
+
+  class ListDigraph;
+
+  class ListDigraphBase {
+
+  protected:
+    struct NodeT {
+      int first_in, first_out;
+      int prev, next;
+    };
+
+    struct ArcT {
+      int target, source;
+      int prev_in, prev_out;
+      int next_in, next_out;
+    };
+
+    std::vector<NodeT> nodes;
+
+    int first_node;
+
+    int first_free_node;
+
+    std::vector<ArcT> arcs;
+
+    int first_free_arc;
+
+  public:
+
+    typedef ListDigraphBase Digraph;
+
+    class Node {
+      friend class ListDigraphBase;
+      friend class ListDigraph;
+    protected:
+
+      int id;
+      explicit Node(int pid) { id = pid;}
+
+    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 ListDigraphBase;
+      friend class ListDigraph;
+    protected:
+
+      int id;
+      explicit Arc(int pid) { id = pid;}
+
+    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;}
+    };
+
+
+
+    ListDigraphBase()
+      : nodes(), first_node(-1),
+        first_free_node(-1), arcs(), first_free_arc(-1) {}
+
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(arcs[e.id].source); }
+    Node target(Arc e) const { return Node(arcs[e.id].target); }
+
+
+    void first(Node& node) const {
+      node.id = first_node;
+    }
+
+    void next(Node& node) const {
+      node.id = nodes[node.id].next;
+    }
+
+
+    void first(Arc& arc) const {
+      int n;
+      for(n = first_node;
+          n != -1 && nodes[n].first_out == -1;
+          n = nodes[n].next) {}
+      arc.id = (n == -1) ? -1 : nodes[n].first_out;
+    }
+
+    void next(Arc& arc) const {
+      if (arcs[arc.id].next_out != -1) {
+        arc.id = arcs[arc.id].next_out;
+      } else {
+        int n;
+        for(n = nodes[arcs[arc.id].source].next;
+            n != -1 && nodes[n].first_out == -1;
+            n = nodes[n].next) {}
+        arc.id = (n == -1) ? -1 : nodes[n].first_out;
+      }
+    }
+
+    void firstOut(Arc &e, const Node& v) const {
+      e.id = nodes[v.id].first_out;
+    }
+    void nextOut(Arc &e) const {
+      e.id=arcs[e.id].next_out;
+    }
+
+    void firstIn(Arc &e, const Node& v) const {
+      e.id = nodes[v.id].first_in;
+    }
+    void nextIn(Arc &e) const {
+      e.id=arcs[e.id].next_in;
+    }
+
+
+    static int id(Node v) { return v.id; }
+    static int id(Arc e) { return e.id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+
+    bool valid(Node n) const {
+      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
+        nodes[n.id].prev != -2;
+    }
+
+    bool valid(Arc a) const {
+      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
+        arcs[a.id].prev_in != -2;
+    }
+
+    Node addNode() {
+      int n;
+
+      if(first_free_node==-1) {
+        n = nodes.size();
+        nodes.push_back(NodeT());
+      } else {
+        n = first_free_node;
+        first_free_node = nodes[n].next;
+      }
+
+      nodes[n].next = first_node;
+      if(first_node != -1) nodes[first_node].prev = n;
+      first_node = n;
+      nodes[n].prev = -1;
+
+      nodes[n].first_in = nodes[n].first_out = -1;
+
+      return Node(n);
+    }
+
+    Arc addArc(Node u, Node v) {
+      int n;
+
+      if (first_free_arc == -1) {
+        n = arcs.size();
+        arcs.push_back(ArcT());
+      } else {
+        n = first_free_arc;
+        first_free_arc = arcs[n].next_in;
+      }
+
+      arcs[n].source = u.id;
+      arcs[n].target = v.id;
+
+      arcs[n].next_out = nodes[u.id].first_out;
+      if(nodes[u.id].first_out != -1) {
+        arcs[nodes[u.id].first_out].prev_out = n;
+      }
+
+      arcs[n].next_in = nodes[v.id].first_in;
+      if(nodes[v.id].first_in != -1) {
+        arcs[nodes[v.id].first_in].prev_in = n;
+      }
+
+      arcs[n].prev_in = arcs[n].prev_out = -1;
+
+      nodes[u.id].first_out = nodes[v.id].first_in = n;
+
+      return Arc(n);
+    }
+
+    void erase(const Node& node) {
+      int n = node.id;
+
+      if(nodes[n].next != -1) {
+        nodes[nodes[n].next].prev = nodes[n].prev;
+      }
+
+      if(nodes[n].prev != -1) {
+        nodes[nodes[n].prev].next = nodes[n].next;
+      } else {
+        first_node = nodes[n].next;
+      }
+
+      nodes[n].next = first_free_node;
+      first_free_node = n;
+      nodes[n].prev = -2;
+
+    }
+
+    void erase(const Arc& arc) {
+      int n = arc.id;
+
+      if(arcs[n].next_in!=-1) {
+        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
+      }
+
+      if(arcs[n].prev_in!=-1) {
+        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
+      } else {
+        nodes[arcs[n].target].first_in = arcs[n].next_in;
+      }
+
+
+      if(arcs[n].next_out!=-1) {
+        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
+      }
+
+      if(arcs[n].prev_out!=-1) {
+        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
+      } else {
+        nodes[arcs[n].source].first_out = arcs[n].next_out;
+      }
+
+      arcs[n].next_in = first_free_arc;
+      first_free_arc = n;
+      arcs[n].prev_in = -2;
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_node = first_free_node = first_free_arc = -1;
+    }
+
+  protected:
+    void changeTarget(Arc e, Node n)
+    {
+      if(arcs[e.id].next_in != -1)
+        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
+      if(arcs[e.id].prev_in != -1)
+        arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
+      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
+      if (nodes[n.id].first_in != -1) {
+        arcs[nodes[n.id].first_in].prev_in = e.id;
+      }
+      arcs[e.id].target = n.id;
+      arcs[e.id].prev_in = -1;
+      arcs[e.id].next_in = nodes[n.id].first_in;
+      nodes[n.id].first_in = e.id;
+    }
+    void changeSource(Arc e, Node n)
+    {
+      if(arcs[e.id].next_out != -1)
+        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
+      if(arcs[e.id].prev_out != -1)
+        arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
+      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
+      if (nodes[n.id].first_out != -1) {
+        arcs[nodes[n.id].first_out].prev_out = e.id;
+      }
+      arcs[e.id].source = n.id;
+      arcs[e.id].prev_out = -1;
+      arcs[e.id].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = e.id;
+    }
+
+  };
+
+  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
+
+  /// \addtogroup graphs
+  /// @{
+
+  ///A general directed graph structure.
+
+  ///\ref ListDigraph is a versatile and fast directed graph
+  ///implementation based on linked lists that are stored in
+  ///\c std::vector structures.
+  ///
+  ///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:
+    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
+    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
+    /// \brief Assignment of a digraph to another one is \e not allowed.
+    /// Use DigraphCopy instead.
+    void operator=(const ListDigraph &) {}
+  public:
+
+    /// Constructor
+
+    /// Constructor.
+    ///
+    ListDigraph() {}
+
+    ///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(); }
+
+    ///Add a new arc to the digraph.
+
+    ///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(Node s, Node t) {
+      return Parent::addArc(s, t);
+    }
+
+    ///\brief Erase a node from the digraph.
+    ///
+    ///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.
+    ///
+    ///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 \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 \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 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
+    ///feature.
+    void changeTarget(Arc a, Node n) {
+      Parent::changeTarget(a,n);
+    }
+    /// 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
+    ///feature.
+    void changeSource(Arc a, Node n) {
+      Parent::changeSource(a,n);
+    }
+
+    /// 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 a) {
+      Node t=target(a);
+      changeTarget(a,source(a));
+      changeSource(a,t);
+    }
+
+    ///Contract two nodes.
+
+    ///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 incoming 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 u, Node v, bool r = true)
+    {
+      for(OutArcIt e(*this,v);e!=INVALID;) {
+        OutArcIt f=e;
+        ++f;
+        if(r && target(e)==u) erase(e);
+        else changeSource(e,u);
+        e=f;
+      }
+      for(InArcIt e(*this,v);e!=INVALID;) {
+        InArcIt f=e;
+        ++f;
+        if(r && source(e)==u) erase(e);
+        else changeTarget(e,u);
+        e=f;
+      }
+      erase(v);
+    }
+
+    ///Split a node.
+
+    ///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 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();
+      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);
+      return b;
+    }
+
+    ///Split an arc.
+
+    ///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 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
+    /// it later.
+    ///
+    /// Class to make a snapshot of the digraph and restore it later.
+    ///
+    /// The newly added nodes and arcs can be removed using the
+    /// restore() function.
+    ///
+    /// \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:
+
+      typedef Parent::NodeNotifier NodeNotifier;
+
+      class NodeObserverProxy : public NodeNotifier::ObserverBase {
+      public:
+
+        NodeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using NodeNotifier::ObserverBase::attach;
+        using NodeNotifier::ObserverBase::detach;
+        using NodeNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Node& node) {
+          snapshot.addNode(node);
+        }
+        virtual void add(const std::vector<Node>& nodes) {
+          for (int i = nodes.size() - 1; i >= 0; ++i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void erase(const Node& node) {
+          snapshot.eraseNode(node);
+        }
+        virtual void erase(const std::vector<Node>& nodes) {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            snapshot.eraseNode(nodes[i]);
+          }
+        }
+        virtual void build() {
+          Node node;
+          std::vector<Node> nodes;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            nodes.push_back(node);
+          }
+          for (int i = nodes.size() - 1; i >= 0; --i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void clear() {
+          Node node;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            snapshot.eraseNode(node);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      class ArcObserverProxy : public ArcNotifier::ObserverBase {
+      public:
+
+        ArcObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using ArcNotifier::ObserverBase::attach;
+        using ArcNotifier::ObserverBase::detach;
+        using ArcNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Arc& arc) {
+          snapshot.addArc(arc);
+        }
+        virtual void add(const std::vector<Arc>& arcs) {
+          for (int i = arcs.size() - 1; i >= 0; ++i) {
+            snapshot.addArc(arcs[i]);
+          }
+        }
+        virtual void erase(const Arc& arc) {
+          snapshot.eraseArc(arc);
+        }
+        virtual void erase(const std::vector<Arc>& arcs) {
+          for (int i = 0; i < int(arcs.size()); ++i) {
+            snapshot.eraseArc(arcs[i]);
+          }
+        }
+        virtual void build() {
+          Arc arc;
+          std::vector<Arc> arcs;
+          for (notifier()->first(arc); arc != INVALID;
+               notifier()->next(arc)) {
+            arcs.push_back(arc);
+          }
+          for (int i = arcs.size() - 1; i >= 0; --i) {
+            snapshot.addArc(arcs[i]);
+          }
+        }
+        virtual void clear() {
+          Arc arc;
+          for (notifier()->first(arc); arc != INVALID;
+               notifier()->next(arc)) {
+            snapshot.eraseArc(arc);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      ListDigraph *digraph;
+
+      NodeObserverProxy node_observer_proxy;
+      ArcObserverProxy arc_observer_proxy;
+
+      std::list<Node> added_nodes;
+      std::list<Arc> added_arcs;
+
+
+      void addNode(const Node& node) {
+        added_nodes.push_front(node);
+      }
+      void eraseNode(const Node& node) {
+        std::list<Node>::iterator it =
+          std::find(added_nodes.begin(), added_nodes.end(), node);
+        if (it == added_nodes.end()) {
+          clear();
+          arc_observer_proxy.detach();
+          throw NodeNotifier::ImmediateDetach();
+        } else {
+          added_nodes.erase(it);
+        }
+      }
+
+      void addArc(const Arc& arc) {
+        added_arcs.push_front(arc);
+      }
+      void eraseArc(const Arc& arc) {
+        std::list<Arc>::iterator it =
+          std::find(added_arcs.begin(), added_arcs.end(), arc);
+        if (it == added_arcs.end()) {
+          clear();
+          node_observer_proxy.detach();
+          throw ArcNotifier::ImmediateDetach();
+        } else {
+          added_arcs.erase(it);
+        }
+      }
+
+      void attach(ListDigraph &_digraph) {
+        digraph = &_digraph;
+        node_observer_proxy.attach(digraph->notifier(Node()));
+        arc_observer_proxy.attach(digraph->notifier(Arc()));
+      }
+
+      void detach() {
+        node_observer_proxy.detach();
+        arc_observer_proxy.detach();
+      }
+
+      bool attached() const {
+        return node_observer_proxy.attached();
+      }
+
+      void clear() {
+        added_nodes.clear();
+        added_arcs.clear();
+      }
+
+    public:
+
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// You have to call save() to actually make a snapshot.
+      Snapshot()
+        : digraph(0), node_observer_proxy(*this),
+          arc_observer_proxy(*this) {}
+
+      /// \brief Constructor that immediately makes a snapshot.
+      ///
+      /// This constructor immediately makes a snapshot of the given digraph.
+      Snapshot(ListDigraph &gr)
+        : node_observer_proxy(*this),
+          arc_observer_proxy(*this) {
+        attach(gr);
+      }
+
+      /// \brief Make a snapshot.
+      ///
+      /// 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.
+      void save(ListDigraph &gr) {
+        if (attached()) {
+          detach();
+          clear();
+        }
+        attach(gr);
+      }
+
+      /// \brief Undo the changes until the last snapshot.
+      ///
+      /// 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();
+        for(std::list<Arc>::iterator it = added_arcs.begin();
+            it != added_arcs.end(); ++it) {
+          digraph->erase(*it);
+        }
+        for(std::list<Node>::iterator it = added_nodes.begin();
+            it != added_nodes.end(); ++it) {
+          digraph->erase(*it);
+        }
+        clear();
+      }
+
+      /// \brief Returns \c true if the snapshot is valid.
+      ///
+      /// This function returns \c true if the snapshot is valid.
+      bool valid() const {
+        return attached();
+      }
+    };
+
+  };
+
+  ///@}
+
+  class ListGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      int prev, next;
+    };
+
+    struct ArcT {
+      int target;
+      int prev_out, next_out;
+    };
+
+    std::vector<NodeT> nodes;
+
+    int first_node;
+
+    int first_free_node;
+
+    std::vector<ArcT> arcs;
+
+    int first_free_arc;
+
+  public:
+
+    typedef ListGraphBase Graph;
+
+    class Node {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Node(int pid) { id = pid;}
+
+    public:
+      Node() {}
+      Node (Invalid) { id = -1; }
+      bool operator==(const Node& node) const {return id == node.id;}
+      bool operator!=(const Node& node) const {return id != node.id;}
+      bool operator<(const Node& node) const {return id < node.id;}
+    };
+
+    class Edge {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Edge(int pid) { id = pid;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { id = -1; }
+      bool operator==(const Edge& edge) const {return id == edge.id;}
+      bool operator!=(const Edge& edge) const {return id != edge.id;}
+      bool operator<(const Edge& edge) const {return id < edge.id;}
+    };
+
+    class Arc {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Arc(int pid) { id = pid;}
+
+    public:
+      operator Edge() const {
+        return id != -1 ? edgeFromId(id / 2) : INVALID;
+      }
+
+      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;}
+    };
+
+    ListGraphBase()
+      : nodes(), first_node(-1),
+        first_free_node(-1), arcs(), first_free_arc(-1) {}
+
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
+    Node target(Arc e) const { return Node(arcs[e.id].target); }
+
+    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
+    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
+
+    static bool direction(Arc e) {
+      return (e.id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e.id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node.id = first_node;
+    }
+
+    void next(Node& node) const {
+      node.id = nodes[node.id].next;
+    }
+
+    void first(Arc& e) const {
+      int n = first_node;
+      while (n != -1 && nodes[n].first_out == -1) {
+        n = nodes[n].next;
+      }
+      e.id = (n == -1) ? -1 : nodes[n].first_out;
+    }
+
+    void next(Arc& e) const {
+      if (arcs[e.id].next_out != -1) {
+        e.id = arcs[e.id].next_out;
+      } else {
+        int n = nodes[arcs[e.id ^ 1].target].next;
+        while(n != -1 && nodes[n].first_out == -1) {
+          n = nodes[n].next;
+        }
+        e.id = (n == -1) ? -1 : nodes[n].first_out;
+      }
+    }
+
+    void first(Edge& e) const {
+      int n = first_node;
+      while (n != -1) {
+        e.id = nodes[n].first_out;
+        while ((e.id & 1) != 1) {
+          e.id = arcs[e.id].next_out;
+        }
+        if (e.id != -1) {
+          e.id /= 2;
+          return;
+        }
+        n = nodes[n].next;
+      }
+      e.id = -1;
+    }
+
+    void next(Edge& e) const {
+      int n = arcs[e.id * 2].target;
+      e.id = arcs[(e.id * 2) | 1].next_out;
+      while ((e.id & 1) != 1) {
+        e.id = arcs[e.id].next_out;
+      }
+      if (e.id != -1) {
+        e.id /= 2;
+        return;
+      }
+      n = nodes[n].next;
+      while (n != -1) {
+        e.id = nodes[n].first_out;
+        while ((e.id & 1) != 1) {
+          e.id = arcs[e.id].next_out;
+        }
+        if (e.id != -1) {
+          e.id /= 2;
+          return;
+        }
+        n = nodes[n].next;
+      }
+      e.id = -1;
+    }
+
+    void firstOut(Arc &e, const Node& v) const {
+      e.id = nodes[v.id].first_out;
+    }
+    void nextOut(Arc &e) const {
+      e.id = arcs[e.id].next_out;
+    }
+
+    void firstIn(Arc &e, const Node& v) const {
+      e.id = ((nodes[v.id].first_out) ^ 1);
+      if (e.id == -2) e.id = -1;
+    }
+    void nextIn(Arc &e) const {
+      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
+      if (e.id == -2) e.id = -1;
+    }
+
+    void firstInc(Edge &e, bool& d, const Node& v) const {
+      int a = nodes[v.id].first_out;
+      if (a != -1 ) {
+        e.id = a / 2;
+        d = ((a & 1) == 1);
+      } else {
+        e.id = -1;
+        d = true;
+      }
+    }
+    void nextInc(Edge &e, bool& d) const {
+      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
+      if (a != -1 ) {
+        e.id = a / 2;
+        d = ((a & 1) == 1);
+      } else {
+        e.id = -1;
+        d = true;
+      }
+    }
+
+    static int id(Node v) { return v.id; }
+    static int id(Arc e) { return e.id; }
+    static int id(Edge e) { return e.id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
+        nodes[n.id].prev != -2;
+    }
+
+    bool valid(Arc a) const {
+      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
+        arcs[a.id].prev_out != -2;
+    }
+
+    bool valid(Edge e) const {
+      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
+        arcs[2 * e.id].prev_out != -2;
+    }
+
+    Node addNode() {
+      int n;
+
+      if(first_free_node==-1) {
+        n = nodes.size();
+        nodes.push_back(NodeT());
+      } else {
+        n = first_free_node;
+        first_free_node = nodes[n].next;
+      }
+
+      nodes[n].next = first_node;
+      if (first_node != -1) nodes[first_node].prev = n;
+      first_node = n;
+      nodes[n].prev = -1;
+
+      nodes[n].first_out = -1;
+
+      return Node(n);
+    }
+
+    Edge addEdge(Node u, Node v) {
+      int n;
+
+      if (first_free_arc == -1) {
+        n = arcs.size();
+        arcs.push_back(ArcT());
+        arcs.push_back(ArcT());
+      } else {
+        n = first_free_arc;
+        first_free_arc = arcs[n].next_out;
+      }
+
+      arcs[n].target = u.id;
+      arcs[n | 1].target = v.id;
+
+      arcs[n].next_out = nodes[v.id].first_out;
+      if (nodes[v.id].first_out != -1) {
+        arcs[nodes[v.id].first_out].prev_out = n;
+      }
+      arcs[n].prev_out = -1;
+      nodes[v.id].first_out = n;
+
+      arcs[n | 1].next_out = nodes[u.id].first_out;
+      if (nodes[u.id].first_out != -1) {
+        arcs[nodes[u.id].first_out].prev_out = (n | 1);
+      }
+      arcs[n | 1].prev_out = -1;
+      nodes[u.id].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+
+    void erase(const Node& node) {
+      int n = node.id;
+
+      if(nodes[n].next != -1) {
+        nodes[nodes[n].next].prev = nodes[n].prev;
+      }
+
+      if(nodes[n].prev != -1) {
+        nodes[nodes[n].prev].next = nodes[n].next;
+      } else {
+        first_node = nodes[n].next;
+      }
+
+      nodes[n].next = first_free_node;
+      first_free_node = n;
+      nodes[n].prev = -2;
+    }
+
+    void erase(const Edge& edge) {
+      int n = edge.id * 2;
+
+      if (arcs[n].next_out != -1) {
+        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
+      }
+
+      if (arcs[n].prev_out != -1) {
+        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
+      } else {
+        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
+      }
+
+      if (arcs[n | 1].next_out != -1) {
+        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
+      }
+
+      if (arcs[n | 1].prev_out != -1) {
+        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
+      } else {
+        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
+      }
+
+      arcs[n].next_out = first_free_arc;
+      first_free_arc = n;
+      arcs[n].prev_out = -2;
+      arcs[n | 1].prev_out = -2;
+
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_node = first_free_node = first_free_arc = -1;
+    }
+
+  protected:
+
+    void changeV(Edge e, Node n) {
+      if(arcs[2 * e.id].next_out != -1) {
+        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
+      }
+      if(arcs[2 * e.id].prev_out != -1) {
+        arcs[arcs[2 * e.id].prev_out].next_out =
+          arcs[2 * e.id].next_out;
+      } else {
+        nodes[arcs[(2 * e.id) | 1].target].first_out =
+          arcs[2 * e.id].next_out;
+      }
+
+      if (nodes[n.id].first_out != -1) {
+        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
+      }
+      arcs[(2 * e.id) | 1].target = n.id;
+      arcs[2 * e.id].prev_out = -1;
+      arcs[2 * e.id].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = 2 * e.id;
+    }
+
+    void changeU(Edge e, Node n) {
+      if(arcs[(2 * e.id) | 1].next_out != -1) {
+        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
+          arcs[(2 * e.id) | 1].prev_out;
+      }
+      if(arcs[(2 * e.id) | 1].prev_out != -1) {
+        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
+          arcs[(2 * e.id) | 1].next_out;
+      } else {
+        nodes[arcs[2 * e.id].target].first_out =
+          arcs[(2 * e.id) | 1].next_out;
+      }
+
+      if (nodes[n.id].first_out != -1) {
+        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
+      }
+      arcs[2 * e.id].target = n.id;
+      arcs[(2 * e.id) | 1].prev_out = -1;
+      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = ((2 * e.id) | 1);
+    }
+
+  };
+
+  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
+
+
+  /// \addtogroup graphs
+  /// @{
+
+  ///A general undirected graph structure.
+
+  ///\ref ListGraph is a versatile and fast undirected graph
+  ///implementation based on linked lists that are stored in
+  ///\c std::vector structures.
+  ///
+  ///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:
+    /// Graphs are \e not copy constructible. Use GraphCopy instead.
+    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use GraphCopy instead.
+    void operator=(const ListGraph &) {}
+  public:
+    /// Constructor
+
+    /// Constructor.
+    ///
+    ListGraph() {}
+
+    typedef Parent::OutArcIt IncEdgeIt;
+
+    /// \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(); }
+
+    /// \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 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 \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 \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); }
+
+    /// \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
+    ///Snapshot feature.
+    void changeU(Edge e, Node n) {
+      Parent::changeU(e,n);
+    }
+    /// \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
+    ///Snapshot feature.
+    void changeV(Edge e, Node n) {
+      Parent::changeV(e,n);
+    }
+
+    /// \brief Contract two nodes.
+    ///
+    /// 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
+    ///Snapshot feature.
+    void contract(Node a, Node b, bool r = true) {
+      for(IncEdgeIt e(*this, b); e!=INVALID;) {
+        IncEdgeIt f = e; ++f;
+        if (r && runningNode(e) == a) {
+          erase(e);
+        } else if (u(e) == b) {
+          changeU(e, a);
+        } else {
+          changeV(e, a);
+        }
+        e = f;
+      }
+      erase(b);
+    }
+
+    ///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
+    /// it later.
+    ///
+    /// Class to make a snapshot of the graph and restore it later.
+    ///
+    /// The newly added nodes and edges can be removed
+    /// using the restore() function.
+    ///
+    /// \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:
+
+      typedef Parent::NodeNotifier NodeNotifier;
+
+      class NodeObserverProxy : public NodeNotifier::ObserverBase {
+      public:
+
+        NodeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using NodeNotifier::ObserverBase::attach;
+        using NodeNotifier::ObserverBase::detach;
+        using NodeNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Node& node) {
+          snapshot.addNode(node);
+        }
+        virtual void add(const std::vector<Node>& nodes) {
+          for (int i = nodes.size() - 1; i >= 0; ++i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void erase(const Node& node) {
+          snapshot.eraseNode(node);
+        }
+        virtual void erase(const std::vector<Node>& nodes) {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            snapshot.eraseNode(nodes[i]);
+          }
+        }
+        virtual void build() {
+          Node node;
+          std::vector<Node> nodes;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            nodes.push_back(node);
+          }
+          for (int i = nodes.size() - 1; i >= 0; --i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void clear() {
+          Node node;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            snapshot.eraseNode(node);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
+      public:
+
+        EdgeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using EdgeNotifier::ObserverBase::attach;
+        using EdgeNotifier::ObserverBase::detach;
+        using EdgeNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Edge& edge) {
+          snapshot.addEdge(edge);
+        }
+        virtual void add(const std::vector<Edge>& edges) {
+          for (int i = edges.size() - 1; i >= 0; ++i) {
+            snapshot.addEdge(edges[i]);
+          }
+        }
+        virtual void erase(const Edge& edge) {
+          snapshot.eraseEdge(edge);
+        }
+        virtual void erase(const std::vector<Edge>& edges) {
+          for (int i = 0; i < int(edges.size()); ++i) {
+            snapshot.eraseEdge(edges[i]);
+          }
+        }
+        virtual void build() {
+          Edge edge;
+          std::vector<Edge> edges;
+          for (notifier()->first(edge); edge != INVALID;
+               notifier()->next(edge)) {
+            edges.push_back(edge);
+          }
+          for (int i = edges.size() - 1; i >= 0; --i) {
+            snapshot.addEdge(edges[i]);
+          }
+        }
+        virtual void clear() {
+          Edge edge;
+          for (notifier()->first(edge); edge != INVALID;
+               notifier()->next(edge)) {
+            snapshot.eraseEdge(edge);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      ListGraph *graph;
+
+      NodeObserverProxy node_observer_proxy;
+      EdgeObserverProxy edge_observer_proxy;
+
+      std::list<Node> added_nodes;
+      std::list<Edge> added_edges;
+
+
+      void addNode(const Node& node) {
+        added_nodes.push_front(node);
+      }
+      void eraseNode(const Node& node) {
+        std::list<Node>::iterator it =
+          std::find(added_nodes.begin(), added_nodes.end(), node);
+        if (it == added_nodes.end()) {
+          clear();
+          edge_observer_proxy.detach();
+          throw NodeNotifier::ImmediateDetach();
+        } else {
+          added_nodes.erase(it);
+        }
+      }
+
+      void addEdge(const Edge& edge) {
+        added_edges.push_front(edge);
+      }
+      void eraseEdge(const Edge& edge) {
+        std::list<Edge>::iterator it =
+          std::find(added_edges.begin(), added_edges.end(), edge);
+        if (it == added_edges.end()) {
+          clear();
+          node_observer_proxy.detach();
+          throw EdgeNotifier::ImmediateDetach();
+        } else {
+          added_edges.erase(it);
+        }
+      }
+
+      void attach(ListGraph &_graph) {
+        graph = &_graph;
+        node_observer_proxy.attach(graph->notifier(Node()));
+        edge_observer_proxy.attach(graph->notifier(Edge()));
+      }
+
+      void detach() {
+        node_observer_proxy.detach();
+        edge_observer_proxy.detach();
+      }
+
+      bool attached() const {
+        return node_observer_proxy.attached();
+      }
+
+      void clear() {
+        added_nodes.clear();
+        added_edges.clear();
+      }
+
+    public:
+
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// You have to call save() to actually make a snapshot.
+      Snapshot()
+        : graph(0), node_observer_proxy(*this),
+          edge_observer_proxy(*this) {}
+
+      /// \brief Constructor that immediately makes a snapshot.
+      ///
+      /// This constructor immediately makes a snapshot of the given graph.
+      Snapshot(ListGraph &gr)
+        : node_observer_proxy(*this),
+          edge_observer_proxy(*this) {
+        attach(gr);
+      }
+
+      /// \brief Make a snapshot.
+      ///
+      /// 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.
+      void save(ListGraph &gr) {
+        if (attached()) {
+          detach();
+          clear();
+        }
+        attach(gr);
+      }
+
+      /// \brief Undo the changes until the last snapshot.
+      ///
+      /// 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();
+        for(std::list<Edge>::iterator it = added_edges.begin();
+            it != added_edges.end(); ++it) {
+          graph->erase(*it);
+        }
+        for(std::list<Node>::iterator it = added_nodes.begin();
+            it != added_nodes.end(); ++it) {
+          graph->erase(*it);
+        }
+        clear();
+      }
+
+      /// \brief Returns \c true if the snapshot is valid.
+      ///
+      /// This function returns \c true if the snapshot is valid.
+      bool valid() const {
+        return attached();
+      }
+    };
+  };
+
+  /// @}
+
+  class ListBpGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      int prev, next;
+      int partition_prev, partition_next;
+      int partition_index;
+      bool red;
+    };
+
+    struct ArcT {
+      int target;
+      int prev_out, next_out;
+    };
+
+    std::vector<NodeT> nodes;
+
+    int first_node, first_red, first_blue;
+    int max_red, max_blue;
+
+    int first_free_red, first_free_blue;
+
+    std::vector<ArcT> arcs;
+
+    int first_free_arc;
+
+  public:
+
+    typedef ListBpGraphBase BpGraph;
+
+    class Node {
+      friend class ListBpGraphBase;
+    protected:
+
+      int id;
+      explicit Node(int pid) { id = pid;}
+
+    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 RedNode : public Node {
+      friend class ListBpGraphBase;
+    protected:
+
+      explicit RedNode(int pid) : Node(pid) {}
+
+    public:
+      RedNode() {}
+      RedNode(const RedNode& node) : Node(node) {}
+      RedNode(Invalid) : Node(INVALID){}
+    };
+
+    class BlueNode : public Node {
+      friend class ListBpGraphBase;
+    protected:
+
+      explicit BlueNode(int pid) : Node(pid) {}
+
+    public:
+      BlueNode() {}
+      BlueNode(const BlueNode& node) : Node(node) {}
+      BlueNode(Invalid) : Node(INVALID){}
+    };
+
+    class Edge {
+      friend class ListBpGraphBase;
+    protected:
+
+      int id;
+      explicit Edge(int pid) { id = pid;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { id = -1; }
+      bool operator==(const Edge& edge) const {return id == edge.id;}
+      bool operator!=(const Edge& edge) const {return id != edge.id;}
+      bool operator<(const Edge& edge) const {return id < edge.id;}
+    };
+
+    class Arc {
+      friend class ListBpGraphBase;
+    protected:
+
+      int id;
+      explicit Arc(int pid) { id = pid;}
+
+    public:
+      operator Edge() const {
+        return id != -1 ? edgeFromId(id / 2) : INVALID;
+      }
+
+      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;}
+    };
+
+    ListBpGraphBase()
+      : nodes(), first_node(-1),
+        first_red(-1), first_blue(-1),
+        max_red(-1), max_blue(-1),
+        first_free_red(-1), first_free_blue(-1),
+        arcs(), first_free_arc(-1) {}
+
+
+    bool red(Node n) const { return nodes[n.id].red; }
+    bool blue(Node n) const { return !nodes[n.id].red; }
+
+    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n.id); }
+    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n.id); }
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxRedId() const { return max_red; }
+    int maxBlueId() const { return max_blue; }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
+    Node target(Arc e) const { return Node(arcs[e.id].target); }
+
+    RedNode redNode(Edge e) const {
+      return RedNode(arcs[2 * e.id].target);
+    }
+    BlueNode blueNode(Edge e) const {
+      return BlueNode(arcs[2 * e.id + 1].target);
+    }
+
+    static bool direction(Arc e) {
+      return (e.id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e.id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node.id = first_node;
+    }
+
+    void next(Node& node) const {
+      node.id = nodes[node.id].next;
+    }
+
+    void first(RedNode& node) const {
+      node.id = first_red;
+    }
+
+    void next(RedNode& node) const {
+      node.id = nodes[node.id].partition_next;
+    }
+
+    void first(BlueNode& node) const {
+      node.id = first_blue;
+    }
+
+    void next(BlueNode& node) const {
+      node.id = nodes[node.id].partition_next;
+    }
+
+    void first(Arc& e) const {
+      int n = first_node;
+      while (n != -1 && nodes[n].first_out == -1) {
+        n = nodes[n].next;
+      }
+      e.id = (n == -1) ? -1 : nodes[n].first_out;
+    }
+
+    void next(Arc& e) const {
+      if (arcs[e.id].next_out != -1) {
+        e.id = arcs[e.id].next_out;
+      } else {
+        int n = nodes[arcs[e.id ^ 1].target].next;
+        while(n != -1 && nodes[n].first_out == -1) {
+          n = nodes[n].next;
+        }
+        e.id = (n == -1) ? -1 : nodes[n].first_out;
+      }
+    }
+
+    void first(Edge& e) const {
+      int n = first_node;
+      while (n != -1) {
+        e.id = nodes[n].first_out;
+        while ((e.id & 1) != 1) {
+          e.id = arcs[e.id].next_out;
+        }
+        if (e.id != -1) {
+          e.id /= 2;
+          return;
+        }
+        n = nodes[n].next;
+      }
+      e.id = -1;
+    }
+
+    void next(Edge& e) const {
+      int n = arcs[e.id * 2].target;
+      e.id = arcs[(e.id * 2) | 1].next_out;
+      while ((e.id & 1) != 1) {
+        e.id = arcs[e.id].next_out;
+      }
+      if (e.id != -1) {
+        e.id /= 2;
+        return;
+      }
+      n = nodes[n].next;
+      while (n != -1) {
+        e.id = nodes[n].first_out;
+        while ((e.id & 1) != 1) {
+          e.id = arcs[e.id].next_out;
+        }
+        if (e.id != -1) {
+          e.id /= 2;
+          return;
+        }
+        n = nodes[n].next;
+      }
+      e.id = -1;
+    }
+
+    void firstOut(Arc &e, const Node& v) const {
+      e.id = nodes[v.id].first_out;
+    }
+    void nextOut(Arc &e) const {
+      e.id = arcs[e.id].next_out;
+    }
+
+    void firstIn(Arc &e, const Node& v) const {
+      e.id = ((nodes[v.id].first_out) ^ 1);
+      if (e.id == -2) e.id = -1;
+    }
+    void nextIn(Arc &e) const {
+      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
+      if (e.id == -2) e.id = -1;
+    }
+
+    void firstInc(Edge &e, bool& d, const Node& v) const {
+      int a = nodes[v.id].first_out;
+      if (a != -1 ) {
+        e.id = a / 2;
+        d = ((a & 1) == 1);
+      } else {
+        e.id = -1;
+        d = true;
+      }
+    }
+    void nextInc(Edge &e, bool& d) const {
+      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
+      if (a != -1 ) {
+        e.id = a / 2;
+        d = ((a & 1) == 1);
+      } else {
+        e.id = -1;
+        d = true;
+      }
+    }
+
+    static int id(Node v) { return v.id; }
+    int id(RedNode v) const { return nodes[v.id].partition_index; }
+    int id(BlueNode v) const { return nodes[v.id].partition_index; }
+    static int id(Arc e) { return e.id; }
+    static int id(Edge e) { return e.id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
+        nodes[n.id].prev != -2;
+    }
+
+    bool valid(Arc a) const {
+      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
+        arcs[a.id].prev_out != -2;
+    }
+
+    bool valid(Edge e) const {
+      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
+        arcs[2 * e.id].prev_out != -2;
+    }
+
+    RedNode addRedNode() {
+      int n;
+
+      if(first_free_red==-1) {
+        n = nodes.size();
+        nodes.push_back(NodeT());
+        nodes[n].partition_index = ++max_red;
+        nodes[n].red = true;
+      } else {
+        n = first_free_red;
+        first_free_red = nodes[n].next;
+      }
+
+      nodes[n].next = first_node;
+      if (first_node != -1) nodes[first_node].prev = n;
+      first_node = n;
+      nodes[n].prev = -1;
+
+      nodes[n].partition_next = first_red;
+      if (first_red != -1) nodes[first_red].partition_prev = n;
+      first_red = n;
+      nodes[n].partition_prev = -1;
+
+      nodes[n].first_out = -1;
+
+      return RedNode(n);
+    }
+
+    BlueNode addBlueNode() {
+      int n;
+
+      if(first_free_blue==-1) {
+        n = nodes.size();
+        nodes.push_back(NodeT());
+        nodes[n].partition_index = ++max_blue;
+        nodes[n].red = false;
+      } else {
+        n = first_free_blue;
+        first_free_blue = nodes[n].next;
+      }
+
+      nodes[n].next = first_node;
+      if (first_node != -1) nodes[first_node].prev = n;
+      first_node = n;
+      nodes[n].prev = -1;
+
+      nodes[n].partition_next = first_blue;
+      if (first_blue != -1) nodes[first_blue].partition_prev = n;
+      first_blue = n;
+      nodes[n].partition_prev = -1;
+
+      nodes[n].first_out = -1;
+
+      return BlueNode(n);
+    }
+
+    Edge addEdge(Node u, Node v) {
+      int n;
+
+      if (first_free_arc == -1) {
+        n = arcs.size();
+        arcs.push_back(ArcT());
+        arcs.push_back(ArcT());
+      } else {
+        n = first_free_arc;
+        first_free_arc = arcs[n].next_out;
+      }
+
+      arcs[n].target = u.id;
+      arcs[n | 1].target = v.id;
+
+      arcs[n].next_out = nodes[v.id].first_out;
+      if (nodes[v.id].first_out != -1) {
+        arcs[nodes[v.id].first_out].prev_out = n;
+      }
+      arcs[n].prev_out = -1;
+      nodes[v.id].first_out = n;
+
+      arcs[n | 1].next_out = nodes[u.id].first_out;
+      if (nodes[u.id].first_out != -1) {
+        arcs[nodes[u.id].first_out].prev_out = (n | 1);
+      }
+      arcs[n | 1].prev_out = -1;
+      nodes[u.id].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+
+    void erase(const Node& node) {
+      int n = node.id;
+
+      if(nodes[n].next != -1) {
+        nodes[nodes[n].next].prev = nodes[n].prev;
+      }
+
+      if(nodes[n].prev != -1) {
+        nodes[nodes[n].prev].next = nodes[n].next;
+      } else {
+        first_node = nodes[n].next;
+      }
+
+      if (nodes[n].partition_next != -1) {
+        nodes[nodes[n].partition_next].partition_prev = nodes[n].partition_prev;
+      }
+
+      if (nodes[n].partition_prev != -1) {
+        nodes[nodes[n].partition_prev].partition_next = nodes[n].partition_next;
+      } else {
+        if (nodes[n].red) {
+          first_red = nodes[n].partition_next;
+        } else {
+          first_blue = nodes[n].partition_next;
+        }
+      }
+
+      if (nodes[n].red) {
+        nodes[n].next = first_free_red;
+        first_free_red = n;
+      } else {
+        nodes[n].next = first_free_blue;
+        first_free_blue = n;
+      }
+      nodes[n].prev = -2;
+    }
+
+    void erase(const Edge& edge) {
+      int n = edge.id * 2;
+
+      if (arcs[n].next_out != -1) {
+        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
+      }
+
+      if (arcs[n].prev_out != -1) {
+        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
+      } else {
+        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
+      }
+
+      if (arcs[n | 1].next_out != -1) {
+        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
+      }
+
+      if (arcs[n | 1].prev_out != -1) {
+        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
+      } else {
+        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
+      }
+
+      arcs[n].next_out = first_free_arc;
+      first_free_arc = n;
+      arcs[n].prev_out = -2;
+      arcs[n | 1].prev_out = -2;
+
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_node = first_free_arc = first_red = first_blue =
+        max_red = max_blue = first_free_red = first_free_blue = -1;
+    }
+
+  protected:
+
+    void changeRed(Edge e, RedNode n) {
+      if(arcs[(2 * e.id) | 1].next_out != -1) {
+        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
+          arcs[(2 * e.id) | 1].prev_out;
+      }
+      if(arcs[(2 * e.id) | 1].prev_out != -1) {
+        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
+          arcs[(2 * e.id) | 1].next_out;
+      } else {
+        nodes[arcs[2 * e.id].target].first_out =
+          arcs[(2 * e.id) | 1].next_out;
+      }
+
+      if (nodes[n.id].first_out != -1) {
+        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
+      }
+      arcs[2 * e.id].target = n.id;
+      arcs[(2 * e.id) | 1].prev_out = -1;
+      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = ((2 * e.id) | 1);
+    }
+
+    void changeBlue(Edge e, BlueNode n) {
+       if(arcs[2 * e.id].next_out != -1) {
+        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
+      }
+      if(arcs[2 * e.id].prev_out != -1) {
+        arcs[arcs[2 * e.id].prev_out].next_out =
+          arcs[2 * e.id].next_out;
+      } else {
+        nodes[arcs[(2 * e.id) | 1].target].first_out =
+          arcs[2 * e.id].next_out;
+      }
+
+      if (nodes[n.id].first_out != -1) {
+        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
+      }
+      arcs[(2 * e.id) | 1].target = n.id;
+      arcs[2 * e.id].prev_out = -1;
+      arcs[2 * e.id].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = 2 * e.id;
+    }
+
+  };
+
+  typedef BpGraphExtender<ListBpGraphBase> ExtendedListBpGraphBase;
+
+
+  /// \addtogroup graphs
+  /// @{
+
+  ///A general undirected graph structure.
+
+  ///\ref ListBpGraph is a versatile and fast undirected graph
+  ///implementation based on linked lists that are stored in
+  ///\c std::vector structures.
+  ///
+  ///This type fully conforms to the \ref concepts::BpGraph "BpGraph 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::BpGraph
+  ///\sa ListDigraph
+  class ListBpGraph : public ExtendedListBpGraphBase {
+    typedef ExtendedListBpGraphBase Parent;
+
+  private:
+    /// BpGraphs are \e not copy constructible. Use BpGraphCopy instead.
+    ListBpGraph(const ListBpGraph &) :ExtendedListBpGraphBase()  {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use BpGraphCopy instead.
+    void operator=(const ListBpGraph &) {}
+  public:
+    /// Constructor
+
+    /// Constructor.
+    ///
+    ListBpGraph() {}
+
+    typedef Parent::OutArcIt IncEdgeIt;
+
+    /// \brief Add a new red node to the graph.
+    ///
+    /// This function adds a red new node to the graph.
+    /// \return The new node.
+    RedNode addRedNode() { return Parent::addRedNode(); }
+
+    /// \brief Add a new blue node to the graph.
+    ///
+    /// This function adds a blue new node to the graph.
+    /// \return The new node.
+    BlueNode addBlueNode() { return Parent::addBlueNode(); }
+
+    /// \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(RedNode u, BlueNode v) {
+      return Parent::addEdge(u, v);
+    }
+    Edge addEdge(BlueNode v, RedNode u) {
+      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 \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 \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); }
+
+    /// \brief Change the red node of an edge.
+    ///
+    /// This function changes the red 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
+    ///Snapshot feature.
+    void changeRed(Edge e, RedNode n) {
+      Parent::changeRed(e, n);
+    }
+    /// \brief Change the blue node of an edge.
+    ///
+    /// This function changes the blue 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
+    ///Snapshot feature.
+    void changeBlue(Edge e, BlueNode n) {
+      Parent::changeBlue(e, n);
+    }
+
+    ///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
+    /// it later.
+    ///
+    /// Class to make a snapshot of the graph and restore it later.
+    ///
+    /// The newly added nodes and edges can be removed
+    /// using the restore() function.
+    ///
+    /// \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:
+
+      typedef Parent::NodeNotifier NodeNotifier;
+
+      class NodeObserverProxy : public NodeNotifier::ObserverBase {
+      public:
+
+        NodeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using NodeNotifier::ObserverBase::attach;
+        using NodeNotifier::ObserverBase::detach;
+        using NodeNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Node& node) {
+          snapshot.addNode(node);
+        }
+        virtual void add(const std::vector<Node>& nodes) {
+          for (int i = nodes.size() - 1; i >= 0; ++i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void erase(const Node& node) {
+          snapshot.eraseNode(node);
+        }
+        virtual void erase(const std::vector<Node>& nodes) {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            snapshot.eraseNode(nodes[i]);
+          }
+        }
+        virtual void build() {
+          Node node;
+          std::vector<Node> nodes;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            nodes.push_back(node);
+          }
+          for (int i = nodes.size() - 1; i >= 0; --i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void clear() {
+          Node node;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            snapshot.eraseNode(node);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
+      public:
+
+        EdgeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using EdgeNotifier::ObserverBase::attach;
+        using EdgeNotifier::ObserverBase::detach;
+        using EdgeNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Edge& edge) {
+          snapshot.addEdge(edge);
+        }
+        virtual void add(const std::vector<Edge>& edges) {
+          for (int i = edges.size() - 1; i >= 0; ++i) {
+            snapshot.addEdge(edges[i]);
+          }
+        }
+        virtual void erase(const Edge& edge) {
+          snapshot.eraseEdge(edge);
+        }
+        virtual void erase(const std::vector<Edge>& edges) {
+          for (int i = 0; i < int(edges.size()); ++i) {
+            snapshot.eraseEdge(edges[i]);
+          }
+        }
+        virtual void build() {
+          Edge edge;
+          std::vector<Edge> edges;
+          for (notifier()->first(edge); edge != INVALID;
+               notifier()->next(edge)) {
+            edges.push_back(edge);
+          }
+          for (int i = edges.size() - 1; i >= 0; --i) {
+            snapshot.addEdge(edges[i]);
+          }
+        }
+        virtual void clear() {
+          Edge edge;
+          for (notifier()->first(edge); edge != INVALID;
+               notifier()->next(edge)) {
+            snapshot.eraseEdge(edge);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      ListBpGraph *graph;
+
+      NodeObserverProxy node_observer_proxy;
+      EdgeObserverProxy edge_observer_proxy;
+
+      std::list<Node> added_nodes;
+      std::list<Edge> added_edges;
+
+
+      void addNode(const Node& node) {
+        added_nodes.push_front(node);
+      }
+      void eraseNode(const Node& node) {
+        std::list<Node>::iterator it =
+          std::find(added_nodes.begin(), added_nodes.end(), node);
+        if (it == added_nodes.end()) {
+          clear();
+          edge_observer_proxy.detach();
+          throw NodeNotifier::ImmediateDetach();
+        } else {
+          added_nodes.erase(it);
+        }
+      }
+
+      void addEdge(const Edge& edge) {
+        added_edges.push_front(edge);
+      }
+      void eraseEdge(const Edge& edge) {
+        std::list<Edge>::iterator it =
+          std::find(added_edges.begin(), added_edges.end(), edge);
+        if (it == added_edges.end()) {
+          clear();
+          node_observer_proxy.detach();
+          throw EdgeNotifier::ImmediateDetach();
+        } else {
+          added_edges.erase(it);
+        }
+      }
+
+      void attach(ListBpGraph &_graph) {
+        graph = &_graph;
+        node_observer_proxy.attach(graph->notifier(Node()));
+        edge_observer_proxy.attach(graph->notifier(Edge()));
+      }
+
+      void detach() {
+        node_observer_proxy.detach();
+        edge_observer_proxy.detach();
+      }
+
+      bool attached() const {
+        return node_observer_proxy.attached();
+      }
+
+      void clear() {
+        added_nodes.clear();
+        added_edges.clear();
+      }
+
+    public:
+
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// You have to call save() to actually make a snapshot.
+      Snapshot()
+        : graph(0), node_observer_proxy(*this),
+          edge_observer_proxy(*this) {}
+
+      /// \brief Constructor that immediately makes a snapshot.
+      ///
+      /// This constructor immediately makes a snapshot of the given graph.
+      Snapshot(ListBpGraph &gr)
+        : node_observer_proxy(*this),
+          edge_observer_proxy(*this) {
+        attach(gr);
+      }
+
+      /// \brief Make a snapshot.
+      ///
+      /// 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.
+      void save(ListBpGraph &gr) {
+        if (attached()) {
+          detach();
+          clear();
+        }
+        attach(gr);
+      }
+
+      /// \brief Undo the changes until the last snapshot.
+      ///
+      /// This function undos the changes until the last snapshot
+      /// created by save() or Snapshot(ListBpGraph&).
+      ///
+      /// \warning This method invalidates the snapshot, i.e. repeated
+      /// restoring is not supported unless you call save() again.
+      void restore() {
+        detach();
+        for(std::list<Edge>::iterator it = added_edges.begin();
+            it != added_edges.end(); ++it) {
+          graph->erase(*it);
+        }
+        for(std::list<Node>::iterator it = added_nodes.begin();
+            it != added_nodes.end(); ++it) {
+          graph->erase(*it);
+        }
+        clear();
+      }
+
+      /// \brief Returns \c true if the snapshot is valid.
+      ///
+      /// This function returns \c true if the snapshot is valid.
+      bool valid() const {
+        return attached();
+      }
+    };
+  };
+
+  /// @}
+} //namespace lemon
+
+
+#endif
diff --git a/lemon/lp.h b/lemon/lp.h
new file mode 100644
index 0000000..567763f
--- /dev/null
+++ b/lemon/lp.h
@@ -0,0 +1,95 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_H
+#define LEMON_LP_H
+
+#include<lemon/config.h>
+
+
+#ifdef LEMON_HAVE_GLPK
+#include <lemon/glpk.h>
+#elif LEMON_HAVE_CPLEX
+#include <lemon/cplex.h>
+#elif LEMON_HAVE_SOPLEX
+#include <lemon/soplex.h>
+#elif LEMON_HAVE_CLP
+#include <lemon/clp.h>
+#elif LEMON_HAVE_CBC
+#include <lemon/cbc.h>
+#endif
+
+///\file
+///\brief Defines a default LP solver
+///\ingroup lp_group
+namespace lemon {
+
+#ifdef DOXYGEN
+  ///The default LP solver identifier
+
+  ///The default LP solver identifier.
+  ///\ingroup lp_group
+  ///
+  ///Currently, the possible values are \c _LEMON_GLPK, \c LEMON__CPLEX,
+  ///\c _LEMON_SOPLEX or \c LEMON__CLP
+#define LEMON_DEFAULT_LP SOLVER
+  ///The default LP solver
+
+  ///The default LP solver.
+  ///\ingroup lp_group
+  ///
+  ///Currently, it is either \c GlpkLp, \c CplexLp, \c SoplexLp or \c ClpLp
+  typedef GlpkLp Lp;
+
+  ///The default MIP solver identifier
+
+  ///The default MIP solver identifier.
+  ///\ingroup lp_group
+  ///
+  ///Currently, the possible values are \c _LEMON_GLPK, \c LEMON__CPLEX
+  ///or \c _LEMON_CBC
+#define LEMON_DEFAULT_MIP SOLVER
+  ///The default MIP solver.
+
+  ///The default MIP solver.
+  ///\ingroup lp_group
+  ///
+  ///Currently, it is either \c GlpkMip, \c CplexMip , \c CbcMip
+  typedef GlpkMip Mip;
+#else
+#if LEMON_DEFAULT_LP == _LEMON_GLPK
+  typedef GlpkLp Lp;
+#elif LEMON_DEFAULT_LP == _LEMON_CPLEX
+  typedef CplexLp Lp;
+#elif LEMON_DEFAULT_LP == _LEMON_SOPLEX
+  typedef SoplexLp Lp;
+#elif LEMON_DEFAULT_LP == _LEMON_CLP
+  typedef ClpLp Lp;
+#endif
+#if LEMON_DEFAULT_MIP == _LEMON_GLPK
+  typedef GlpkMip Mip;
+#elif LEMON_DEFAULT_MIP == _LEMON_CPLEX
+  typedef CplexMip Mip;
+#elif LEMON_DEFAULT_MIP == _LEMON_CBC
+  typedef CbcMip Mip;
+#endif
+#endif
+
+} //namespace lemon
+
+#endif //LEMON_LP_H
diff --git a/lemon/lp_base.cc b/lemon/lp_base.cc
new file mode 100644
index 0000000..312fd63
--- /dev/null
+++ b/lemon/lp_base.cc
@@ -0,0 +1,30 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief The implementation of the LP solver interface.
+
+#include <lemon/lp_base.h>
+namespace lemon {
+
+  const LpBase::Value LpBase::INF =
+    std::numeric_limits<LpBase::Value>::infinity();
+  const LpBase::Value LpBase::NaN =
+    std::numeric_limits<LpBase::Value>::quiet_NaN();
+
+} //namespace lemon
diff --git a/lemon/lp_base.h b/lemon/lp_base.h
new file mode 100644
index 0000000..22d3e48
--- /dev/null
+++ b/lemon/lp_base.h
@@ -0,0 +1,2147 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_BASE_H
+#define LEMON_LP_BASE_H
+
+#include<iostream>
+#include<vector>
+#include<map>
+#include<limits>
+#include<lemon/math.h>
+
+#include<lemon/error.h>
+#include<lemon/assert.h>
+
+#include<lemon/core.h>
+#include<lemon/bits/solver_bits.h>
+
+///\file
+///\brief The interface of the LP solver interface.
+///\ingroup lp_group
+namespace lemon {
+
+  ///Common base class for LP and MIP solvers
+
+  ///Usually this class is not used directly, please use one of the concrete
+  ///implementations of the solver interface.
+  ///\ingroup lp_group
+  class LpBase {
+
+  protected:
+
+    _solver_bits::VarIndex rows;
+    _solver_bits::VarIndex cols;
+
+  public:
+
+    ///Possible outcomes of an LP solving procedure
+    enum SolveExitStatus {
+      /// = 0. It means that the problem has been successfully solved: either
+      ///an optimal solution has been found or infeasibility/unboundedness
+      ///has been proved.
+      SOLVED = 0,
+      /// = 1. Any other case (including the case when some user specified
+      ///limit has been exceeded).
+      UNSOLVED = 1
+    };
+
+    ///Direction of the optimization
+    enum Sense {
+      /// Minimization
+      MIN,
+      /// Maximization
+      MAX
+    };
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// No output (default value).
+      MESSAGE_NOTHING,
+      /// Error messages only.
+      MESSAGE_ERROR,
+      /// Warnings.
+      MESSAGE_WARNING,
+      /// Normal output.
+      MESSAGE_NORMAL,
+      /// Verbose output.
+      MESSAGE_VERBOSE
+    };
+
+
+    ///The floating point type used by the solver
+    typedef double Value;
+    ///The infinity constant
+    static const Value INF;
+    ///The not a number constant
+    static const Value NaN;
+
+    friend class Col;
+    friend class ColIt;
+    friend class Row;
+    friend class RowIt;
+
+    ///Refer to a column of the LP.
+
+    ///This type is used to refer to a column of the LP.
+    ///
+    ///Its value remains valid and correct even after the addition or erase of
+    ///other columns.
+    ///
+    ///\note This class is similar to other Item types in LEMON, like
+    ///Node and Arc types in digraph.
+    class Col {
+      friend class LpBase;
+    protected:
+      int _id;
+      explicit Col(int id) : _id(id) {}
+    public:
+      typedef Value ExprValue;
+      typedef True LpCol;
+      /// Default constructor
+
+      /// \warning The default constructor sets the Col to an
+      /// undefined value.
+      Col() {}
+      /// Invalid constructor \& conversion.
+
+      /// This constructor initializes the Col to be invalid.
+      /// \sa Invalid for more details.
+      Col(const Invalid&) : _id(-1) {}
+      /// Equality operator
+
+      /// Two \ref Col "Col"s are equal if and only if they point to
+      /// the same LP column or both are invalid.
+      bool operator==(Col c) const  {return _id == c._id;}
+      /// Inequality operator
+
+      /// \sa operator==(Col c)
+      ///
+      bool operator!=(Col c) const  {return _id != c._id;}
+      /// Artificial ordering operator.
+
+      /// To allow the use of this object in std::map or similar
+      /// associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(Col c) const  {return _id < c._id;}
+    };
+
+    ///Iterator for iterate over the columns of an LP problem
+
+    /// Its usage is quite simple, for example, you can count the number
+    /// of columns in an LP \c lp:
+    ///\code
+    /// int count=0;
+    /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
+    ///\endcode
+    class ColIt : public Col {
+      const LpBase *_solver;
+    public:
+      /// Default constructor
+
+      /// \warning The default constructor sets the iterator
+      /// to an undefined value.
+      ColIt() {}
+      /// Sets the iterator to the first Col
+
+      /// Sets the iterator to the first Col.
+      ///
+      ColIt(const LpBase &solver) : _solver(&solver)
+      {
+        _solver->cols.firstItem(_id);
+      }
+      /// Invalid constructor \& conversion
+
+      /// Initialize the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ColIt(const Invalid&) : Col(INVALID) {}
+      /// Next column
+
+      /// Assign the iterator to the next column.
+      ///
+      ColIt &operator++()
+      {
+        _solver->cols.nextItem(_id);
+        return *this;
+      }
+    };
+
+    /// \brief Returns the ID of the column.
+    static int id(const Col& col) { return col._id; }
+    /// \brief Returns the column with the given ID.
+    ///
+    /// \pre The argument should be a valid column ID in the LP problem.
+    static Col colFromId(int id) { return Col(id); }
+
+    ///Refer to a row of the LP.
+
+    ///This type is used to refer to a row of the LP.
+    ///
+    ///Its value remains valid and correct even after the addition or erase of
+    ///other rows.
+    ///
+    ///\note This class is similar to other Item types in LEMON, like
+    ///Node and Arc types in digraph.
+    class Row {
+      friend class LpBase;
+    protected:
+      int _id;
+      explicit Row(int id) : _id(id) {}
+    public:
+      typedef Value ExprValue;
+      typedef True LpRow;
+      /// Default constructor
+
+      /// \warning The default constructor sets the Row to an
+      /// undefined value.
+      Row() {}
+      /// Invalid constructor \& conversion.
+
+      /// This constructor initializes the Row to be invalid.
+      /// \sa Invalid for more details.
+      Row(const Invalid&) : _id(-1) {}
+      /// Equality operator
+
+      /// Two \ref Row "Row"s are equal if and only if they point to
+      /// the same LP row or both are invalid.
+      bool operator==(Row r) const  {return _id == r._id;}
+      /// Inequality operator
+
+      /// \sa operator==(Row r)
+      ///
+      bool operator!=(Row r) const  {return _id != r._id;}
+      /// Artificial ordering operator.
+
+      /// To allow the use of this object in std::map or similar
+      /// associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(Row r) const  {return _id < r._id;}
+    };
+
+    ///Iterator for iterate over the rows of an LP problem
+
+    /// Its usage is quite simple, for example, you can count the number
+    /// of rows in an LP \c lp:
+    ///\code
+    /// int count=0;
+    /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
+    ///\endcode
+    class RowIt : public Row {
+      const LpBase *_solver;
+    public:
+      /// Default constructor
+
+      /// \warning The default constructor sets the iterator
+      /// to an undefined value.
+      RowIt() {}
+      /// Sets the iterator to the first Row
+
+      /// Sets the iterator to the first Row.
+      ///
+      RowIt(const LpBase &solver) : _solver(&solver)
+      {
+        _solver->rows.firstItem(_id);
+      }
+      /// Invalid constructor \& conversion
+
+      /// Initialize the iterator to be invalid.
+      /// \sa Invalid for more details.
+      RowIt(const Invalid&) : Row(INVALID) {}
+      /// Next row
+
+      /// Assign the iterator to the next row.
+      ///
+      RowIt &operator++()
+      {
+        _solver->rows.nextItem(_id);
+        return *this;
+      }
+    };
+
+    /// \brief Returns the ID of the row.
+    static int id(const Row& row) { return row._id; }
+    /// \brief Returns the row with the given ID.
+    ///
+    /// \pre The argument should be a valid row ID in the LP problem.
+    static Row rowFromId(int id) { return Row(id); }
+
+  public:
+
+    ///Linear expression of variables and a constant component
+
+    ///This data structure stores a linear expression of the variables
+    ///(\ref Col "Col"s) and also has a constant component.
+    ///
+    ///There are several ways to access and modify the contents of this
+    ///container.
+    ///\code
+    ///e[v]=5;
+    ///e[v]+=12;
+    ///e.erase(v);
+    ///\endcode
+    ///or you can also iterate through its elements.
+    ///\code
+    ///double s=0;
+    ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
+    ///  s+=*i * primal(i);
+    ///\endcode
+    ///(This code computes the primal value of the expression).
+    ///- Numbers (<tt>double</tt>'s)
+    ///and variables (\ref Col "Col"s) directly convert to an
+    ///\ref Expr and the usual linear operations are defined, so
+    ///\code
+    ///v+w
+    ///2*v-3.12*(v-w/2)+2
+    ///v*2.1+(3*v+(v*12+w+6)*3)/2
+    ///\endcode
+    ///are valid expressions.
+    ///The usual assignment operations are also defined.
+    ///\code
+    ///e=v+w;
+    ///e+=2*v-3.12*(v-w/2)+2;
+    ///e*=3.4;
+    ///e/=5;
+    ///\endcode
+    ///- The constant member can be set and read by dereference
+    ///  operator (unary *)
+    ///
+    ///\code
+    ///*e=12;
+    ///double c=*e;
+    ///\endcode
+    ///
+    ///\sa Constr
+    class Expr {
+      friend class LpBase;
+    public:
+      /// The key type of the expression
+      typedef LpBase::Col Key;
+      /// The value type of the expression
+      typedef LpBase::Value Value;
+
+    protected:
+      Value const_comp;
+      std::map<int, Value> comps;
+
+    public:
+      typedef True SolverExpr;
+      /// Default constructor
+
+      /// Construct an empty expression, the coefficients and
+      /// the constant component are initialized to zero.
+      Expr() : const_comp(0) {}
+      /// Construct an expression from a column
+
+      /// Construct an expression, which has a term with \c c variable
+      /// and 1.0 coefficient.
+      Expr(const Col &c) : const_comp(0) {
+        typedef std::map<int, Value>::value_type pair_type;
+        comps.insert(pair_type(id(c), 1));
+      }
+      /// Construct an expression from a constant
+
+      /// Construct an expression, which's constant component is \c v.
+      ///
+      Expr(const Value &v) : const_comp(v) {}
+      /// Returns the coefficient of the column
+      Value operator[](const Col& c) const {
+        std::map<int, Value>::const_iterator it=comps.find(id(c));
+        if (it != comps.end()) {
+          return it->second;
+        } else {
+          return 0;
+        }
+      }
+      /// Returns the coefficient of the column
+      Value& operator[](const Col& c) {
+        return comps[id(c)];
+      }
+      /// Sets the coefficient of the column
+      void set(const Col &c, const Value &v) {
+        if (v != 0.0) {
+          typedef std::map<int, Value>::value_type pair_type;
+          comps.insert(pair_type(id(c), v));
+        } else {
+          comps.erase(id(c));
+        }
+      }
+      /// Returns the constant component of the expression
+      Value& operator*() { return const_comp; }
+      /// Returns the constant component of the expression
+      const Value& operator*() const { return const_comp; }
+      /// \brief Removes the coefficients which's absolute value does
+      /// not exceed \c epsilon. It also sets to zero the constant
+      /// component, if it does not exceed epsilon in absolute value.
+      void simplify(Value epsilon = 0.0) {
+        std::map<int, Value>::iterator it=comps.begin();
+        while (it != comps.end()) {
+          std::map<int, Value>::iterator jt=it;
+          ++jt;
+          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
+          it=jt;
+        }
+        if (std::fabs(const_comp) <= epsilon) const_comp = 0;
+      }
+
+      void simplify(Value epsilon = 0.0) const {
+        const_cast<Expr*>(this)->simplify(epsilon);
+      }
+
+      ///Sets all coefficients and the constant component to 0.
+      void clear() {
+        comps.clear();
+        const_comp=0;
+      }
+
+      ///Compound assignment
+      Expr &operator+=(const Expr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]+=it->second;
+        const_comp+=e.const_comp;
+        return *this;
+      }
+      ///Compound assignment
+      Expr &operator-=(const Expr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]-=it->second;
+        const_comp-=e.const_comp;
+        return *this;
+      }
+      ///Multiply with a constant
+      Expr &operator*=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second*=v;
+        const_comp*=v;
+        return *this;
+      }
+      ///Division with a constant
+      Expr &operator/=(const Value &c) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second/=c;
+        const_comp/=c;
+        return *this;
+      }
+
+      ///Iterator over the expression
+
+      ///The iterator iterates over the terms of the expression.
+      ///
+      ///\code
+      ///double s=0;
+      ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * primal(i);
+      ///\endcode
+      class CoeffIt {
+      private:
+
+        std::map<int, Value>::iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+
+        /// Sets the iterator to the first term of the expression.
+        ///
+        CoeffIt(Expr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the column of the term
+        operator Col() const {
+          return colFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        Value& operator*() { return _it->second; }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+        /// Next term
+
+        /// Assign the iterator to the next term.
+        ///
+        CoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+      /// Const iterator over the expression
+
+      ///The iterator iterates over the terms of the expression.
+      ///
+      ///\code
+      ///double s=0;
+      ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
+      ///  s+=*i * primal(i);
+      ///\endcode
+      class ConstCoeffIt {
+      private:
+
+        std::map<int, Value>::const_iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+
+        /// Sets the iterator to the first term of the expression.
+        ///
+        ConstCoeffIt(const Expr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the column of the term
+        operator Col() const {
+          return colFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+
+        /// Assign the iterator to the next term.
+        ///
+        ConstCoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+    };
+
+    ///Linear constraint
+
+    ///This data stucture represents a linear constraint in the LP.
+    ///Basically it is a linear expression with a lower or an upper bound
+    ///(or both). These parts of the constraint can be obtained by the member
+    ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
+    ///respectively.
+    ///There are two ways to construct a constraint.
+    ///- You can set the linear expression and the bounds directly
+    ///  by the functions above.
+    ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
+    ///  are defined between expressions, or even between constraints whenever
+    ///  it makes sense. Therefore if \c e and \c f are linear expressions and
+    ///  \c s and \c t are numbers, then the followings are valid expressions
+    ///  and thus they can be used directly e.g. in \ref addRow() whenever
+    ///  it makes sense.
+    ///\code
+    ///  e<=s
+    ///  e<=f
+    ///  e==f
+    ///  s<=e<=t
+    ///  e>=t
+    ///\endcode
+    ///\warning The validity of a constraint is checked only at run
+    ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
+    ///compile, but will fail an assertion.
+    class Constr
+    {
+    public:
+      typedef LpBase::Expr Expr;
+      typedef Expr::Key Key;
+      typedef Expr::Value Value;
+
+    protected:
+      Expr _expr;
+      Value _lb,_ub;
+    public:
+      ///\e
+      Constr() : _expr(), _lb(NaN), _ub(NaN) {}
+      ///\e
+      Constr(Value lb, const Expr &e, Value ub) :
+        _expr(e), _lb(lb), _ub(ub) {}
+      Constr(const Expr &e) :
+        _expr(e), _lb(NaN), _ub(NaN) {}
+      ///\e
+      void clear()
+      {
+        _expr.clear();
+        _lb=_ub=NaN;
+      }
+
+      ///Reference to the linear expression
+      Expr &expr() { return _expr; }
+      ///Cont reference to the linear expression
+      const Expr &expr() const { return _expr; }
+      ///Reference to the lower bound.
+
+      ///\return
+      ///- \ref INF "INF": the constraint is lower unbounded.
+      ///- \ref NaN "NaN": lower bound has not been set.
+      ///- finite number: the lower bound
+      Value &lowerBound() { return _lb; }
+      ///The const version of \ref lowerBound()
+      const Value &lowerBound() const { return _lb; }
+      ///Reference to the upper bound.
+
+      ///\return
+      ///- \ref INF "INF": the constraint is upper unbounded.
+      ///- \ref NaN "NaN": upper bound has not been set.
+      ///- finite number: the upper bound
+      Value &upperBound() { return _ub; }
+      ///The const version of \ref upperBound()
+      const Value &upperBound() const { return _ub; }
+      ///Is the constraint lower bounded?
+      bool lowerBounded() const {
+        return _lb != -INF && !isNaN(_lb);
+      }
+      ///Is the constraint upper bounded?
+      bool upperBounded() const {
+        return _ub != INF && !isNaN(_ub);
+      }
+
+    };
+
+    ///Linear expression of rows
+
+    ///This data structure represents a column of the matrix,
+    ///thas is it strores a linear expression of the dual variables
+    ///(\ref Row "Row"s).
+    ///
+    ///There are several ways to access and modify the contents of this
+    ///container.
+    ///\code
+    ///e[v]=5;
+    ///e[v]+=12;
+    ///e.erase(v);
+    ///\endcode
+    ///or you can also iterate through its elements.
+    ///\code
+    ///double s=0;
+    ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
+    ///  s+=*i;
+    ///\endcode
+    ///(This code computes the sum of all coefficients).
+    ///- Numbers (<tt>double</tt>'s)
+    ///and variables (\ref Row "Row"s) directly convert to an
+    ///\ref DualExpr and the usual linear operations are defined, so
+    ///\code
+    ///v+w
+    ///2*v-3.12*(v-w/2)
+    ///v*2.1+(3*v+(v*12+w)*3)/2
+    ///\endcode
+    ///are valid \ref DualExpr dual expressions.
+    ///The usual assignment operations are also defined.
+    ///\code
+    ///e=v+w;
+    ///e+=2*v-3.12*(v-w/2);
+    ///e*=3.4;
+    ///e/=5;
+    ///\endcode
+    ///
+    ///\sa Expr
+    class DualExpr {
+      friend class LpBase;
+    public:
+      /// The key type of the expression
+      typedef LpBase::Row Key;
+      /// The value type of the expression
+      typedef LpBase::Value Value;
+
+    protected:
+      std::map<int, Value> comps;
+
+    public:
+      typedef True SolverExpr;
+      /// Default constructor
+
+      /// Construct an empty expression, the coefficients are
+      /// initialized to zero.
+      DualExpr() {}
+      /// Construct an expression from a row
+
+      /// Construct an expression, which has a term with \c r dual
+      /// variable and 1.0 coefficient.
+      DualExpr(const Row &r) {
+        typedef std::map<int, Value>::value_type pair_type;
+        comps.insert(pair_type(id(r), 1));
+      }
+      /// Returns the coefficient of the row
+      Value operator[](const Row& r) const {
+        std::map<int, Value>::const_iterator it = comps.find(id(r));
+        if (it != comps.end()) {
+          return it->second;
+        } else {
+          return 0;
+        }
+      }
+      /// Returns the coefficient of the row
+      Value& operator[](const Row& r) {
+        return comps[id(r)];
+      }
+      /// Sets the coefficient of the row
+      void set(const Row &r, const Value &v) {
+        if (v != 0.0) {
+          typedef std::map<int, Value>::value_type pair_type;
+          comps.insert(pair_type(id(r), v));
+        } else {
+          comps.erase(id(r));
+        }
+      }
+      /// \brief Removes the coefficients which's absolute value does
+      /// not exceed \c epsilon.
+      void simplify(Value epsilon = 0.0) {
+        std::map<int, Value>::iterator it=comps.begin();
+        while (it != comps.end()) {
+          std::map<int, Value>::iterator jt=it;
+          ++jt;
+          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
+          it=jt;
+        }
+      }
+
+      void simplify(Value epsilon = 0.0) const {
+        const_cast<DualExpr*>(this)->simplify(epsilon);
+      }
+
+      ///Sets all coefficients to 0.
+      void clear() {
+        comps.clear();
+      }
+      ///Compound assignment
+      DualExpr &operator+=(const DualExpr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]+=it->second;
+        return *this;
+      }
+      ///Compound assignment
+      DualExpr &operator-=(const DualExpr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]-=it->second;
+        return *this;
+      }
+      ///Multiply with a constant
+      DualExpr &operator*=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second*=v;
+        return *this;
+      }
+      ///Division with a constant
+      DualExpr &operator/=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second/=v;
+        return *this;
+      }
+
+      ///Iterator over the expression
+
+      ///The iterator iterates over the terms of the expression.
+      ///
+      ///\code
+      ///double s=0;
+      ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * dual(i);
+      ///\endcode
+      class CoeffIt {
+      private:
+
+        std::map<int, Value>::iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+
+        /// Sets the iterator to the first term of the expression.
+        ///
+        CoeffIt(DualExpr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the row of the term
+        operator Row() const {
+          return rowFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        Value& operator*() { return _it->second; }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+
+        /// Assign the iterator to the next term.
+        ///
+        CoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+      ///Iterator over the expression
+
+      ///The iterator iterates over the terms of the expression.
+      ///
+      ///\code
+      ///double s=0;
+      ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * dual(i);
+      ///\endcode
+      class ConstCoeffIt {
+      private:
+
+        std::map<int, Value>::const_iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+
+        /// Sets the iterator to the first term of the expression.
+        ///
+        ConstCoeffIt(const DualExpr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the row of the term
+        operator Row() const {
+          return rowFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+
+        /// Assign the iterator to the next term.
+        ///
+        ConstCoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+    };
+
+
+  protected:
+
+    class InsertIterator {
+    private:
+
+      std::map<int, Value>& _host;
+      const _solver_bits::VarIndex& _index;
+
+    public:
+
+      typedef std::output_iterator_tag iterator_category;
+      typedef void difference_type;
+      typedef void value_type;
+      typedef void reference;
+      typedef void pointer;
+
+      InsertIterator(std::map<int, Value>& host,
+                   const _solver_bits::VarIndex& index)
+        : _host(host), _index(index) {}
+
+      InsertIterator& operator=(const std::pair<int, Value>& value) {
+        typedef std::map<int, Value>::value_type pair_type;
+        _host.insert(pair_type(_index[value.first], value.second));
+        return *this;
+      }
+
+      InsertIterator& operator*() { return *this; }
+      InsertIterator& operator++() { return *this; }
+      InsertIterator operator++(int) { return *this; }
+
+    };
+
+    class ExprIterator {
+    private:
+      std::map<int, Value>::const_iterator _host_it;
+      const _solver_bits::VarIndex& _index;
+    public:
+
+      typedef std::bidirectional_iterator_tag iterator_category;
+      typedef std::ptrdiff_t difference_type;
+      typedef const std::pair<int, Value> value_type;
+      typedef value_type reference;
+
+      class pointer {
+      public:
+        pointer(value_type& _value) : value(_value) {}
+        value_type* operator->() { return &value; }
+      private:
+        value_type value;
+      };
+
+      ExprIterator(const std::map<int, Value>::const_iterator& host_it,
+                   const _solver_bits::VarIndex& index)
+        : _host_it(host_it), _index(index) {}
+
+      reference operator*() {
+        return std::make_pair(_index(_host_it->first), _host_it->second);
+      }
+
+      pointer operator->() {
+        return pointer(operator*());
+      }
+
+      ExprIterator& operator++() { ++_host_it; return *this; }
+      ExprIterator operator++(int) {
+        ExprIterator tmp(*this); ++_host_it; return tmp;
+      }
+
+      ExprIterator& operator--() { --_host_it; return *this; }
+      ExprIterator operator--(int) {
+        ExprIterator tmp(*this); --_host_it; return tmp;
+      }
+
+      bool operator==(const ExprIterator& it) const {
+        return _host_it == it._host_it;
+      }
+
+      bool operator!=(const ExprIterator& it) const {
+        return _host_it != it._host_it;
+      }
+
+    };
+
+  protected:
+
+    //Abstract virtual functions
+
+    virtual int _addColId(int col) { return cols.addIndex(col); }
+    virtual int _addRowId(int row) { return rows.addIndex(row); }
+
+    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
+    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
+
+    virtual int _addCol() = 0;
+    virtual int _addRow() = 0;
+
+    virtual 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;
+
+    virtual void _getColName(int col, std::string& name) const = 0;
+    virtual void _setColName(int col, const std::string& name) = 0;
+    virtual int _colByName(const std::string& name) const = 0;
+
+    virtual void _getRowName(int row, std::string& name) const = 0;
+    virtual void _setRowName(int row, const std::string& name) = 0;
+    virtual int _rowByName(const std::string& name) const = 0;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
+    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
+    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
+
+    virtual void _setCoeff(int row, int col, Value value) = 0;
+    virtual Value _getCoeff(int row, int col) const = 0;
+
+    virtual void _setColLowerBound(int i, Value value) = 0;
+    virtual Value _getColLowerBound(int i) const = 0;
+
+    virtual void _setColUpperBound(int i, Value value) = 0;
+    virtual Value _getColUpperBound(int i) const = 0;
+
+    virtual void _setRowLowerBound(int i, Value value) = 0;
+    virtual Value _getRowLowerBound(int i) const = 0;
+
+    virtual void _setRowUpperBound(int i, Value value) = 0;
+    virtual Value _getRowUpperBound(int i) const = 0;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
+    virtual void _getObjCoeffs(InsertIterator b) const = 0;
+
+    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
+    virtual Value _getObjCoeff(int i) const = 0;
+
+    virtual void _setSense(Sense) = 0;
+    virtual Sense _getSense() const = 0;
+
+    virtual void _clear() = 0;
+
+    virtual const char* _solverName() const = 0;
+
+    virtual void _messageLevel(MessageLevel level) = 0;
+
+    //Own protected stuff
+
+    //Constant component of the objective function
+    Value obj_const_comp;
+
+    LpBase() : rows(), cols(), obj_const_comp(0) {}
+
+  public:
+
+    ///Unsupported file format exception
+    class UnsupportedFormatError : public Exception
+    {
+      std::string _format;
+      mutable std::string _what;
+    public:
+      explicit UnsupportedFormatError(std::string format) throw()
+        : _format(format) { }
+      virtual ~UnsupportedFormatError() throw() {}
+      virtual const char* what() const throw() {
+        try {
+          _what.clear();
+          std::ostringstream oss;
+          oss << "lemon::UnsupportedFormatError: " << _format;
+          _what = oss.str();
+        }
+        catch (...) {}
+        if (!_what.empty()) return _what.c_str();
+        else return "lemon::UnsupportedFormatError";
+      }
+    };
+
+  protected:
+    virtual void _write(std::string, std::string format) const
+    {
+      throw UnsupportedFormatError(format);
+    }
+
+  public:
+
+    /// Virtual destructor
+    virtual ~LpBase() {}
+
+    ///Gives back the name of the solver.
+    const char* solverName() const {return _solverName();}
+
+    ///\name Build Up and Modify the LP
+
+    ///@{
+
+    ///Add a new empty column (i.e a new variable) to the LP
+    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
+
+    ///\brief Adds several new columns (i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument and fills
+    ///its elements with new columns (i.e. variables)
+    ///\param t can be
+    ///- a standard STL compatible iterable container with
+    ///\ref Col as its \c values_type like
+    ///\code
+    ///std::vector<LpBase::Col>
+    ///std::list<LpBase::Col>
+    ///\endcode
+    ///- a standard STL compatible iterable container with
+    ///\ref Col as its \c mapped_type like
+    ///\code
+    ///std::map<AnyType,LpBase::Col>
+    ///\endcode
+    ///- an iterable lemon \ref concepts::WriteMap "write map" like
+    ///\code
+    ///ListGraph::NodeMap<LpBase::Col>
+    ///ListGraph::ArcMap<LpBase::Col>
+    ///\endcode
+    ///\return The number of the created column.
+#ifdef DOXYGEN
+    template<class T>
+    int addColSet(T &t) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,int>::type
+    addColSet(T &t,dummy<0> = 0) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       int>::type
+    addColSet(T &t,dummy<1> = 1) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        i->second=addCol();
+        s++;
+      }
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       int>::type
+    addColSet(T &t,dummy<2> = 2) {
+      int s=0;
+      for(typename T::MapIt i(t); i!=INVALID; ++i)
+        {
+          i.set(addCol());
+          s++;
+        }
+      return s;
+    }
+#endif
+
+    ///Set a column (i.e a dual constraint) of the LP
+
+    ///\param c is the column to be modified
+    ///\param e is a dual linear expression (see \ref DualExpr)
+    ///a better one.
+    void col(Col c, const DualExpr &e) {
+      e.simplify();
+      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
+                    ExprIterator(e.comps.end(), rows));
+    }
+
+    ///Get a column (i.e a dual constraint) of the LP
+
+    ///\param c is the column to get
+    ///\return the dual expression associated to the column
+    DualExpr col(Col c) const {
+      DualExpr e;
+      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
+      return e;
+    }
+
+    ///Add a new column to the LP
+
+    ///\param e is a dual linear expression (see \ref DualExpr)
+    ///\param o is the corresponding component of the objective
+    ///function. It is 0 by default.
+    ///\return The created column.
+    Col addCol(const DualExpr &e, Value o = 0) {
+      Col c=addCol();
+      col(c,e);
+      objCoeff(c,o);
+      return c;
+    }
+
+    ///Add a new empty row (i.e a new constraint) to the LP
+
+    ///This function adds a new empty row (i.e a new constraint) to the LP.
+    ///\return The created row
+    Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
+
+    ///\brief Add several new rows (i.e constraints) at once
+    ///
+    ///This magic function takes a container as its argument and fills
+    ///its elements with new row (i.e. variables)
+    ///\param t can be
+    ///- a standard STL compatible iterable container with
+    ///\ref Row as its \c values_type like
+    ///\code
+    ///std::vector<LpBase::Row>
+    ///std::list<LpBase::Row>
+    ///\endcode
+    ///- a standard STL compatible iterable container with
+    ///\ref Row as its \c mapped_type like
+    ///\code
+    ///std::map<AnyType,LpBase::Row>
+    ///\endcode
+    ///- an iterable lemon \ref concepts::WriteMap "write map" like
+    ///\code
+    ///ListGraph::NodeMap<LpBase::Row>
+    ///ListGraph::ArcMap<LpBase::Row>
+    ///\endcode
+    ///\return The number of rows created.
+#ifdef DOXYGEN
+    template<class T>
+    int addRowSet(T &t) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpRow,int>::type
+    addRowSet(T &t, dummy<0> = 0) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
+    addRowSet(T &t, dummy<1> = 1) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        i->second=addRow();
+        s++;
+      }
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
+    addRowSet(T &t, dummy<2> = 2) {
+      int s=0;
+      for(typename T::MapIt i(t); i!=INVALID; ++i)
+        {
+          i.set(addRow());
+          s++;
+        }
+      return s;
+    }
+#endif
+
+    ///Set a row (i.e a constraint) of the LP
+
+    ///\param r is the row to be modified
+    ///\param l is lower bound (-\ref INF means no bound)
+    ///\param e is a linear expression (see \ref Expr)
+    ///\param u is the upper bound (\ref INF means no bound)
+    void row(Row r, Value l, const Expr &e, Value u) {
+      e.simplify();
+      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
+                    ExprIterator(e.comps.end(), cols));
+      _setRowLowerBound(rows(id(r)),l - *e);
+      _setRowUpperBound(rows(id(r)),u - *e);
+    }
+
+    ///Set a row (i.e a constraint) of the LP
+
+    ///\param r is the row to be modified
+    ///\param c is a linear expression (see \ref Constr)
+    void row(Row r, const Constr &c) {
+      row(r, c.lowerBounded()?c.lowerBound():-INF,
+          c.expr(), c.upperBounded()?c.upperBound():INF);
+    }
+
+
+    ///Get a row (i.e a constraint) of the LP
+
+    ///\param r is the row to get
+    ///\return the expression associated to the row
+    Expr row(Row r) const {
+      Expr e;
+      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
+      return e;
+    }
+
+    ///Add a new row (i.e a new constraint) to the LP
+
+    ///\param l is the lower bound (-\ref INF means no bound)
+    ///\param e is a linear expression (see \ref Expr)
+    ///\param u is the upper bound (\ref INF means no bound)
+    ///\return The created row.
+    Row addRow(Value l,const Expr &e, Value u) {
+      Row r;
+      e.simplify();
+      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
+                                ExprIterator(e.comps.end(), cols), u - *e));
+      return r;
+    }
+
+    ///Add a new row (i.e a new constraint) to the LP
+
+    ///\param c is a linear expression (see \ref Constr)
+    ///\return The created row.
+    Row addRow(const Constr &c) {
+      Row r;
+      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;
+    }
+    ///Erase a column (i.e a variable) from the LP
+
+    ///\param c is the column to be deleted
+    void erase(Col c) {
+      _eraseCol(cols(id(c)));
+      _eraseColId(cols(id(c)));
+    }
+    ///Erase a row (i.e a constraint) from the LP
+
+    ///\param r is the row to be deleted
+    void erase(Row r) {
+      _eraseRow(rows(id(r)));
+      _eraseRowId(rows(id(r)));
+    }
+
+    /// Get the name of a column
+
+    ///\param c is the coresponding column
+    ///\return The name of the colunm
+    std::string colName(Col c) const {
+      std::string name;
+      _getColName(cols(id(c)), name);
+      return name;
+    }
+
+    /// Set the name of a column
+
+    ///\param c is the coresponding column
+    ///\param name The name to be given
+    void colName(Col c, const std::string& name) {
+      _setColName(cols(id(c)), name);
+    }
+
+    /// Get the column by its name
+
+    ///\param name The name of the column
+    ///\return the proper column or \c INVALID
+    Col colByName(const std::string& name) const {
+      int k = _colByName(name);
+      return k != -1 ? Col(cols[k]) : Col(INVALID);
+    }
+
+    /// Get the name of a row
+
+    ///\param r is the coresponding row
+    ///\return The name of the row
+    std::string rowName(Row r) const {
+      std::string name;
+      _getRowName(rows(id(r)), name);
+      return name;
+    }
+
+    /// Set the name of a row
+
+    ///\param r is the coresponding row
+    ///\param name The name to be given
+    void rowName(Row r, const std::string& name) {
+      _setRowName(rows(id(r)), name);
+    }
+
+    /// Get the row by its name
+
+    ///\param name The name of the row
+    ///\return the proper row or \c INVALID
+    Row rowByName(const std::string& name) const {
+      int k = _rowByName(name);
+      return k != -1 ? Row(rows[k]) : Row(INVALID);
+    }
+
+    /// Set an element of the coefficient matrix of the LP
+
+    ///\param r is the row of the element to be modified
+    ///\param c is the column of the element to be modified
+    ///\param val is the new value of the coefficient
+    void coeff(Row r, Col c, Value val) {
+      _setCoeff(rows(id(r)),cols(id(c)), val);
+    }
+
+    /// Get an element of the coefficient matrix of the LP
+
+    ///\param r is the row of the element
+    ///\param c is the column of the element
+    ///\return the corresponding coefficient
+    Value coeff(Row r, Col c) const {
+      return _getCoeff(rows(id(r)),cols(id(c)));
+    }
+
+    /// Set the lower bound of a column (i.e a variable)
+
+    /// The lower bound of a variable (column) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void colLowerBound(Col c, Value value) {
+      _setColLowerBound(cols(id(c)),value);
+    }
+
+    /// Get the lower bound of a column (i.e a variable)
+
+    /// This function returns the lower bound for column (variable) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The lower bound for column \c c
+    Value colLowerBound(Col c) const {
+      return _getColLowerBound(cols(id(c)));
+    }
+
+    ///\brief Set the lower bound of  several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    ///The lower bound of a variable (column) has to be given by an
+    ///extended number of type Value, i.e. a finite number of type
+    ///Value or -\ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colLowerBound(T &t, Value value) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,void>::type
+    colLowerBound(T &t, Value value,dummy<0> = 0) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colLowerBound(*i, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       void>::type
+    colLowerBound(T &t, Value value,dummy<1> = 1) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colLowerBound(i->second, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       void>::type
+    colLowerBound(T &t, Value value,dummy<2> = 2) {
+      for(typename T::MapIt i(t); i!=INVALID; ++i){
+        colLowerBound(*i, value);
+      }
+    }
+#endif
+
+    /// Set the upper bound of a column (i.e a variable)
+
+    /// The upper bound of a variable (column) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    void colUpperBound(Col c, Value value) {
+      _setColUpperBound(cols(id(c)),value);
+    };
+
+    /// Get the upper bound of a column (i.e a variable)
+
+    /// This function returns the upper bound for column (variable) \c c
+    /// (this might be \ref INF as well).
+    /// \return The upper bound for column \c c
+    Value colUpperBound(Col c) const {
+      return _getColUpperBound(cols(id(c)));
+    }
+
+    ///\brief Set the upper bound of  several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    ///The upper bound of a variable (column) has to be given by an
+    ///extended number of type Value, i.e. a finite number of type
+    ///Value or \ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colUpperBound(T &t, Value value) { return 0;}
+#else
+    template<class T1>
+    typename enable_if<typename T1::value_type::LpCol,void>::type
+    colUpperBound(T1 &t, Value value,dummy<0> = 0) {
+      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
+        colUpperBound(*i, value);
+      }
+    }
+    template<class T1>
+    typename enable_if<typename T1::value_type::second_type::LpCol,
+                       void>::type
+    colUpperBound(T1 &t, Value value,dummy<1> = 1) {
+      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
+        colUpperBound(i->second, value);
+      }
+    }
+    template<class T1>
+    typename enable_if<typename T1::MapIt::Value::LpCol,
+                       void>::type
+    colUpperBound(T1 &t, Value value,dummy<2> = 2) {
+      for(typename T1::MapIt i(t); i!=INVALID; ++i){
+        colUpperBound(*i, value);
+      }
+    }
+#endif
+
+    /// Set the lower and the upper bounds of a column (i.e a variable)
+
+    /// The lower and the upper bounds of
+    /// a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value, -\ref INF or \ref INF.
+    void colBounds(Col c, Value lower, Value upper) {
+      _setColLowerBound(cols(id(c)),lower);
+      _setColUpperBound(cols(id(c)),upper);
+    }
+
+    ///\brief Set the lower and the upper bound of several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    /// The lower and the upper bounds of
+    /// a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value, -\ref INF or \ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colBounds(T &t, Value lower, Value upper) { return 0;}
+#else
+    template<class T2>
+    typename enable_if<typename T2::value_type::LpCol,void>::type
+    colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
+      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
+        colBounds(*i, lower, upper);
+      }
+    }
+    template<class T2>
+    typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
+    colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
+      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
+        colBounds(i->second, lower, upper);
+      }
+    }
+    template<class T2>
+    typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
+    colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
+      for(typename T2::MapIt i(t); i!=INVALID; ++i){
+        colBounds(*i, lower, upper);
+      }
+    }
+#endif
+
+    /// Set the lower bound of a row (i.e a constraint)
+
+    /// The lower bound of a constraint (row) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void rowLowerBound(Row r, Value value) {
+      _setRowLowerBound(rows(id(r)),value);
+    }
+
+    /// Get the lower bound of a row (i.e a constraint)
+
+    /// This function returns the lower bound for row (constraint) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The lower bound for row \c r
+    Value rowLowerBound(Row r) const {
+      return _getRowLowerBound(rows(id(r)));
+    }
+
+    /// Set the upper bound of a row (i.e a constraint)
+
+    /// The upper bound of a constraint (row) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void rowUpperBound(Row r, Value value) {
+      _setRowUpperBound(rows(id(r)),value);
+    }
+
+    /// Get the upper bound of a row (i.e a constraint)
+
+    /// This function returns the upper bound for row (constraint) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The upper bound for row \c r
+    Value rowUpperBound(Row r) const {
+      return _getRowUpperBound(rows(id(r)));
+    }
+
+    ///Set an element of the objective function
+    void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
+
+    ///Get an element of the objective function
+    Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
+
+    ///Set the objective function
+
+    ///\param e is a linear expression of type \ref Expr.
+    ///
+    void obj(const Expr& e) {
+      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
+                    ExprIterator(e.comps.end(), cols));
+      obj_const_comp = *e;
+    }
+
+    ///Get the objective function
+
+    ///\return the objective function as a linear expression of type
+    ///Expr.
+    Expr obj() const {
+      Expr e;
+      _getObjCoeffs(InsertIterator(e.comps, cols));
+      *e = obj_const_comp;
+      return e;
+    }
+
+
+    ///Set the direction of optimization
+    void sense(Sense sense) { _setSense(sense); }
+
+    ///Query the direction of the optimization
+    Sense sense() const {return _getSense(); }
+
+    ///Set the sense to maximization
+    void max() { _setSense(MAX); }
+
+    ///Set the sense to maximization
+    void min() { _setSense(MIN); }
+
+    ///Clear the problem
+    void clear() { _clear(); rows.clear(); cols.clear(); }
+
+    /// Set the message level of the solver
+    void messageLevel(MessageLevel level) { _messageLevel(level); }
+
+    /// Write the problem to a file in the given format
+
+    /// This function writes the problem to a file in the given format.
+    /// Different solver backends may support different formats.
+    /// Trying to write in an unsupported format will trigger
+    /// \ref UnsupportedFormatError. For the supported formats,
+    /// visit the documentation of the base class of the related backends
+    /// (\ref CplexBase, \ref GlpkBase etc.)
+    /// \param file The file path
+    /// \param format The output file format.
+    void write(std::string file, std::string format = "MPS") const
+    {
+      _write(file.c_str(),format.c_str());
+    }
+
+    ///@}
+
+  };
+
+  /// Addition
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(a);
+    tmp+=b;
+    return tmp;
+  }
+  ///Substraction
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(a);
+    tmp-=b;
+    return tmp;
+  }
+  ///Multiply with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
+    LpBase::Expr tmp(a);
+    tmp*=b;
+    return tmp;
+  }
+
+  ///Multiply with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(b);
+    tmp*=a;
+    return tmp;
+  }
+  ///Divide with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
+    LpBase::Expr tmp(a);
+    tmp/=b;
+    return tmp;
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, f - e, LpBase::NaN);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Value &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(e, f, LpBase::NaN);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(LpBase::NaN, e, f);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, e - f, LpBase::NaN);
+  }
+
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Value &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(LpBase::NaN, f, e);
+  }
+
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(f, e, LpBase::NaN);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator==(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(f, e, f);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator==(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, f - e, 0);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Value &n,
+                                   const LpBase::Constr &c) {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
+    tmp.lowerBound()=n;
+    return tmp;
+  }
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Constr &c,
+                                   const LpBase::Value &n)
+  {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
+    tmp.upperBound()=n;
+    return tmp;
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Value &n,
+                                   const LpBase::Constr &c) {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
+    tmp.upperBound()=n;
+    return tmp;
+  }
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Constr &c,
+                                   const LpBase::Value &n)
+  {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
+    tmp.lowerBound()=n;
+    return tmp;
+  }
+
+  ///Addition
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(a);
+    tmp+=b;
+    return tmp;
+  }
+  ///Substraction
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(a);
+    tmp-=b;
+    return tmp;
+  }
+  ///Multiply with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
+                                    const LpBase::Value &b) {
+    LpBase::DualExpr tmp(a);
+    tmp*=b;
+    return tmp;
+  }
+
+  ///Multiply with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator*(const LpBase::Value &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(b);
+    tmp*=a;
+    return tmp;
+  }
+  ///Divide with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
+                                    const LpBase::Value &b) {
+    LpBase::DualExpr tmp(a);
+    tmp/=b;
+    return tmp;
+  }
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Common base class for LP solvers
+  ///
+  /// This class is an abstract base class for LP solvers. This class
+  /// provides a full interface for set and modify an LP problem,
+  /// solve it and retrieve the solution. You can use one of the
+  /// descendants as a concrete implementation, or the \c Lp
+  /// default LP solver. However, if you would like to handle LP
+  /// solvers as reference or pointer in a generic way, you can use
+  /// this class directly.
+  class LpSolver : virtual public LpBase {
+  public:
+
+    /// The problem types for primal and dual problems
+    enum ProblemType {
+      /// = 0. Feasible solution hasn't been found (but may exist).
+      UNDEFINED = 0,
+      /// = 1. The problem has no feasible solution.
+      INFEASIBLE = 1,
+      /// = 2. Feasible solution found.
+      FEASIBLE = 2,
+      /// = 3. Optimal solution exists and found.
+      OPTIMAL = 3,
+      /// = 4. The cost function is unbounded.
+      UNBOUNDED = 4
+    };
+
+    ///The basis status of variables
+    enum VarStatus {
+      /// The variable is in the basis
+      BASIC,
+      /// The variable is free, but not basic
+      FREE,
+      /// The variable has active lower bound
+      LOWER,
+      /// The variable has active upper bound
+      UPPER,
+      /// The variable is non-basic and fixed
+      FIXED
+    };
+
+  protected:
+
+    virtual SolveExitStatus _solve() = 0;
+
+    virtual Value _getPrimal(int i) const = 0;
+    virtual Value _getDual(int i) const = 0;
+
+    virtual Value _getPrimalRay(int i) const = 0;
+    virtual Value _getDualRay(int i) const = 0;
+
+    virtual Value _getPrimalValue() const = 0;
+
+    virtual VarStatus _getColStatus(int i) const = 0;
+    virtual VarStatus _getRowStatus(int i) const = 0;
+
+    virtual ProblemType _getPrimalType() const = 0;
+    virtual ProblemType _getDualType() const = 0;
+
+  public:
+
+    ///Allocate a new LP problem instance
+    virtual LpSolver* newSolver() const = 0;
+    ///Make a copy of the LP problem
+    virtual LpSolver* cloneSolver() const = 0;
+
+    ///\name Solve the LP
+
+    ///@{
+
+    ///\e Solve the LP problem at hand
+    ///
+    ///\return The result of the optimization procedure. Possible
+    ///values and their meanings can be found in the documentation of
+    ///\ref SolveExitStatus.
+    SolveExitStatus solve() { return _solve(); }
+
+    ///@}
+
+    ///\name Obtain the Solution
+
+    ///@{
+
+    /// The type of the primal problem
+    ProblemType primalType() const {
+      return _getPrimalType();
+    }
+
+    /// The type of the dual problem
+    ProblemType dualType() const {
+      return _getDualType();
+    }
+
+    /// Return the primal value of the column
+
+    /// Return the primal value of the column.
+    /// \pre The problem is solved.
+    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
+
+    /// Return the primal value of the expression
+
+    /// Return the primal value of the expression, i.e. the dot
+    /// product of the primal solution and the expression.
+    /// \pre The problem is solved.
+    Value primal(const Expr& e) const {
+      double res = *e;
+      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
+        res += *c * primal(c);
+      }
+      return res;
+    }
+    /// Returns a component of the primal ray
+
+    /// The primal ray is solution of the modified primal problem,
+    /// where we change each finite bound to 0, and we looking for a
+    /// negative objective value in case of minimization, and positive
+    /// objective value for maximization. If there is such solution,
+    /// that proofs the unsolvability of the dual problem, and if a
+    /// feasible primal solution exists, then the unboundness of
+    /// primal problem.
+    ///
+    /// \pre The problem is solved and the dual problem is infeasible.
+    /// \note Some solvers does not provide primal ray calculation
+    /// functions.
+    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
+
+    /// Return the dual value of the row
+
+    /// Return the dual value of the row.
+    /// \pre The problem is solved.
+    Value dual(Row r) const { return _getDual(rows(id(r))); }
+
+    /// Return the dual value of the dual expression
+
+    /// Return the dual value of the dual expression, i.e. the dot
+    /// product of the dual solution and the dual expression.
+    /// \pre The problem is solved.
+    Value dual(const DualExpr& e) const {
+      double res = 0.0;
+      for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
+        res += *r * dual(r);
+      }
+      return res;
+    }
+
+    /// Returns a component of the dual ray
+
+    /// The dual ray is solution of the modified primal problem, where
+    /// we change each finite bound to 0 (i.e. the objective function
+    /// coefficients in the primal problem), and we looking for a
+    /// ositive objective value. If there is such solution, that
+    /// proofs the unsolvability of the primal problem, and if a
+    /// feasible dual solution exists, then the unboundness of
+    /// dual problem.
+    ///
+    /// \pre The problem is solved and the primal problem is infeasible.
+    /// \note Some solvers does not provide dual ray calculation
+    /// functions.
+    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
+
+    /// Return the basis status of the column
+
+    /// \see VarStatus
+    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
+
+    /// Return the basis status of the row
+
+    /// \see VarStatus
+    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
+
+    ///The value of the objective function
+
+    ///\return
+    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
+    /// of the primal problem, depending on whether we minimize or maximize.
+    ///- \ref NaN if no primal solution is found.
+    ///- The (finite) objective value if an optimal solution is found.
+    Value primal() const { return _getPrimalValue()+obj_const_comp;}
+    ///@}
+
+  protected:
+
+  };
+
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Common base class for MIP solvers
+  ///
+  /// This class is an abstract base class for MIP solvers. This class
+  /// provides a full interface for set and modify an MIP problem,
+  /// solve it and retrieve the solution. You can use one of the
+  /// descendants as a concrete implementation, or the \c Lp
+  /// default MIP solver. However, if you would like to handle MIP
+  /// solvers as reference or pointer in a generic way, you can use
+  /// this class directly.
+  class MipSolver : virtual public LpBase {
+  public:
+
+    /// The problem types for MIP problems
+    enum ProblemType {
+      /// = 0. Feasible solution hasn't been found (but may exist).
+      UNDEFINED = 0,
+      /// = 1. The problem has no feasible solution.
+      INFEASIBLE = 1,
+      /// = 2. Feasible solution found.
+      FEASIBLE = 2,
+      /// = 3. Optimal solution exists and found.
+      OPTIMAL = 3,
+      /// = 4. The cost function is unbounded.
+      ///The Mip or at least the relaxed problem is unbounded.
+      UNBOUNDED = 4
+    };
+
+    ///Allocate a new MIP problem instance
+    virtual MipSolver* newSolver() const = 0;
+    ///Make a copy of the MIP problem
+    virtual MipSolver* cloneSolver() const = 0;
+
+    ///\name Solve the MIP
+
+    ///@{
+
+    /// Solve the MIP problem at hand
+    ///
+    ///\return The result of the optimization procedure. Possible
+    ///values and their meanings can be found in the documentation of
+    ///\ref SolveExitStatus.
+    SolveExitStatus solve() { return _solve(); }
+
+    ///@}
+
+    ///\name Set Column Type
+    ///@{
+
+    ///Possible variable (column) types (e.g. real, integer, binary etc.)
+    enum ColTypes {
+      /// = 0. Continuous variable (default).
+      REAL = 0,
+      /// = 1. Integer variable.
+      INTEGER = 1
+    };
+
+    ///Sets the type of the given column to the given type
+
+    ///Sets the type of the given column to the given type.
+    ///
+    void colType(Col c, ColTypes col_type) {
+      _setColType(cols(id(c)),col_type);
+    }
+
+    ///Gives back the type of the column.
+
+    ///Gives back the type of the column.
+    ///
+    ColTypes colType(Col c) const {
+      return _getColType(cols(id(c)));
+    }
+    ///@}
+
+    ///\name Obtain the Solution
+
+    ///@{
+
+    /// The type of the MIP problem
+    ProblemType type() const {
+      return _getType();
+    }
+
+    /// Return the value of the row in the solution
+
+    ///  Return the value of the row in the solution.
+    /// \pre The problem is solved.
+    Value sol(Col c) const { return _getSol(cols(id(c))); }
+
+    /// Return the value of the expression in the solution
+
+    /// Return the value of the expression in the solution, i.e. the
+    /// dot product of the solution and the expression.
+    /// \pre The problem is solved.
+    Value sol(const Expr& e) const {
+      double res = *e;
+      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
+        res += *c * sol(c);
+      }
+      return res;
+    }
+    ///The value of the objective function
+
+    ///\return
+    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
+    /// of the problem, depending on whether we minimize or maximize.
+    ///- \ref NaN if no primal solution is found.
+    ///- The (finite) objective value if an optimal solution is found.
+    Value solValue() const { return _getSolValue()+obj_const_comp;}
+    ///@}
+
+  protected:
+
+    virtual SolveExitStatus _solve() = 0;
+    virtual ColTypes _getColType(int col) const = 0;
+    virtual void _setColType(int col, ColTypes col_type) = 0;
+    virtual ProblemType _getType() const = 0;
+    virtual Value _getSol(int i) const = 0;
+    virtual Value _getSolValue() const = 0;
+
+  };
+
+
+
+} //namespace lemon
+
+#endif //LEMON_LP_BASE_H
diff --git a/lemon/lp_skeleton.cc b/lemon/lp_skeleton.cc
new file mode 100644
index 0000000..fc1c143
--- /dev/null
+++ b/lemon/lp_skeleton.cc
@@ -0,0 +1,143 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/lp_skeleton.h>
+
+///\file
+///\brief A skeleton file to implement LP solver interfaces
+namespace lemon {
+
+  int SkeletonSolverBase::_addCol()
+  {
+    return ++col_num;
+  }
+
+  int SkeletonSolverBase::_addRow()
+  {
+    return ++row_num;
+  }
+
+  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
+  {
+    return ++row_num;
+  }
+
+  void SkeletonSolverBase::_eraseCol(int) {}
+  void SkeletonSolverBase::_eraseRow(int) {}
+
+  void SkeletonSolverBase::_getColName(int, std::string &) const {}
+  void SkeletonSolverBase::_setColName(int, const std::string &) {}
+  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
+
+  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
+  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
+  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
+
+  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
+
+  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
+
+  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
+  { return 0; }
+
+  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
+
+  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setSense(Sense) {}
+  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
+  { return MIN; }
+
+  void SkeletonSolverBase::_clear() {
+    row_num = col_num = 0;
+  }
+
+  void SkeletonSolverBase::_messageLevel(MessageLevel) {}
+
+  void SkeletonSolverBase::_write(std::string, std::string) const {}
+
+  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
+
+  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
+
+  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
+
+  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
+  { return UNDEFINED; }
+
+  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
+  { return UNDEFINED; }
+
+  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
+  { return BASIC; }
+
+  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
+  { return BASIC; }
+
+  LpSkeleton* LpSkeleton::newSolver() const
+  { return static_cast<LpSkeleton*>(0); }
+
+  LpSkeleton* LpSkeleton::cloneSolver() const
+  { return static_cast<LpSkeleton*>(0); }
+
+  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
+
+  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
+  { return SOLVED; }
+
+  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
+  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
+
+  MipSkeleton::ProblemType MipSkeleton::_getType() const
+  { return UNDEFINED; }
+
+  MipSkeleton* MipSkeleton::newSolver() const
+  { return static_cast<MipSkeleton*>(0); }
+
+  MipSkeleton* MipSkeleton::cloneSolver() const
+  { return static_cast<MipSkeleton*>(0); }
+
+  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
+
+} //namespace lemon
+
diff --git a/lemon/lp_skeleton.h b/lemon/lp_skeleton.h
new file mode 100644
index 0000000..27285a4
--- /dev/null
+++ b/lemon/lp_skeleton.h
@@ -0,0 +1,234 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_SKELETON_H
+#define LEMON_LP_SKELETON_H
+
+#include <lemon/lp_base.h>
+
+///\file
+///\brief Skeleton file to implement LP/MIP solver interfaces
+///
+///The classes in this file do nothing, but they can serve as skeletons when
+///implementing an interface to new solvers.
+namespace lemon {
+
+  ///A skeleton class to implement LP/MIP solver base interface
+
+  ///This class does nothing, but it can serve as a skeleton when
+  ///implementing an interface to new solvers.
+  class SkeletonSolverBase : public virtual LpBase {
+    int col_num,row_num;
+
+  protected:
+
+    SkeletonSolverBase()
+      : col_num(-1), row_num(-1) {}
+
+    /// \e
+    virtual int _addCol();
+    /// \e
+    virtual int _addRow();
+    /// \e
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+    /// \e
+    virtual void _eraseCol(int i);
+    /// \e
+    virtual void _eraseRow(int i);
+
+    /// \e
+    virtual void _getColName(int col, std::string& name) const;
+    /// \e
+    virtual void _setColName(int col, const std::string& name);
+    /// \e
+    virtual int _colByName(const std::string& name) const;
+
+    /// \e
+    virtual void _getRowName(int row, std::string& name) const;
+    /// \e
+    virtual void _setRowName(int row, const std::string& name);
+    /// \e
+    virtual int _rowByName(const std::string& name) const;
+
+    /// \e
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+    /// \e
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    /// Set one element of the coefficient matrix
+    virtual void _setCoeff(int row, int col, Value value);
+
+    /// Get one element of the coefficient matrix
+    virtual Value _getCoeff(int row, int col) const;
+
+    /// The lower bound of a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual void _setColLowerBound(int i, Value value);
+    /// \e
+
+    /// The lower bound of a variable (column) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual Value _getColLowerBound(int i) const;
+
+    /// The upper bound of a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual void _setColUpperBound(int i, Value value);
+    /// \e
+
+    /// The upper bound of a variable (column) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual Value _getColUpperBound(int i) const;
+
+    /// The lower bound of a constraint (row) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual void _setRowLowerBound(int i, Value value);
+    /// \e
+
+    /// The lower bound of a constraint (row) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual Value _getRowLowerBound(int i) const;
+
+    /// The upper bound of a constraint (row) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual void _setRowUpperBound(int i, Value value);
+    /// \e
+
+    /// The upper bound of a constraint (row) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual Value _getRowUpperBound(int i) const;
+
+    /// \e
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    /// \e
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    /// \e
+    virtual Value _getObjCoeff(int i) const;
+
+    ///\e
+    virtual void _setSense(Sense);
+    ///\e
+    virtual Sense _getSense() const;
+
+    ///\e
+    virtual void _clear();
+
+    ///\e
+    virtual void _messageLevel(MessageLevel);
+
+    ///\e
+    virtual void _write(std::string file, std::string format) const;
+
+  };
+
+  /// \brief Skeleton class for an LP solver interface
+  ///
+  ///This class does nothing, but it can serve as a skeleton when
+  ///implementing an interface to new solvers.
+
+  ///\ingroup lp_group
+  class LpSkeleton : public LpSolver, public SkeletonSolverBase {
+  public:
+    ///\e
+    LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
+    ///\e
+    virtual LpSkeleton* newSolver() const;
+    ///\e
+    virtual LpSkeleton* cloneSolver() const;
+  protected:
+
+    ///\e
+    virtual SolveExitStatus _solve();
+
+    ///\e
+    virtual Value _getPrimal(int i) const;
+    ///\e
+    virtual Value _getDual(int i) const;
+
+    ///\e
+    virtual Value _getPrimalValue() const;
+
+    ///\e
+    virtual Value _getPrimalRay(int i) const;
+    ///\e
+    virtual Value _getDualRay(int i) const;
+
+    ///\e
+    virtual ProblemType _getPrimalType() const;
+    ///\e
+    virtual ProblemType _getDualType() const;
+
+    ///\e
+    virtual VarStatus _getColStatus(int i) const;
+    ///\e
+    virtual VarStatus _getRowStatus(int i) const;
+
+    ///\e
+    virtual const char* _solverName() const;
+
+  };
+
+  /// \brief Skeleton class for a MIP solver interface
+  ///
+  ///This class does nothing, but it can serve as a skeleton when
+  ///implementing an interface to new solvers.
+  ///\ingroup lp_group
+  class MipSkeleton : public MipSolver, public SkeletonSolverBase {
+  public:
+    ///\e
+    MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
+    ///\e
+    virtual MipSkeleton* newSolver() const;
+    ///\e
+    virtual MipSkeleton* cloneSolver() const;
+
+  protected:
+    ///\e
+    virtual SolveExitStatus _solve();
+
+    ///\e
+    virtual Value _getSol(int i) const;
+
+    ///\e
+    virtual Value _getSolValue() const;
+
+    ///\e
+    virtual ProblemType _getType() const;
+
+    ///\e
+    virtual const char* _solverName() const;
+
+  };
+
+} //namespace lemon
+
+#endif
diff --git a/lemon/maps.h b/lemon/maps.h
new file mode 100644
index 0000000..1bc49e9
--- /dev/null
+++ b/lemon/maps.h
@@ -0,0 +1,4057 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_MAPS_H
+#define LEMON_MAPS_H
+
+#include <iterator>
+#include <functional>
+#include <vector>
+#include <map>
+
+#include <lemon/core.h>
+
+///\file
+///\ingroup maps
+///\brief Miscellaneous property maps
+
+namespace lemon {
+
+  /// \addtogroup maps
+  /// @{
+
+  /// Base class of maps.
+
+  /// Base class of maps. It provides the necessary type definitions
+  /// required by the map %concepts.
+  template<typename K, typename V>
+  class MapBase {
+  public:
+    /// \brief The key type of the map.
+    typedef K Key;
+    /// \brief The value type of the map.
+    /// (The type of objects associated with the keys).
+    typedef V Value;
+  };
+
+
+  /// Null map. (a.k.a. DoNothingMap)
+
+  /// This map can be used if you have to provide a map only for
+  /// its type definitions, or if you have to provide a writable map,
+  /// but data written to it is not required (i.e. it will be sent to
+  /// <tt>/dev/null</tt>).
+  /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+  ///
+  /// \sa ConstMap
+  template<typename K, typename V>
+  class NullMap : public MapBase<K, V> {
+  public:
+    ///\e
+    typedef K Key;
+    ///\e
+    typedef V Value;
+
+    /// Gives back a default constructed element.
+    Value operator[](const Key&) const { return Value(); }
+    /// Absorbs the value.
+    void set(const Key&, const Value&) {}
+  };
+
+  /// Returns a \c NullMap class
+
+  /// This function just returns a \c NullMap class.
+  /// \relates NullMap
+  template <typename K, typename V>
+  NullMap<K, V> nullMap() {
+    return NullMap<K, V>();
+  }
+
+
+  /// Constant map.
+
+  /// This \ref concepts::ReadMap "readable map" assigns a specified
+  /// value to each key.
+  ///
+  /// In other aspects it is equivalent to \c NullMap.
+  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
+  /// concept, but it absorbs the data written to it.
+  ///
+  /// The simplest way of using this map is through the constMap()
+  /// function.
+  ///
+  /// \sa NullMap
+  /// \sa IdentityMap
+  template<typename K, typename V>
+  class ConstMap : public MapBase<K, V> {
+  private:
+    V _value;
+  public:
+    ///\e
+    typedef K Key;
+    ///\e
+    typedef V Value;
+
+    /// Default constructor
+
+    /// Default constructor.
+    /// The value of the map will be default constructed.
+    ConstMap() {}
+
+    /// Constructor with specified initial value
+
+    /// Constructor with specified initial value.
+    /// \param v The initial value of the map.
+    ConstMap(const Value &v) : _value(v) {}
+
+    /// Gives back the specified value.
+    Value operator[](const Key&) const { return _value; }
+
+    /// Absorbs the value.
+    void set(const Key&, const Value&) {}
+
+    /// Sets the value that is assigned to each key.
+    void setAll(const Value &v) {
+      _value = v;
+    }
+
+    template<typename V1>
+    ConstMap(const ConstMap<K, V1> &, const Value &v) : _value(v) {}
+  };
+
+  /// Returns a \c ConstMap class
+
+  /// This function just returns a \c ConstMap class.
+  /// \relates ConstMap
+  template<typename K, typename V>
+  inline ConstMap<K, V> constMap(const V &v) {
+    return ConstMap<K, V>(v);
+  }
+
+  template<typename K, typename V>
+  inline ConstMap<K, V> constMap() {
+    return ConstMap<K, V>();
+  }
+
+
+  template<typename T, T v>
+  struct Const {};
+
+  /// Constant map with inlined constant value.
+
+  /// This \ref concepts::ReadMap "readable map" assigns a specified
+  /// value to each key.
+  ///
+  /// In other aspects it is equivalent to \c NullMap.
+  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
+  /// concept, but it absorbs the data written to it.
+  ///
+  /// The simplest way of using this map is through the constMap()
+  /// function.
+  ///
+  /// \sa NullMap
+  /// \sa IdentityMap
+  template<typename K, typename V, V v>
+  class ConstMap<K, Const<V, v> > : public MapBase<K, V> {
+  public:
+    ///\e
+    typedef K Key;
+    ///\e
+    typedef V Value;
+
+    /// Constructor.
+    ConstMap() {}
+
+    /// Gives back the specified value.
+    Value operator[](const Key&) const { return v; }
+
+    /// Absorbs the value.
+    void set(const Key&, const Value&) {}
+  };
+
+  /// Returns a \c ConstMap class with inlined constant value
+
+  /// This function just returns a \c ConstMap class with inlined
+  /// constant value.
+  /// \relates ConstMap
+  template<typename K, typename V, V v>
+  inline ConstMap<K, Const<V, v> > constMap() {
+    return ConstMap<K, Const<V, v> >();
+  }
+
+
+  /// Identity map.
+
+  /// This \ref concepts::ReadMap "read-only map" gives back the given
+  /// key as value without any modification.
+  ///
+  /// \sa ConstMap
+  template <typename T>
+  class IdentityMap : public MapBase<T, T> {
+  public:
+    ///\e
+    typedef T Key;
+    ///\e
+    typedef T Value;
+
+    /// Gives back the given value without any modification.
+    Value operator[](const Key &k) const {
+      return k;
+    }
+  };
+
+  /// Returns an \c IdentityMap class
+
+  /// This function just returns an \c IdentityMap class.
+  /// \relates IdentityMap
+  template<typename T>
+  inline IdentityMap<T> identityMap() {
+    return IdentityMap<T>();
+  }
+
+
+  /// \brief Map for storing values for integer keys from the range
+  /// <tt>[0..size-1]</tt>.
+  ///
+  /// 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 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.
+  ///
+  /// The simplest way of using this map is through the rangeMap()
+  /// function.
+  template <typename V>
+  class RangeMap : public MapBase<int, V> {
+    template <typename V1>
+    friend class RangeMap;
+  private:
+
+    typedef std::vector<V> Vector;
+    Vector _vector;
+
+  public:
+
+    /// Key type
+    typedef int Key;
+    /// Value type
+    typedef V Value;
+    /// Reference type
+    typedef typename Vector::reference Reference;
+    /// Const reference type
+    typedef typename Vector::const_reference ConstReference;
+
+    typedef True ReferenceMapTag;
+
+  public:
+
+    /// Constructor with specified default value.
+    RangeMap(int size = 0, const Value &value = Value())
+      : _vector(size, value) {}
+
+    /// Constructs the map from an appropriate \c std::vector.
+    template <typename V1>
+    RangeMap(const std::vector<V1>& vector)
+      : _vector(vector.begin(), vector.end()) {}
+
+    /// Constructs the map from another \c RangeMap.
+    template <typename V1>
+    RangeMap(const RangeMap<V1> &c)
+      : _vector(c._vector.begin(), c._vector.end()) {}
+
+    /// Returns the size of the map.
+    int size() {
+      return _vector.size();
+    }
+
+    /// Resizes the map.
+
+    /// Resizes the underlying \c std::vector container, so changes the
+    /// keyset of the map.
+    /// \param size The new size of the map. The new keyset will be the
+    /// range <tt>[0..size-1]</tt>.
+    /// \param value The default value to assign to the new keys.
+    void resize(int size, const Value &value = Value()) {
+      _vector.resize(size, value);
+    }
+
+  private:
+
+    RangeMap& operator=(const RangeMap&);
+
+  public:
+
+    ///\e
+    Reference operator[](const Key &k) {
+      return _vector[k];
+    }
+
+    ///\e
+    ConstReference operator[](const Key &k) const {
+      return _vector[k];
+    }
+
+    ///\e
+    void set(const Key &k, const Value &v) {
+      _vector[k] = v;
+    }
+  };
+
+  /// Returns a \c RangeMap class
+
+  /// This function just returns a \c RangeMap class.
+  /// \relates RangeMap
+  template<typename V>
+  inline RangeMap<V> rangeMap(int size = 0, const V &value = V()) {
+    return RangeMap<V>(size, value);
+  }
+
+  /// \brief Returns a \c RangeMap class created from an appropriate
+  /// \c std::vector
+
+  /// This function just returns a \c RangeMap class created from an
+  /// appropriate \c std::vector.
+  /// \relates RangeMap
+  template<typename V>
+  inline RangeMap<V> rangeMap(const std::vector<V> &vector) {
+    return RangeMap<V>(vector);
+  }
+
+
+  /// Map type based on \c std::map
+
+  /// This map is essentially a wrapper for \c std::map with addition
+  /// that you can specify a default value for the keys that are not
+  /// stored actually. This value can be different from the default
+  /// contructed value (i.e. \c %Value()).
+  /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
+  /// concept.
+  ///
+  /// This map is useful if a default value should be assigned to most of
+  /// the keys and different values should be assigned only to a few
+  /// keys (i.e. the map is "sparse").
+  /// 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
+  /// 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
+  /// maps.
+  ///
+  /// The simplest way of using this map is through the sparseMap()
+  /// function.
+  template <typename K, typename V, typename Comp = std::less<K> >
+  class SparseMap : public MapBase<K, V> {
+    template <typename K1, typename V1, typename C1>
+    friend class SparseMap;
+  public:
+
+    /// Key type
+    typedef K Key;
+    /// Value type
+    typedef V Value;
+    /// Reference type
+    typedef Value& Reference;
+    /// Const reference type
+    typedef const Value& ConstReference;
+
+    typedef True ReferenceMapTag;
+
+  private:
+
+    typedef std::map<K, V, Comp> Map;
+    Map _map;
+    Value _value;
+
+  public:
+
+    /// \brief Constructor with specified default value.
+    SparseMap(const Value &value = Value()) : _value(value) {}
+    /// \brief Constructs the map from an appropriate \c std::map, and
+    /// explicitly specifies a default value.
+    template <typename V1, typename Comp1>
+    SparseMap(const std::map<Key, V1, Comp1> &map,
+              const Value &value = Value())
+      : _map(map.begin(), map.end()), _value(value) {}
+
+    /// \brief Constructs the map from another \c SparseMap.
+    template<typename V1, typename Comp1>
+    SparseMap(const SparseMap<Key, V1, Comp1> &c)
+      : _map(c._map.begin(), c._map.end()), _value(c._value) {}
+
+  private:
+
+    SparseMap& operator=(const SparseMap&);
+
+  public:
+
+    ///\e
+    Reference operator[](const Key &k) {
+      typename Map::iterator it = _map.lower_bound(k);
+      if (it != _map.end() && !_map.key_comp()(k, it->first))
+        return it->second;
+      else
+        return _map.insert(it, std::make_pair(k, _value))->second;
+    }
+
+    ///\e
+    ConstReference operator[](const Key &k) const {
+      typename Map::const_iterator it = _map.find(k);
+      if (it != _map.end())
+        return it->second;
+      else
+        return _value;
+    }
+
+    ///\e
+    void set(const Key &k, const Value &v) {
+      typename Map::iterator it = _map.lower_bound(k);
+      if (it != _map.end() && !_map.key_comp()(k, it->first))
+        it->second = v;
+      else
+        _map.insert(it, std::make_pair(k, v));
+    }
+
+    ///\e
+    void setAll(const Value &v) {
+      _value = v;
+      _map.clear();
+    }
+  };
+
+  /// Returns a \c SparseMap class
+
+  /// This function just returns a \c SparseMap class with specified
+  /// default value.
+  /// \relates SparseMap
+  template<typename K, typename V, typename Compare>
+  inline SparseMap<K, V, Compare> sparseMap(const V& value = V()) {
+    return SparseMap<K, V, Compare>(value);
+  }
+
+  template<typename K, typename V>
+  inline SparseMap<K, V, std::less<K> > sparseMap(const V& value = V()) {
+    return SparseMap<K, V, std::less<K> >(value);
+  }
+
+  /// \brief Returns a \c SparseMap class created from an appropriate
+  /// \c std::map
+
+  /// This function just returns a \c SparseMap class created from an
+  /// appropriate \c std::map.
+  /// \relates SparseMap
+  template<typename K, typename V, typename Compare>
+  inline SparseMap<K, V, Compare>
+    sparseMap(const std::map<K, V, Compare> &map, const V& value = V())
+  {
+    return SparseMap<K, V, Compare>(map, value);
+  }
+
+  /// @}
+
+  /// \addtogroup map_adaptors
+  /// @{
+
+  /// Composition of two maps
+
+  /// This \ref concepts::ReadMap "read-only map" returns the
+  /// composition of two given maps. That is to say, if \c m1 is of
+  /// type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   ComposeMap<M1, M2> cm(m1,m2);
+  /// \endcode
+  /// <tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>.
+  ///
+  /// The \c Key type of the map is inherited from \c M2 and the
+  /// \c Value type is from \c M1.
+  /// \c M2::Value must be convertible to \c M1::Key.
+  ///
+  /// The simplest way of using this map is through the composeMap()
+  /// function.
+  ///
+  /// \sa CombineMap
+  template <typename M1, typename M2>
+  class ComposeMap : public MapBase<typename M2::Key, typename M1::Value> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M2::Key Key;
+    ///\e
+    typedef typename M1::Value Value;
+
+    /// Constructor
+    ComposeMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
+
+    ///\e
+    typename MapTraits<M1>::ConstReturnValue
+    operator[](const Key &k) const { return _m1[_m2[k]]; }
+  };
+
+  /// Returns a \c ComposeMap class
+
+  /// This function just returns a \c ComposeMap class.
+  ///
+  /// If \c m1 and \c m2 are maps and the \c Value type of \c m2 is
+  /// convertible to the \c Key of \c m1, then <tt>composeMap(m1,m2)[x]</tt>
+  /// will be equal to <tt>m1[m2[x]]</tt>.
+  ///
+  /// \relates ComposeMap
+  template <typename M1, typename M2>
+  inline ComposeMap<M1, M2> composeMap(const M1 &m1, const M2 &m2) {
+    return ComposeMap<M1, M2>(m1, m2);
+  }
+
+
+  /// Combination of two maps using an STL (binary) functor.
+
+  /// This \ref concepts::ReadMap "read-only map" takes two maps and a
+  /// binary functor and returns the combination of the two given maps
+  /// using the functor.
+  /// That is to say, if \c m1 is of type \c M1 and \c m2 is of \c M2
+  /// and \c f is of \c F, then for
+  /// \code
+  ///   CombineMap<M1,M2,F,V> cm(m1,m2,f);
+  /// \endcode
+  /// <tt>cm[x]</tt> will be equal to <tt>f(m1[x],m2[x])</tt>.
+  ///
+  /// The \c Key type of the map is inherited from \c M1 (\c M1::Key
+  /// must be convertible to \c M2::Key) and the \c Value type is \c V.
+  /// \c M2::Value and \c M1::Value must be convertible to the
+  /// corresponding input parameter of \c F and the return type of \c F
+  /// must be convertible to \c V.
+  ///
+  /// The simplest way of using this map is through the combineMap()
+  /// function.
+  ///
+  /// \sa ComposeMap
+  template<typename M1, typename M2, typename F,
+           typename V = typename F::result_type>
+  class CombineMap : public MapBase<typename M1::Key, V> {
+    const M1 &_m1;
+    const M2 &_m2;
+    F _f;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef V Value;
+
+    /// Constructor
+    CombineMap(const M1 &m1, const M2 &m2, const F &f = F())
+      : _m1(m1), _m2(m2), _f(f) {}
+    ///\e
+    Value operator[](const Key &k) const { return _f(_m1[k],_m2[k]); }
+  };
+
+  /// Returns a \c CombineMap class
+
+  /// This function just returns a \c CombineMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are both maps with \c double
+  /// values, then
+  /// \code
+  ///   combineMap(m1,m2,std::plus<double>())
+  /// \endcode
+  /// is equivalent to
+  /// \code
+  ///   addMap(m1,m2)
+  /// \endcode
+  ///
+  /// This function is specialized for adaptable binary function
+  /// classes and C++ functions.
+  ///
+  /// \relates CombineMap
+  template<typename M1, typename M2, typename F, typename V>
+  inline CombineMap<M1, M2, F, V>
+  combineMap(const M1 &m1, const M2 &m2, const F &f) {
+    return CombineMap<M1, M2, F, V>(m1,m2,f);
+  }
+
+  template<typename M1, typename M2, typename F>
+  inline CombineMap<M1, M2, F, typename F::result_type>
+  combineMap(const M1 &m1, const M2 &m2, const F &f) {
+    return combineMap<M1, M2, F, typename F::result_type>(m1,m2,f);
+  }
+
+  template<typename M1, typename M2, typename K1, typename K2, typename V>
+  inline CombineMap<M1, M2, V (*)(K1, K2), V>
+  combineMap(const M1 &m1, const M2 &m2, V (*f)(K1, K2)) {
+    return combineMap<M1, M2, V (*)(K1, K2), V>(m1,m2,f);
+  }
+
+
+  /// Converts an STL style (unary) functor to a map
+
+  /// This \ref concepts::ReadMap "read-only map" returns the value
+  /// of a given functor. Actually, it just wraps the functor and
+  /// provides the \c Key and \c Value typedefs.
+  ///
+  /// Template parameters \c K and \c V will become its \c Key and
+  /// \c Value. In most cases they have to be given explicitly because
+  /// a functor typically does not provide \c argument_type and
+  /// \c result_type typedefs.
+  /// Parameter \c F is the type of the used functor.
+  ///
+  /// The simplest way of using this map is through the functorToMap()
+  /// function.
+  ///
+  /// \sa MapToFunctor
+  template<typename F,
+           typename K = typename F::argument_type,
+           typename V = typename F::result_type>
+  class FunctorToMap : public MapBase<K, V> {
+    F _f;
+  public:
+    ///\e
+    typedef K Key;
+    ///\e
+    typedef V Value;
+
+    /// Constructor
+    FunctorToMap(const F &f = F()) : _f(f) {}
+    ///\e
+    Value operator[](const Key &k) const { return _f(k); }
+  };
+
+  /// Returns a \c FunctorToMap class
+
+  /// This function just returns a \c FunctorToMap class.
+  ///
+  /// This function is specialized for adaptable binary function
+  /// classes and C++ functions.
+  ///
+  /// \relates FunctorToMap
+  template<typename K, typename V, typename F>
+  inline FunctorToMap<F, K, V> functorToMap(const F &f) {
+    return FunctorToMap<F, K, V>(f);
+  }
+
+  template <typename F>
+  inline FunctorToMap<F, typename F::argument_type, typename F::result_type>
+    functorToMap(const F &f)
+  {
+    return FunctorToMap<F, typename F::argument_type,
+      typename F::result_type>(f);
+  }
+
+  template <typename K, typename V>
+  inline FunctorToMap<V (*)(K), K, V> functorToMap(V (*f)(K)) {
+    return FunctorToMap<V (*)(K), K, V>(f);
+  }
+
+
+  /// Converts a map to an STL style (unary) functor
+
+  /// This class converts a map to an STL style (unary) functor.
+  /// That is it provides an <tt>operator()</tt> to read its values.
+  ///
+  /// For the sake of convenience it also works as a usual
+  /// \ref concepts::ReadMap "readable map", i.e. <tt>operator[]</tt>
+  /// and the \c Key and \c Value typedefs also exist.
+  ///
+  /// The simplest way of using this map is through the mapToFunctor()
+  /// function.
+  ///
+  ///\sa FunctorToMap
+  template <typename M>
+  class MapToFunctor : public MapBase<typename M::Key, typename M::Value> {
+    const M &_m;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef typename M::Value Value;
+
+    typedef typename M::Key argument_type;
+    typedef typename M::Value result_type;
+
+    /// Constructor
+    MapToFunctor(const M &m) : _m(m) {}
+    ///\e
+    Value operator()(const Key &k) const { return _m[k]; }
+    ///\e
+    Value operator[](const Key &k) const { return _m[k]; }
+  };
+
+  /// Returns a \c MapToFunctor class
+
+  /// This function just returns a \c MapToFunctor class.
+  /// \relates MapToFunctor
+  template<typename M>
+  inline MapToFunctor<M> mapToFunctor(const M &m) {
+    return MapToFunctor<M>(m);
+  }
+
+
+  /// \brief Map adaptor to convert the \c Value type of a map to
+  /// another type using the default conversion.
+
+  /// Map adaptor to convert the \c Value type of a \ref concepts::ReadMap
+  /// "readable map" to another type using the default conversion.
+  /// The \c Key type of it is inherited from \c M and the \c Value
+  /// type is \c V.
+  /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
+  ///
+  /// The simplest way of using this map is through the convertMap()
+  /// function.
+  template <typename M, typename V>
+  class ConvertMap : public MapBase<typename M::Key, V> {
+    const M &_m;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef V Value;
+
+    /// Constructor
+
+    /// Constructor.
+    /// \param m The underlying map.
+    ConvertMap(const M &m) : _m(m) {}
+
+    ///\e
+    Value operator[](const Key &k) const { return _m[k]; }
+  };
+
+  /// Returns a \c ConvertMap class
+
+  /// This function just returns a \c ConvertMap class.
+  /// \relates ConvertMap
+  template<typename V, typename M>
+  inline ConvertMap<M, V> convertMap(const M &map) {
+    return ConvertMap<M, V>(map);
+  }
+
+
+  /// Applies all map setting operations to two maps
+
+  /// This map has two \ref concepts::WriteMap "writable map" parameters
+  /// and each write request will be passed to both of them.
+  /// If \c M1 is also \ref concepts::ReadMap "readable", then the read
+  /// operations will return the corresponding values of \c M1.
+  ///
+  /// The \c Key and \c Value types are inherited from \c M1.
+  /// The \c Key and \c Value of \c M2 must be convertible from those
+  /// of \c M1.
+  ///
+  /// The simplest way of using this map is through the forkMap()
+  /// function.
+  template<typename  M1, typename M2>
+  class ForkMap : public MapBase<typename M1::Key, typename M1::Value> {
+    M1 &_m1;
+    M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef typename M1::Value Value;
+
+    /// Constructor
+    ForkMap(M1 &m1, M2 &m2) : _m1(m1), _m2(m2) {}
+    /// Returns the value associated with the given key in the first map.
+    Value operator[](const Key &k) const { return _m1[k]; }
+    /// Sets the value associated with the given key in both maps.
+    void set(const Key &k, const Value &v) { _m1.set(k,v); _m2.set(k,v); }
+  };
+
+  /// Returns a \c ForkMap class
+
+  /// This function just returns a \c ForkMap class.
+  /// \relates ForkMap
+  template <typename M1, typename M2>
+  inline ForkMap<M1,M2> forkMap(M1 &m1, M2 &m2) {
+    return ForkMap<M1,M2>(m1,m2);
+  }
+
+
+  /// Sum of two maps
+
+  /// This \ref concepts::ReadMap "read-only map" returns the sum
+  /// of the values of the two given maps.
+  /// Its \c Key and \c Value types are inherited from \c M1.
+  /// The \c Key and \c Value of \c M2 must be convertible to those of
+  /// \c M1.
+  ///
+  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   AddMap<M1,M2> am(m1,m2);
+  /// \endcode
+  /// <tt>am[x]</tt> will be equal to <tt>m1[x]+m2[x]</tt>.
+  ///
+  /// The simplest way of using this map is through the addMap()
+  /// function.
+  ///
+  /// \sa SubMap, MulMap, DivMap
+  /// \sa ShiftMap, ShiftWriteMap
+  template<typename M1, typename M2>
+  class AddMap : public MapBase<typename M1::Key, typename M1::Value> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef typename M1::Value Value;
+
+    /// Constructor
+    AddMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m1[k]+_m2[k]; }
+  };
+
+  /// Returns an \c AddMap class
+
+  /// This function just returns an \c AddMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are both maps with \c double
+  /// values, then <tt>addMap(m1,m2)[x]</tt> will be equal to
+  /// <tt>m1[x]+m2[x]</tt>.
+  ///
+  /// \relates AddMap
+  template<typename M1, typename M2>
+  inline AddMap<M1, M2> addMap(const M1 &m1, const M2 &m2) {
+    return AddMap<M1, M2>(m1,m2);
+  }
+
+
+  /// Difference of two maps
+
+  /// This \ref concepts::ReadMap "read-only map" returns the difference
+  /// of the values of the two given maps.
+  /// Its \c Key and \c Value types are inherited from \c M1.
+  /// The \c Key and \c Value of \c M2 must be convertible to those of
+  /// \c M1.
+  ///
+  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   SubMap<M1,M2> sm(m1,m2);
+  /// \endcode
+  /// <tt>sm[x]</tt> will be equal to <tt>m1[x]-m2[x]</tt>.
+  ///
+  /// The simplest way of using this map is through the subMap()
+  /// function.
+  ///
+  /// \sa AddMap, MulMap, DivMap
+  template<typename M1, typename M2>
+  class SubMap : public MapBase<typename M1::Key, typename M1::Value> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef typename M1::Value Value;
+
+    /// Constructor
+    SubMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m1[k]-_m2[k]; }
+  };
+
+  /// Returns a \c SubMap class
+
+  /// This function just returns a \c SubMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are both maps with \c double
+  /// values, then <tt>subMap(m1,m2)[x]</tt> will be equal to
+  /// <tt>m1[x]-m2[x]</tt>.
+  ///
+  /// \relates SubMap
+  template<typename M1, typename M2>
+  inline SubMap<M1, M2> subMap(const M1 &m1, const M2 &m2) {
+    return SubMap<M1, M2>(m1,m2);
+  }
+
+
+  /// Product of two maps
+
+  /// This \ref concepts::ReadMap "read-only map" returns the product
+  /// of the values of the two given maps.
+  /// Its \c Key and \c Value types are inherited from \c M1.
+  /// The \c Key and \c Value of \c M2 must be convertible to those of
+  /// \c M1.
+  ///
+  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   MulMap<M1,M2> mm(m1,m2);
+  /// \endcode
+  /// <tt>mm[x]</tt> will be equal to <tt>m1[x]*m2[x]</tt>.
+  ///
+  /// The simplest way of using this map is through the mulMap()
+  /// function.
+  ///
+  /// \sa AddMap, SubMap, DivMap
+  /// \sa ScaleMap, ScaleWriteMap
+  template<typename M1, typename M2>
+  class MulMap : public MapBase<typename M1::Key, typename M1::Value> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef typename M1::Value Value;
+
+    /// Constructor
+    MulMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m1[k]*_m2[k]; }
+  };
+
+  /// Returns a \c MulMap class
+
+  /// This function just returns a \c MulMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are both maps with \c double
+  /// values, then <tt>mulMap(m1,m2)[x]</tt> will be equal to
+  /// <tt>m1[x]*m2[x]</tt>.
+  ///
+  /// \relates MulMap
+  template<typename M1, typename M2>
+  inline MulMap<M1, M2> mulMap(const M1 &m1,const M2 &m2) {
+    return MulMap<M1, M2>(m1,m2);
+  }
+
+
+  /// Quotient of two maps
+
+  /// This \ref concepts::ReadMap "read-only map" returns the quotient
+  /// of the values of the two given maps.
+  /// Its \c Key and \c Value types are inherited from \c M1.
+  /// The \c Key and \c Value of \c M2 must be convertible to those of
+  /// \c M1.
+  ///
+  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   DivMap<M1,M2> dm(m1,m2);
+  /// \endcode
+  /// <tt>dm[x]</tt> will be equal to <tt>m1[x]/m2[x]</tt>.
+  ///
+  /// The simplest way of using this map is through the divMap()
+  /// function.
+  ///
+  /// \sa AddMap, SubMap, MulMap
+  template<typename M1, typename M2>
+  class DivMap : public MapBase<typename M1::Key, typename M1::Value> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef typename M1::Value Value;
+
+    /// Constructor
+    DivMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m1[k]/_m2[k]; }
+  };
+
+  /// Returns a \c DivMap class
+
+  /// This function just returns a \c DivMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are both maps with \c double
+  /// values, then <tt>divMap(m1,m2)[x]</tt> will be equal to
+  /// <tt>m1[x]/m2[x]</tt>.
+  ///
+  /// \relates DivMap
+  template<typename M1, typename M2>
+  inline DivMap<M1, M2> divMap(const M1 &m1,const M2 &m2) {
+    return DivMap<M1, M2>(m1,m2);
+  }
+
+
+  /// Shifts a map with a constant.
+
+  /// This \ref concepts::ReadMap "read-only map" returns the sum of
+  /// the given map and a constant value (i.e. it shifts the map with
+  /// the constant). Its \c Key and \c Value are inherited from \c M.
+  ///
+  /// Actually,
+  /// \code
+  ///   ShiftMap<M> sh(m,v);
+  /// \endcode
+  /// is equivalent to
+  /// \code
+  ///   ConstMap<M::Key, M::Value> cm(v);
+  ///   AddMap<M, ConstMap<M::Key, M::Value> > sh(m,cm);
+  /// \endcode
+  ///
+  /// The simplest way of using this map is through the shiftMap()
+  /// function.
+  ///
+  /// \sa ShiftWriteMap
+  template<typename M, typename C = typename M::Value>
+  class ShiftMap : public MapBase<typename M::Key, typename M::Value> {
+    const M &_m;
+    C _v;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef typename M::Value Value;
+
+    /// Constructor
+
+    /// Constructor.
+    /// \param m The undelying map.
+    /// \param v The constant value.
+    ShiftMap(const M &m, const C &v) : _m(m), _v(v) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m[k]+_v; }
+  };
+
+  /// Shifts a map with a constant (read-write version).
+
+  /// This \ref concepts::ReadWriteMap "read-write map" returns the sum
+  /// of the given map and a constant value (i.e. it shifts the map with
+  /// the constant). Its \c Key and \c Value are inherited from \c M.
+  /// It makes also possible to write the map.
+  ///
+  /// The simplest way of using this map is through the shiftWriteMap()
+  /// function.
+  ///
+  /// \sa ShiftMap
+  template<typename M, typename C = typename M::Value>
+  class ShiftWriteMap : public MapBase<typename M::Key, typename M::Value> {
+    M &_m;
+    C _v;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef typename M::Value Value;
+
+    /// Constructor
+
+    /// Constructor.
+    /// \param m The undelying map.
+    /// \param v The constant value.
+    ShiftWriteMap(M &m, const C &v) : _m(m), _v(v) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m[k]+_v; }
+    ///\e
+    void set(const Key &k, const Value &v) { _m.set(k, v-_v); }
+  };
+
+  /// Returns a \c ShiftMap class
+
+  /// This function just returns a \c ShiftMap class.
+  ///
+  /// For example, if \c m is a map with \c double values and \c v is
+  /// \c double, then <tt>shiftMap(m,v)[x]</tt> will be equal to
+  /// <tt>m[x]+v</tt>.
+  ///
+  /// \relates ShiftMap
+  template<typename M, typename C>
+  inline ShiftMap<M, C> shiftMap(const M &m, const C &v) {
+    return ShiftMap<M, C>(m,v);
+  }
+
+  /// Returns a \c ShiftWriteMap class
+
+  /// This function just returns a \c ShiftWriteMap class.
+  ///
+  /// For example, if \c m is a map with \c double values and \c v is
+  /// \c double, then <tt>shiftWriteMap(m,v)[x]</tt> will be equal to
+  /// <tt>m[x]+v</tt>.
+  /// Moreover it makes also possible to write the map.
+  ///
+  /// \relates ShiftWriteMap
+  template<typename M, typename C>
+  inline ShiftWriteMap<M, C> shiftWriteMap(M &m, const C &v) {
+    return ShiftWriteMap<M, C>(m,v);
+  }
+
+
+  /// Scales a map with a constant.
+
+  /// This \ref concepts::ReadMap "read-only map" returns the value of
+  /// the given map multiplied from the left side with a constant value.
+  /// Its \c Key and \c Value are inherited from \c M.
+  ///
+  /// Actually,
+  /// \code
+  ///   ScaleMap<M> sc(m,v);
+  /// \endcode
+  /// is equivalent to
+  /// \code
+  ///   ConstMap<M::Key, M::Value> cm(v);
+  ///   MulMap<ConstMap<M::Key, M::Value>, M> sc(cm,m);
+  /// \endcode
+  ///
+  /// The simplest way of using this map is through the scaleMap()
+  /// function.
+  ///
+  /// \sa ScaleWriteMap
+  template<typename M, typename C = typename M::Value>
+  class ScaleMap : public MapBase<typename M::Key, typename M::Value> {
+    const M &_m;
+    C _v;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef typename M::Value Value;
+
+    /// Constructor
+
+    /// Constructor.
+    /// \param m The undelying map.
+    /// \param v The constant value.
+    ScaleMap(const M &m, const C &v) : _m(m), _v(v) {}
+    ///\e
+    Value operator[](const Key &k) const { return _v*_m[k]; }
+  };
+
+  /// Scales a map with a constant (read-write version).
+
+  /// This \ref concepts::ReadWriteMap "read-write map" returns the value of
+  /// the given map multiplied from the left side with a constant value.
+  /// Its \c Key and \c Value are inherited from \c M.
+  /// It can also be used as write map if the \c / operator is defined
+  /// between \c Value and \c C and the given multiplier is not zero.
+  ///
+  /// The simplest way of using this map is through the scaleWriteMap()
+  /// function.
+  ///
+  /// \sa ScaleMap
+  template<typename M, typename C = typename M::Value>
+  class ScaleWriteMap : public MapBase<typename M::Key, typename M::Value> {
+    M &_m;
+    C _v;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef typename M::Value Value;
+
+    /// Constructor
+
+    /// Constructor.
+    /// \param m The undelying map.
+    /// \param v The constant value.
+    ScaleWriteMap(M &m, const C &v) : _m(m), _v(v) {}
+    ///\e
+    Value operator[](const Key &k) const { return _v*_m[k]; }
+    ///\e
+    void set(const Key &k, const Value &v) { _m.set(k, v/_v); }
+  };
+
+  /// Returns a \c ScaleMap class
+
+  /// This function just returns a \c ScaleMap class.
+  ///
+  /// For example, if \c m is a map with \c double values and \c v is
+  /// \c double, then <tt>scaleMap(m,v)[x]</tt> will be equal to
+  /// <tt>v*m[x]</tt>.
+  ///
+  /// \relates ScaleMap
+  template<typename M, typename C>
+  inline ScaleMap<M, C> scaleMap(const M &m, const C &v) {
+    return ScaleMap<M, C>(m,v);
+  }
+
+  /// Returns a \c ScaleWriteMap class
+
+  /// This function just returns a \c ScaleWriteMap class.
+  ///
+  /// For example, if \c m is a map with \c double values and \c v is
+  /// \c double, then <tt>scaleWriteMap(m,v)[x]</tt> will be equal to
+  /// <tt>v*m[x]</tt>.
+  /// Moreover it makes also possible to write the map.
+  ///
+  /// \relates ScaleWriteMap
+  template<typename M, typename C>
+  inline ScaleWriteMap<M, C> scaleWriteMap(M &m, const C &v) {
+    return ScaleWriteMap<M, C>(m,v);
+  }
+
+
+  /// Negative of a map
+
+  /// This \ref concepts::ReadMap "read-only map" returns the negative
+  /// of the values of the given map (using the unary \c - operator).
+  /// Its \c Key and \c Value are inherited from \c M.
+  ///
+  /// If M::Value is \c int, \c double etc., then
+  /// \code
+  ///   NegMap<M> neg(m);
+  /// \endcode
+  /// is equivalent to
+  /// \code
+  ///   ScaleMap<M> neg(m,-1);
+  /// \endcode
+  ///
+  /// The simplest way of using this map is through the negMap()
+  /// function.
+  ///
+  /// \sa NegWriteMap
+  template<typename M>
+  class NegMap : public MapBase<typename M::Key, typename M::Value> {
+    const M& _m;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef typename M::Value Value;
+
+    /// Constructor
+    NegMap(const M &m) : _m(m) {}
+    ///\e
+    Value operator[](const Key &k) const { return -_m[k]; }
+  };
+
+  /// Negative of a map (read-write version)
+
+  /// This \ref concepts::ReadWriteMap "read-write map" returns the
+  /// negative of the values of the given map (using the unary \c -
+  /// operator).
+  /// Its \c Key and \c Value are inherited from \c M.
+  /// It makes also possible to write the map.
+  ///
+  /// If M::Value is \c int, \c double etc., then
+  /// \code
+  ///   NegWriteMap<M> neg(m);
+  /// \endcode
+  /// is equivalent to
+  /// \code
+  ///   ScaleWriteMap<M> neg(m,-1);
+  /// \endcode
+  ///
+  /// The simplest way of using this map is through the negWriteMap()
+  /// function.
+  ///
+  /// \sa NegMap
+  template<typename M>
+  class NegWriteMap : public MapBase<typename M::Key, typename M::Value> {
+    M &_m;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef typename M::Value Value;
+
+    /// Constructor
+    NegWriteMap(M &m) : _m(m) {}
+    ///\e
+    Value operator[](const Key &k) const { return -_m[k]; }
+    ///\e
+    void set(const Key &k, const Value &v) { _m.set(k, -v); }
+  };
+
+  /// Returns a \c NegMap class
+
+  /// This function just returns a \c NegMap class.
+  ///
+  /// For example, if \c m is a map with \c double values, then
+  /// <tt>negMap(m)[x]</tt> will be equal to <tt>-m[x]</tt>.
+  ///
+  /// \relates NegMap
+  template <typename M>
+  inline NegMap<M> negMap(const M &m) {
+    return NegMap<M>(m);
+  }
+
+  /// Returns a \c NegWriteMap class
+
+  /// This function just returns a \c NegWriteMap class.
+  ///
+  /// For example, if \c m is a map with \c double values, then
+  /// <tt>negWriteMap(m)[x]</tt> will be equal to <tt>-m[x]</tt>.
+  /// Moreover it makes also possible to write the map.
+  ///
+  /// \relates NegWriteMap
+  template <typename M>
+  inline NegWriteMap<M> negWriteMap(M &m) {
+    return NegWriteMap<M>(m);
+  }
+
+
+  /// Absolute value of a map
+
+  /// This \ref concepts::ReadMap "read-only map" returns the absolute
+  /// value of the values of the given map.
+  /// Its \c Key and \c Value are inherited from \c M.
+  /// \c Value must be comparable to \c 0 and the unary \c -
+  /// operator must be defined for it, of course.
+  ///
+  /// The simplest way of using this map is through the absMap()
+  /// function.
+  template<typename M>
+  class AbsMap : public MapBase<typename M::Key, typename M::Value> {
+    const M &_m;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef typename M::Value Value;
+
+    /// Constructor
+    AbsMap(const M &m) : _m(m) {}
+    ///\e
+    Value operator[](const Key &k) const {
+      Value tmp = _m[k];
+      return tmp >= 0 ? tmp : -tmp;
+    }
+
+  };
+
+  /// Returns an \c AbsMap class
+
+  /// This function just returns an \c AbsMap class.
+  ///
+  /// For example, if \c m is a map with \c double values, then
+  /// <tt>absMap(m)[x]</tt> will be equal to <tt>m[x]</tt> if
+  /// it is positive or zero and <tt>-m[x]</tt> if <tt>m[x]</tt> is
+  /// negative.
+  ///
+  /// \relates AbsMap
+  template<typename M>
+  inline AbsMap<M> absMap(const M &m) {
+    return AbsMap<M>(m);
+  }
+
+  /// @}
+
+  // Logical maps and map adaptors:
+
+  /// \addtogroup maps
+  /// @{
+
+  /// Constant \c true map.
+
+  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
+  /// each key.
+  ///
+  /// Note that
+  /// \code
+  ///   TrueMap<K> tm;
+  /// \endcode
+  /// is equivalent to
+  /// \code
+  ///   ConstMap<K,bool> tm(true);
+  /// \endcode
+  ///
+  /// \sa FalseMap
+  /// \sa ConstMap
+  template <typename K>
+  class TrueMap : public MapBase<K, bool> {
+  public:
+    ///\e
+    typedef K Key;
+    ///\e
+    typedef bool Value;
+
+    /// Gives back \c true.
+    Value operator[](const Key&) const { return true; }
+  };
+
+  /// Returns a \c TrueMap class
+
+  /// This function just returns a \c TrueMap class.
+  /// \relates TrueMap
+  template<typename K>
+  inline TrueMap<K> trueMap() {
+    return TrueMap<K>();
+  }
+
+
+  /// Constant \c false map.
+
+  /// This \ref concepts::ReadMap "read-only map" assigns \c false to
+  /// each key.
+  ///
+  /// Note that
+  /// \code
+  ///   FalseMap<K> fm;
+  /// \endcode
+  /// is equivalent to
+  /// \code
+  ///   ConstMap<K,bool> fm(false);
+  /// \endcode
+  ///
+  /// \sa TrueMap
+  /// \sa ConstMap
+  template <typename K>
+  class FalseMap : public MapBase<K, bool> {
+  public:
+    ///\e
+    typedef K Key;
+    ///\e
+    typedef bool Value;
+
+    /// Gives back \c false.
+    Value operator[](const Key&) const { return false; }
+  };
+
+  /// Returns a \c FalseMap class
+
+  /// This function just returns a \c FalseMap class.
+  /// \relates FalseMap
+  template<typename K>
+  inline FalseMap<K> falseMap() {
+    return FalseMap<K>();
+  }
+
+  /// @}
+
+  /// \addtogroup map_adaptors
+  /// @{
+
+  /// Logical 'and' of two maps
+
+  /// This \ref concepts::ReadMap "read-only map" returns the logical
+  /// 'and' of the values of the two given maps.
+  /// Its \c Key type is inherited from \c M1 and its \c Value type is
+  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
+  ///
+  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   AndMap<M1,M2> am(m1,m2);
+  /// \endcode
+  /// <tt>am[x]</tt> will be equal to <tt>m1[x]&&m2[x]</tt>.
+  ///
+  /// The simplest way of using this map is through the andMap()
+  /// function.
+  ///
+  /// \sa OrMap
+  /// \sa NotMap, NotWriteMap
+  template<typename M1, typename M2>
+  class AndMap : public MapBase<typename M1::Key, bool> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef bool Value;
+
+    /// Constructor
+    AndMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m1[k]&&_m2[k]; }
+  };
+
+  /// Returns an \c AndMap class
+
+  /// This function just returns an \c AndMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are both maps with \c bool values,
+  /// then <tt>andMap(m1,m2)[x]</tt> will be equal to
+  /// <tt>m1[x]&&m2[x]</tt>.
+  ///
+  /// \relates AndMap
+  template<typename M1, typename M2>
+  inline AndMap<M1, M2> andMap(const M1 &m1, const M2 &m2) {
+    return AndMap<M1, M2>(m1,m2);
+  }
+
+
+  /// Logical 'or' of two maps
+
+  /// This \ref concepts::ReadMap "read-only map" returns the logical
+  /// 'or' of the values of the two given maps.
+  /// Its \c Key type is inherited from \c M1 and its \c Value type is
+  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
+  ///
+  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   OrMap<M1,M2> om(m1,m2);
+  /// \endcode
+  /// <tt>om[x]</tt> will be equal to <tt>m1[x]||m2[x]</tt>.
+  ///
+  /// The simplest way of using this map is through the orMap()
+  /// function.
+  ///
+  /// \sa AndMap
+  /// \sa NotMap, NotWriteMap
+  template<typename M1, typename M2>
+  class OrMap : public MapBase<typename M1::Key, bool> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef bool Value;
+
+    /// Constructor
+    OrMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m1[k]||_m2[k]; }
+  };
+
+  /// Returns an \c OrMap class
+
+  /// This function just returns an \c OrMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are both maps with \c bool values,
+  /// then <tt>orMap(m1,m2)[x]</tt> will be equal to
+  /// <tt>m1[x]||m2[x]</tt>.
+  ///
+  /// \relates OrMap
+  template<typename M1, typename M2>
+  inline OrMap<M1, M2> orMap(const M1 &m1, const M2 &m2) {
+    return OrMap<M1, M2>(m1,m2);
+  }
+
+
+  /// Logical 'not' of a map
+
+  /// This \ref concepts::ReadMap "read-only map" returns the logical
+  /// negation of the values of the given map.
+  /// Its \c Key is inherited from \c M and its \c Value is \c bool.
+  ///
+  /// The simplest way of using this map is through the notMap()
+  /// function.
+  ///
+  /// \sa NotWriteMap
+  template <typename M>
+  class NotMap : public MapBase<typename M::Key, bool> {
+    const M &_m;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef bool Value;
+
+    /// Constructor
+    NotMap(const M &m) : _m(m) {}
+    ///\e
+    Value operator[](const Key &k) const { return !_m[k]; }
+  };
+
+  /// Logical 'not' of a map (read-write version)
+
+  /// This \ref concepts::ReadWriteMap "read-write map" returns the
+  /// logical negation of the values of the given map.
+  /// Its \c Key is inherited from \c M and its \c Value is \c bool.
+  /// It makes also possible to write the map. When a value is set,
+  /// the opposite value is set to the original map.
+  ///
+  /// The simplest way of using this map is through the notWriteMap()
+  /// function.
+  ///
+  /// \sa NotMap
+  template <typename M>
+  class NotWriteMap : public MapBase<typename M::Key, bool> {
+    M &_m;
+  public:
+    ///\e
+    typedef typename M::Key Key;
+    ///\e
+    typedef bool Value;
+
+    /// Constructor
+    NotWriteMap(M &m) : _m(m) {}
+    ///\e
+    Value operator[](const Key &k) const { return !_m[k]; }
+    ///\e
+    void set(const Key &k, bool v) { _m.set(k, !v); }
+  };
+
+  /// Returns a \c NotMap class
+
+  /// This function just returns a \c NotMap class.
+  ///
+  /// For example, if \c m is a map with \c bool values, then
+  /// <tt>notMap(m)[x]</tt> will be equal to <tt>!m[x]</tt>.
+  ///
+  /// \relates NotMap
+  template <typename M>
+  inline NotMap<M> notMap(const M &m) {
+    return NotMap<M>(m);
+  }
+
+  /// Returns a \c NotWriteMap class
+
+  /// This function just returns a \c NotWriteMap class.
+  ///
+  /// For example, if \c m is a map with \c bool values, then
+  /// <tt>notWriteMap(m)[x]</tt> will be equal to <tt>!m[x]</tt>.
+  /// Moreover it makes also possible to write the map.
+  ///
+  /// \relates NotWriteMap
+  template <typename M>
+  inline NotWriteMap<M> notWriteMap(M &m) {
+    return NotWriteMap<M>(m);
+  }
+
+
+  /// Combination of two maps using the \c == operator
+
+  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
+  /// the keys for which the corresponding values of the two maps are
+  /// equal.
+  /// Its \c Key type is inherited from \c M1 and its \c Value type is
+  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
+  ///
+  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   EqualMap<M1,M2> em(m1,m2);
+  /// \endcode
+  /// <tt>em[x]</tt> will be equal to <tt>m1[x]==m2[x]</tt>.
+  ///
+  /// The simplest way of using this map is through the equalMap()
+  /// function.
+  ///
+  /// \sa LessMap
+  template<typename M1, typename M2>
+  class EqualMap : public MapBase<typename M1::Key, bool> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef bool Value;
+
+    /// Constructor
+    EqualMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m1[k]==_m2[k]; }
+  };
+
+  /// Returns an \c EqualMap class
+
+  /// This function just returns an \c EqualMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are maps with keys and values of
+  /// the same type, then <tt>equalMap(m1,m2)[x]</tt> will be equal to
+  /// <tt>m1[x]==m2[x]</tt>.
+  ///
+  /// \relates EqualMap
+  template<typename M1, typename M2>
+  inline EqualMap<M1, M2> equalMap(const M1 &m1, const M2 &m2) {
+    return EqualMap<M1, M2>(m1,m2);
+  }
+
+
+  /// Combination of two maps using the \c < operator
+
+  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
+  /// the keys for which the corresponding value of the first map is
+  /// less then the value of the second map.
+  /// Its \c Key type is inherited from \c M1 and its \c Value type is
+  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
+  ///
+  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
+  /// \code
+  ///   LessMap<M1,M2> lm(m1,m2);
+  /// \endcode
+  /// <tt>lm[x]</tt> will be equal to <tt>m1[x]<m2[x]</tt>.
+  ///
+  /// The simplest way of using this map is through the lessMap()
+  /// function.
+  ///
+  /// \sa EqualMap
+  template<typename M1, typename M2>
+  class LessMap : public MapBase<typename M1::Key, bool> {
+    const M1 &_m1;
+    const M2 &_m2;
+  public:
+    ///\e
+    typedef typename M1::Key Key;
+    ///\e
+    typedef bool Value;
+
+    /// Constructor
+    LessMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
+    ///\e
+    Value operator[](const Key &k) const { return _m1[k]<_m2[k]; }
+  };
+
+  /// Returns an \c LessMap class
+
+  /// This function just returns an \c LessMap class.
+  ///
+  /// For example, if \c m1 and \c m2 are maps with keys and values of
+  /// the same type, then <tt>lessMap(m1,m2)[x]</tt> will be equal to
+  /// <tt>m1[x]<m2[x]</tt>.
+  ///
+  /// \relates LessMap
+  template<typename M1, typename M2>
+  inline LessMap<M1, M2> lessMap(const M1 &m1, const M2 &m2) {
+    return LessMap<M1, M2>(m1,m2);
+  }
+
+  namespace _maps_bits {
+
+    template <typename _Iterator, typename Enable = void>
+    struct IteratorTraits {
+      typedef typename std::iterator_traits<_Iterator>::value_type Value;
+    };
+
+    template <typename _Iterator>
+    struct IteratorTraits<_Iterator,
+      typename exists<typename _Iterator::container_type>::type>
+    {
+      typedef typename _Iterator::container_type::value_type Value;
+    };
+
+  }
+
+  /// @}
+
+  /// \addtogroup maps
+  /// @{
+
+  /// \brief Writable bool map for logging each \c true assigned element
+  ///
+  /// A \ref concepts::WriteMap "writable" bool map for logging
+  /// each \c true assigned element, i.e it copies subsequently each
+  /// keys set to \c true to the given iterator.
+  /// The most important usage of it is storing certain nodes or arcs
+  /// that were marked \c true by an algorithm.
+  ///
+  /// There are several algorithms that provide solutions through bool
+  /// maps and most of them assign \c true at most once for each key.
+  /// In these cases it is a natural request to store each \c true
+  /// assigned elements (in order of the assignment), which can be
+  /// easily done with LoggerBoolMap.
+  ///
+  /// The simplest way of using this map is through the loggerBoolMap()
+  /// function.
+  ///
+  /// \tparam IT The type of the iterator.
+  /// \tparam KEY The key type of the map. The default value set
+  /// according to the iterator type should work in most cases.
+  ///
+  /// \note The container of the iterator must contain enough space
+  /// for the elements or the iterator should be an inserter iterator.
+#ifdef DOXYGEN
+  template <typename IT, typename KEY>
+#else
+  template <typename IT,
+            typename KEY = typename _maps_bits::IteratorTraits<IT>::Value>
+#endif
+  class LoggerBoolMap : public MapBase<KEY, bool> {
+  public:
+
+    ///\e
+    typedef KEY Key;
+    ///\e
+    typedef bool Value;
+    ///\e
+    typedef IT Iterator;
+
+    /// Constructor
+    LoggerBoolMap(Iterator it)
+      : _begin(it), _end(it) {}
+
+    /// Gives back the given iterator set for the first key
+    Iterator begin() const {
+      return _begin;
+    }
+
+    /// Gives back the the 'after the last' iterator
+    Iterator end() const {
+      return _end;
+    }
+
+    /// The set function of the map
+    void set(const Key& key, Value value) {
+      if (value) {
+        *_end++ = key;
+      }
+    }
+
+  private:
+    Iterator _begin;
+    Iterator _end;
+  };
+
+  /// Returns a \c LoggerBoolMap class
+
+  /// This function just returns a \c LoggerBoolMap class.
+  ///
+  /// 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
+  /// order of Dfs algorithm, as the following examples show.
+  /// \code
+  ///   std::vector<Node> v;
+  ///   dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
+  /// \endcode
+  /// \code
+  ///   std::vector<Node> v(countNodes(g));
+  ///   dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
+  /// \endcode
+  ///
+  /// \note The container of the iterator must contain enough space
+  /// for the elements or the iterator should be an inserter iterator.
+  ///
+  /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so
+  /// it cannot be used when a readable map is needed, for example, as
+  /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms.
+  ///
+  /// \relates LoggerBoolMap
+  template<typename Iterator>
+  inline LoggerBoolMap<Iterator> loggerBoolMap(Iterator it) {
+    return LoggerBoolMap<Iterator>(it);
+  }
+
+  /// @}
+
+  /// \addtogroup graph_maps
+  /// @{
+
+  /// \brief Provides an immutable and unique id for each item in a graph.
+  ///
+  /// IdMap provides a unique and immutable id for each item of the
+  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
+  ///  - \b unique: different items get different ids,
+  ///  - \b immutable: the id of an item does not change (even if you
+  ///    delete other nodes).
+  ///
+  /// Using this map you get access (i.e. can read) the inner id values of
+  /// the items stored in the graph, which is returned by the \c id()
+  /// function of the graph. This map can be inverted with its member
+  /// class \c InverseMap or with the \c operator()() member.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  ///
+  /// \see RangeIdMap
+  template <typename GR, typename K>
+  class IdMap : public MapBase<K, int> {
+  public:
+    /// The graph type of IdMap.
+    typedef GR Graph;
+    typedef GR Digraph;
+    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
+    typedef K Item;
+    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
+    typedef K Key;
+    /// The value type of IdMap.
+    typedef int Value;
+
+    /// \brief Constructor.
+    ///
+    /// Constructor of the map.
+    explicit IdMap(const Graph& graph) : _graph(&graph) {}
+
+    /// \brief Gives back the \e id of the item.
+    ///
+    /// Gives back the immutable and unique \e id of the item.
+    int operator[](const Item& item) const { return _graph->id(item);}
+
+    /// \brief Gives back the \e item by its id.
+    ///
+    /// Gives back the \e item by its id.
+    Item operator()(int id) { return _graph->fromId(id, Item()); }
+
+  private:
+    const Graph* _graph;
+
+  public:
+
+    /// \brief The inverse map type of IdMap.
+    ///
+    /// The inverse map type of IdMap. The subscript operator gives back
+    /// an item by its id.
+    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
+    /// \see inverse()
+    class InverseMap {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor for creating an id-to-item map.
+      explicit InverseMap(const Graph& graph) : _graph(&graph) {}
+
+      /// \brief Constructor.
+      ///
+      /// Constructor for creating an id-to-item map.
+      explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
+
+      /// \brief Gives back an item by its id.
+      ///
+      /// Gives back an item by its id.
+      Item operator[](int id) const { return _graph->fromId(id, Item());}
+
+    private:
+      const Graph* _graph;
+    };
+
+    /// \brief Gives back the inverse of the map.
+    ///
+    /// Gives back the inverse of the IdMap.
+    InverseMap inverse() const { return InverseMap(*_graph);}
+  };
+
+  /// \brief Returns an \c IdMap class.
+  ///
+  /// This function just returns an \c IdMap class.
+  /// \relates IdMap
+  template <typename K, typename GR>
+  inline IdMap<GR, K> idMap(const GR& graph) {
+    return IdMap<GR, K>(graph);
+  }
+
+  /// \brief General cross reference graph map type.
+
+  /// This class provides simple invertable graph maps.
+  /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
+  /// and if a key is set to a new value, then stores it in the inverse map.
+  /// The graph items can be accessed by their values either using
+  /// \c InverseMap or \c operator()(), and the values of the map can be
+  /// accessed with an STL compatible forward iterator (\c ValueIt).
+  ///
+  /// This map is intended to be used when all associated values are
+  /// different (the map is actually invertable) or there are only a few
+  /// items with the same value.
+  /// Otherwise consider to use \c IterableValueMap, which is more
+  /// suitable and more efficient for such cases. It provides iterators
+  /// to traverse the items with the same associated value, but
+  /// it does not have \c InverseMap.
+  ///
+  /// This type is not reference map, so it cannot be modified with
+  /// the subscript operator.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  /// \tparam V The value type of the map.
+  ///
+  /// \see IterableValueMap
+  template <typename GR, typename K, typename V>
+  class CrossRefMap
+    : protected ItemSetTraits<GR, K>::template Map<V>::Type {
+  private:
+
+    typedef typename ItemSetTraits<GR, K>::
+      template Map<V>::Type Map;
+
+    typedef std::multimap<V, K> Container;
+    Container _inv_map;
+
+  public:
+
+    /// The graph type of CrossRefMap.
+    typedef GR Graph;
+    typedef GR Digraph;
+    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
+    typedef K Item;
+    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
+    typedef K Key;
+    /// The value type of CrossRefMap.
+    typedef V Value;
+
+    /// \brief Constructor.
+    ///
+    /// Construct a new CrossRefMap for the given graph.
+    explicit CrossRefMap(const Graph& graph) : Map(graph) {}
+
+    /// \brief Forward iterator for values.
+    ///
+    /// This iterator is an STL compatible forward
+    /// iterator on the values of the map. The values can
+    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
+    /// They are considered with multiplicity, so each value is
+    /// traversed for each item it is assigned to.
+    class ValueIt
+      : public std::iterator<std::forward_iterator_tag, Value> {
+      friend class CrossRefMap;
+    private:
+      ValueIt(typename Container::const_iterator _it)
+        : it(_it) {}
+    public:
+
+      /// Constructor
+      ValueIt() {}
+
+      /// \e
+      ValueIt& operator++() { ++it; return *this; }
+      /// \e
+      ValueIt operator++(int) {
+        ValueIt tmp(*this);
+        operator++();
+        return tmp;
+      }
+
+      /// \e
+      const Value& operator*() const { return it->first; }
+      /// \e
+      const Value* operator->() const { return &(it->first); }
+
+      /// \e
+      bool operator==(ValueIt jt) const { return it == jt.it; }
+      /// \e
+      bool operator!=(ValueIt jt) const { return it != jt.it; }
+
+    private:
+      typename Container::const_iterator it;
+    };
+
+    /// Alias for \c ValueIt
+    typedef ValueIt ValueIterator;
+
+    /// \brief Returns an iterator to the first value.
+    ///
+    /// Returns an STL compatible iterator to the
+    /// first value of the map. The values of the
+    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
+    /// range.
+    ValueIt beginValue() const {
+      return ValueIt(_inv_map.begin());
+    }
+
+    /// \brief Returns an iterator after the last value.
+    ///
+    /// Returns an STL compatible iterator after the
+    /// last value of the map. The values of the
+    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
+    /// range.
+    ValueIt endValue() const {
+      return ValueIt(_inv_map.end());
+    }
+
+    /// \brief Sets the value associated with the given key.
+    ///
+    /// Sets the value associated with the given key.
+    void set(const Key& key, const Value& val) {
+      Value oldval = Map::operator[](key);
+      typename Container::iterator it;
+      for (it = _inv_map.equal_range(oldval).first;
+           it != _inv_map.equal_range(oldval).second; ++it) {
+        if (it->second == key) {
+          _inv_map.erase(it);
+          break;
+        }
+      }
+      _inv_map.insert(std::make_pair(val, key));
+      Map::set(key, val);
+    }
+
+    /// \brief Returns the value associated with the given key.
+    ///
+    /// Returns the value associated with the given key.
+    typename MapTraits<Map>::ConstReturnValue
+    operator[](const Key& key) const {
+      return Map::operator[](key);
+    }
+
+    /// \brief Gives back an item by its value.
+    ///
+    /// This function gives back an item that is assigned to
+    /// the given value or \c INVALID if no such item exists.
+    /// If there are more items with the same associated value,
+    /// only one of them is returned.
+    Key operator()(const Value& val) const {
+      typename Container::const_iterator it = _inv_map.find(val);
+      return it != _inv_map.end() ? it->second : INVALID;
+    }
+
+    /// \brief Returns the number of items with the given value.
+    ///
+    /// This function returns the number of items with the given value
+    /// associated with it.
+    int count(const Value &val) const {
+      return _inv_map.count(val);
+    }
+
+  protected:
+
+    /// \brief Erase the key from the map and the inverse map.
+    ///
+    /// Erase the key from the map and the inverse map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void erase(const Key& key) {
+      Value val = Map::operator[](key);
+      typename Container::iterator it;
+      for (it = _inv_map.equal_range(val).first;
+           it != _inv_map.equal_range(val).second; ++it) {
+        if (it->second == key) {
+          _inv_map.erase(it);
+          break;
+        }
+      }
+      Map::erase(key);
+    }
+
+    /// \brief Erase more keys from the map and the inverse map.
+    ///
+    /// Erase more keys from the map and the inverse map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        Value val = Map::operator[](keys[i]);
+        typename Container::iterator it;
+        for (it = _inv_map.equal_range(val).first;
+             it != _inv_map.equal_range(val).second; ++it) {
+          if (it->second == keys[i]) {
+            _inv_map.erase(it);
+            break;
+          }
+        }
+      }
+      Map::erase(keys);
+    }
+
+    /// \brief Clear the keys from the map and the inverse map.
+    ///
+    /// Clear the keys from the map and the inverse map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void clear() {
+      _inv_map.clear();
+      Map::clear();
+    }
+
+  public:
+
+    /// \brief The inverse map type of CrossRefMap.
+    ///
+    /// The inverse map type of CrossRefMap. The subscript operator gives
+    /// back an item by its value.
+    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
+    /// \see inverse()
+    class InverseMap {
+    public:
+      /// \brief Constructor
+      ///
+      /// Constructor of the InverseMap.
+      explicit InverseMap(const CrossRefMap& inverted)
+        : _inverted(inverted) {}
+
+      /// The value type of the InverseMap.
+      typedef typename CrossRefMap::Key Value;
+      /// The key type of the InverseMap.
+      typedef typename CrossRefMap::Value Key;
+
+      /// \brief Subscript operator.
+      ///
+      /// Subscript operator. It gives back an item
+      /// that is assigned to the given value or \c INVALID
+      /// if no such item exists.
+      Value operator[](const Key& key) const {
+        return _inverted(key);
+      }
+
+    private:
+      const CrossRefMap& _inverted;
+    };
+
+    /// \brief Gives back the inverse of the map.
+    ///
+    /// Gives back the inverse of the CrossRefMap.
+    InverseMap inverse() const {
+      return InverseMap(*this);
+    }
+
+  };
+
+  /// \brief Provides continuous and unique id for the
+  /// items of a graph.
+  ///
+  /// RangeIdMap provides a unique and continuous
+  /// id for each item of a given type (\c Node, \c Arc or
+  /// \c Edge) in a graph. This id is
+  ///  - \b unique: different items get different ids,
+  ///  - \b continuous: the range of the ids is the set of integers
+  ///    between 0 and \c n-1, where \c n is the number of the items of
+  ///    this type (\c Node, \c Arc or \c Edge).
+  ///  - So, the ids can change when deleting an item of the same type.
+  ///
+  /// Thus this id is not (necessarily) the same as what can get using
+  /// the \c id() function of the graph or \ref IdMap.
+  /// This map can be inverted with its member class \c InverseMap,
+  /// or with the \c operator()() member.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  ///
+  /// \see IdMap
+  template <typename GR, typename K>
+  class RangeIdMap
+    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
+
+    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Map;
+
+  public:
+    /// The graph type of RangeIdMap.
+    typedef GR Graph;
+    typedef GR Digraph;
+    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
+    typedef K Item;
+    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
+    typedef K Key;
+    /// The value type of RangeIdMap.
+    typedef int Value;
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    explicit RangeIdMap(const Graph& gr) : Map(gr) {
+      Item it;
+      const typename Map::Notifier* nf = Map::notifier();
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Map::set(it, _inv_map.size());
+        _inv_map.push_back(it);
+      }
+    }
+
+  protected:
+
+    /// \brief Adds a new key to the map.
+    ///
+    /// Add a new key to the map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void add(const Item& item) {
+      Map::add(item);
+      Map::set(item, _inv_map.size());
+      _inv_map.push_back(item);
+    }
+
+    /// \brief Add more new keys to the map.
+    ///
+    /// Add more new keys to the map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void add(const std::vector<Item>& items) {
+      Map::add(items);
+      for (int i = 0; i < int(items.size()); ++i) {
+        Map::set(items[i], _inv_map.size());
+        _inv_map.push_back(items[i]);
+      }
+    }
+
+    /// \brief Erase the key from the map.
+    ///
+    /// Erase the key from the map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void erase(const Item& item) {
+      Map::set(_inv_map.back(), Map::operator[](item));
+      _inv_map[Map::operator[](item)] = _inv_map.back();
+      _inv_map.pop_back();
+      Map::erase(item);
+    }
+
+    /// \brief Erase more keys from the map.
+    ///
+    /// Erase more keys from the map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void erase(const std::vector<Item>& items) {
+      for (int i = 0; i < int(items.size()); ++i) {
+        Map::set(_inv_map.back(), Map::operator[](items[i]));
+        _inv_map[Map::operator[](items[i])] = _inv_map.back();
+        _inv_map.pop_back();
+      }
+      Map::erase(items);
+    }
+
+    /// \brief Build the unique map.
+    ///
+    /// Build the unique map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void build() {
+      Map::build();
+      Item it;
+      const typename Map::Notifier* nf = Map::notifier();
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Map::set(it, _inv_map.size());
+        _inv_map.push_back(it);
+      }
+    }
+
+    /// \brief Clear the keys from the map.
+    ///
+    /// Clear the keys from the map. It is called by the
+    /// \c AlterationNotifier.
+    virtual void clear() {
+      _inv_map.clear();
+      Map::clear();
+    }
+
+  public:
+
+    /// \brief Returns the maximal value plus one.
+    ///
+    /// Returns the maximal value plus one in the map.
+    unsigned int size() const {
+      return _inv_map.size();
+    }
+
+    /// \brief Swaps the position of the two items in the map.
+    ///
+    /// Swaps the position of the two items in the map.
+    void swap(const Item& p, const Item& q) {
+      int pi = Map::operator[](p);
+      int qi = Map::operator[](q);
+      Map::set(p, qi);
+      _inv_map[qi] = p;
+      Map::set(q, pi);
+      _inv_map[pi] = q;
+    }
+
+    /// \brief Gives back the \e range \e id of the item
+    ///
+    /// Gives back the \e range \e id of the item.
+    int operator[](const Item& item) const {
+      return Map::operator[](item);
+    }
+
+    /// \brief Gives back the item belonging to a \e range \e id
+    ///
+    /// Gives back the item belonging to the given \e range \e id.
+    Item operator()(int id) const {
+      return _inv_map[id];
+    }
+
+  private:
+
+    typedef std::vector<Item> Container;
+    Container _inv_map;
+
+  public:
+
+    /// \brief The inverse map type of RangeIdMap.
+    ///
+    /// The inverse map type of RangeIdMap. The subscript operator gives
+    /// back an item by its \e range \e id.
+    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
+    class InverseMap {
+    public:
+      /// \brief Constructor
+      ///
+      /// Constructor of the InverseMap.
+      explicit InverseMap(const RangeIdMap& inverted)
+        : _inverted(inverted) {}
+
+
+      /// The value type of the InverseMap.
+      typedef typename RangeIdMap::Key Value;
+      /// The key type of the InverseMap.
+      typedef typename RangeIdMap::Value Key;
+
+      /// \brief Subscript operator.
+      ///
+      /// Subscript operator. It gives back the item
+      /// that the given \e range \e id currently belongs to.
+      Value operator[](const Key& key) const {
+        return _inverted(key);
+      }
+
+      /// \brief Size of the map.
+      ///
+      /// Returns the size of the map.
+      unsigned int size() const {
+        return _inverted.size();
+      }
+
+    private:
+      const RangeIdMap& _inverted;
+    };
+
+    /// \brief Gives back the inverse of the map.
+    ///
+    /// Gives back the inverse of the RangeIdMap.
+    const InverseMap inverse() const {
+      return InverseMap(*this);
+    }
+  };
+
+  /// \brief Returns a \c RangeIdMap class.
+  ///
+  /// This function just returns an \c RangeIdMap class.
+  /// \relates RangeIdMap
+  template <typename K, typename GR>
+  inline RangeIdMap<GR, K> rangeIdMap(const GR& graph) {
+    return RangeIdMap<GR, K>(graph);
+  }
+
+  /// \brief Dynamic iterable \c bool map.
+  ///
+  /// This class provides a special graph map type which can store a
+  /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
+  /// For both \c true and \c false values it is possible to iterate on
+  /// the keys mapped to the value.
+  ///
+  /// This type is a reference map, so it can be modified with the
+  /// subscript operator.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  ///
+  /// \see IterableIntMap, IterableValueMap
+  /// \see CrossRefMap
+  template <typename GR, typename K>
+  class IterableBoolMap
+    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
+  private:
+    typedef GR Graph;
+
+    typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
+    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
+
+    std::vector<K> _array;
+    int _sep;
+
+  public:
+
+    /// Indicates that the map is reference map.
+    typedef True ReferenceMapTag;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef bool Value;
+    /// The const reference type.
+    typedef const Value& ConstReference;
+
+  private:
+
+    int position(const Key& key) const {
+      return Parent::operator[](key);
+    }
+
+  public:
+
+    /// \brief Reference to the value of the map.
+    ///
+    /// This class is similar to the \c bool type. It can be converted to
+    /// \c bool and it provides the same operators.
+    class Reference {
+      friend class IterableBoolMap;
+    private:
+      Reference(IterableBoolMap& map, const Key& key)
+        : _key(key), _map(map) {}
+    public:
+
+      Reference& operator=(const Reference& value) {
+        _map.set(_key, static_cast<bool>(value));
+         return *this;
+      }
+
+      operator bool() const {
+        return static_cast<const IterableBoolMap&>(_map)[_key];
+      }
+
+      Reference& operator=(bool value) {
+        _map.set(_key, value);
+        return *this;
+      }
+      Reference& operator&=(bool value) {
+        _map.set(_key, _map[_key] & value);
+        return *this;
+      }
+      Reference& operator|=(bool value) {
+        _map.set(_key, _map[_key] | value);
+        return *this;
+      }
+      Reference& operator^=(bool value) {
+        _map.set(_key, _map[_key] ^ value);
+        return *this;
+      }
+    private:
+      Key _key;
+      IterableBoolMap& _map;
+    };
+
+    /// \brief Constructor of the map with a default value.
+    ///
+    /// Constructor of the map with a default value.
+    explicit IterableBoolMap(const Graph& graph, bool def = false)
+      : Parent(graph) {
+      typename Parent::Notifier* nf = Parent::notifier();
+      Key it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Parent::set(it, _array.size());
+        _array.push_back(it);
+      }
+      _sep = (def ? _array.size() : 0);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    bool operator[](const Key& key) const {
+      return position(key) < _sep;
+    }
+
+    /// \brief Subscript operator of the map.
+    ///
+    /// Subscript operator of the map.
+    Reference operator[](const Key& key) {
+      return Reference(*this, key);
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, bool value) {
+      int pos = position(key);
+      if (value) {
+        if (pos < _sep) return;
+        Key tmp = _array[_sep];
+        _array[_sep] = key;
+        Parent::set(key, _sep);
+        _array[pos] = tmp;
+        Parent::set(tmp, pos);
+        ++_sep;
+      } else {
+        if (pos >= _sep) return;
+        --_sep;
+        Key tmp = _array[_sep];
+        _array[_sep] = key;
+        Parent::set(key, _sep);
+        _array[pos] = tmp;
+        Parent::set(tmp, pos);
+      }
+    }
+
+    /// \brief Set all items.
+    ///
+    /// Set all items in the map.
+    /// \note Constant time operation.
+    void setAll(bool value) {
+      _sep = (value ? _array.size() : 0);
+    }
+
+    /// \brief Returns the number of the keys mapped to \c true.
+    ///
+    /// Returns the number of the keys mapped to \c true.
+    int trueNum() const {
+      return _sep;
+    }
+
+    /// \brief Returns the number of the keys mapped to \c false.
+    ///
+    /// Returns the number of the keys mapped to \c false.
+    int falseNum() const {
+      return _array.size() - _sep;
+    }
+
+    /// \brief Iterator for the keys mapped to \c true.
+    ///
+    /// Iterator for the keys mapped to \c true. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class TrueIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys mapped to \c true.
+      /// \param map The IterableBoolMap.
+      explicit TrueIt(const IterableBoolMap& map)
+        : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
+          _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      TrueIt& operator++() {
+        int pos = _map->position(*this);
+        Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+    /// \brief Iterator for the keys mapped to \c false.
+    ///
+    /// Iterator for the keys mapped to \c false. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class FalseIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys mapped to \c false.
+      /// \param map The IterableBoolMap.
+      explicit FalseIt(const IterableBoolMap& map)
+        : Parent(map._sep < int(map._array.size()) ?
+                 map._array.back() : INVALID), _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      FalseIt& operator++() {
+        int pos = _map->position(*this);
+        Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+    /// \brief Iterator for the keys mapped to a given value.
+    ///
+    /// Iterator for the keys mapped to a given value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys mapped to the given value.
+      /// \param map The IterableBoolMap.
+      /// \param value The value.
+      ItemIt(const IterableBoolMap& map, bool value)
+        : Parent(value ?
+                 (map._sep > 0 ?
+                  map._array[map._sep - 1] : INVALID) :
+                 (map._sep < int(map._array.size()) ?
+                  map._array.back() : INVALID)), _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      ItemIt& operator++() {
+        int pos = _map->position(*this);
+        int _sep = pos >= _map->_sep ? _map->_sep : 0;
+        Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+  protected:
+
+    virtual void add(const Key& key) {
+      Parent::add(key);
+      Parent::set(key, _array.size());
+      _array.push_back(key);
+    }
+
+    virtual void add(const std::vector<Key>& keys) {
+      Parent::add(keys);
+      for (int i = 0; i < int(keys.size()); ++i) {
+        Parent::set(keys[i], _array.size());
+        _array.push_back(keys[i]);
+      }
+    }
+
+    virtual void erase(const Key& key) {
+      int pos = position(key);
+      if (pos < _sep) {
+        --_sep;
+        Parent::set(_array[_sep], pos);
+        _array[pos] = _array[_sep];
+        Parent::set(_array.back(), _sep);
+        _array[_sep] = _array.back();
+        _array.pop_back();
+      } else {
+        Parent::set(_array.back(), pos);
+        _array[pos] = _array.back();
+        _array.pop_back();
+      }
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        int pos = position(keys[i]);
+        if (pos < _sep) {
+          --_sep;
+          Parent::set(_array[_sep], pos);
+          _array[pos] = _array[_sep];
+          Parent::set(_array.back(), _sep);
+          _array[_sep] = _array.back();
+          _array.pop_back();
+        } else {
+          Parent::set(_array.back(), pos);
+          _array[pos] = _array.back();
+          _array.pop_back();
+        }
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void build() {
+      Parent::build();
+      typename Parent::Notifier* nf = Parent::notifier();
+      Key it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Parent::set(it, _array.size());
+        _array.push_back(it);
+      }
+      _sep = 0;
+    }
+
+    virtual void clear() {
+      _array.clear();
+      _sep = 0;
+      Parent::clear();
+    }
+
+  };
+
+
+  namespace _maps_bits {
+    template <typename Item>
+    struct IterableIntMapNode {
+      IterableIntMapNode() : value(-1) {}
+      IterableIntMapNode(int _value) : value(_value) {}
+      Item prev, next;
+      int value;
+    };
+  }
+
+  /// \brief Dynamic iterable integer map.
+  ///
+  /// This class provides a special graph map type which can store an
+  /// integer value for graph items (\c Node, \c Arc or \c Edge).
+  /// For each non-negative value it is possible to iterate on the keys
+  /// mapped to the value.
+  ///
+  /// This map is intended to be used with small integer values, for which
+  /// it is efficient, and supports iteration only for non-negative values.
+  /// If you need large values and/or iteration for negative integers,
+  /// consider to use \ref IterableValueMap instead.
+  ///
+  /// This type is a reference map, so it can be modified with the
+  /// subscript operator.
+  ///
+  /// \note The size of the data structure depends on the largest
+  /// value in the map.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  ///
+  /// \see IterableBoolMap, IterableValueMap
+  /// \see CrossRefMap
+  template <typename GR, typename K>
+  class IterableIntMap
+    : protected ItemSetTraits<GR, K>::
+        template Map<_maps_bits::IterableIntMapNode<K> >::Type {
+  public:
+    typedef typename ItemSetTraits<GR, K>::
+      template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef int Value;
+    /// The graph type
+    typedef GR Graph;
+
+    /// \brief Constructor of the map.
+    ///
+    /// Constructor of the map. It sets all values to -1.
+    explicit IterableIntMap(const Graph& graph)
+      : Parent(graph) {}
+
+    /// \brief Constructor of the map with a given value.
+    ///
+    /// Constructor of the map with a given value.
+    explicit IterableIntMap(const Graph& graph, int value)
+      : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
+      if (value >= 0) {
+        for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+          lace(it);
+        }
+      }
+    }
+
+  private:
+
+    void unlace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.value < 0) return;
+      if (node.prev != INVALID) {
+        Parent::operator[](node.prev).next = node.next;
+      } else {
+        _first[node.value] = node.next;
+      }
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = node.prev;
+      }
+      while (!_first.empty() && _first.back() == INVALID) {
+        _first.pop_back();
+      }
+    }
+
+    void lace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.value < 0) return;
+      if (node.value >= int(_first.size())) {
+        _first.resize(node.value + 1, INVALID);
+      }
+      node.prev = INVALID;
+      node.next = _first[node.value];
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = key;
+      }
+      _first[node.value] = key;
+    }
+
+  public:
+
+    /// Indicates that the map is reference map.
+    typedef True ReferenceMapTag;
+
+    /// \brief Reference to the value of the map.
+    ///
+    /// This class is similar to the \c int type. It can
+    /// be converted to \c int and it has the same operators.
+    class Reference {
+      friend class IterableIntMap;
+    private:
+      Reference(IterableIntMap& map, const Key& key)
+        : _key(key), _map(map) {}
+    public:
+
+      Reference& operator=(const Reference& value) {
+        _map.set(_key, static_cast<const int&>(value));
+         return *this;
+      }
+
+      operator const int&() const {
+        return static_cast<const IterableIntMap&>(_map)[_key];
+      }
+
+      Reference& operator=(int value) {
+        _map.set(_key, value);
+        return *this;
+      }
+      Reference& operator++() {
+        _map.set(_key, _map[_key] + 1);
+        return *this;
+      }
+      int operator++(int) {
+        int value = _map[_key];
+        _map.set(_key, value + 1);
+        return value;
+      }
+      Reference& operator--() {
+        _map.set(_key, _map[_key] - 1);
+        return *this;
+      }
+      int operator--(int) {
+        int value = _map[_key];
+        _map.set(_key, value - 1);
+        return value;
+      }
+      Reference& operator+=(int value) {
+        _map.set(_key, _map[_key] + value);
+        return *this;
+      }
+      Reference& operator-=(int value) {
+        _map.set(_key, _map[_key] - value);
+        return *this;
+      }
+      Reference& operator*=(int value) {
+        _map.set(_key, _map[_key] * value);
+        return *this;
+      }
+      Reference& operator/=(int value) {
+        _map.set(_key, _map[_key] / value);
+        return *this;
+      }
+      Reference& operator%=(int value) {
+        _map.set(_key, _map[_key] % value);
+        return *this;
+      }
+      Reference& operator&=(int value) {
+        _map.set(_key, _map[_key] & value);
+        return *this;
+      }
+      Reference& operator|=(int value) {
+        _map.set(_key, _map[_key] | value);
+        return *this;
+      }
+      Reference& operator^=(int value) {
+        _map.set(_key, _map[_key] ^ value);
+        return *this;
+      }
+      Reference& operator<<=(int value) {
+        _map.set(_key, _map[_key] << value);
+        return *this;
+      }
+      Reference& operator>>=(int value) {
+        _map.set(_key, _map[_key] >> value);
+        return *this;
+      }
+
+    private:
+      Key _key;
+      IterableIntMap& _map;
+    };
+
+    /// The const reference type.
+    typedef const Value& ConstReference;
+
+    /// \brief Gives back the maximal value plus one.
+    ///
+    /// Gives back the maximal value plus one.
+    int size() const {
+      return _first.size();
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, const Value& value) {
+      unlace(key);
+      Parent::operator[](key).value = value;
+      lace(key);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    const Value& operator[](const Key& key) const {
+      return Parent::operator[](key).value;
+    }
+
+    /// \brief Subscript operator of the map.
+    ///
+    /// Subscript operator of the map.
+    Reference operator[](const Key& key) {
+      return Reference(*this, key);
+    }
+
+    /// \brief Iterator for the keys with the same value.
+    ///
+    /// Iterator for the keys with the same value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the item type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid item, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys mapped to the given value.
+      /// \param map The IterableIntMap.
+      /// \param value The value.
+      ItemIt(const IterableIntMap& map, int value) : _map(&map) {
+        if (value < 0 || value >= int(_map->_first.size())) {
+          Parent::operator=(INVALID);
+        } else {
+          Parent::operator=(_map->_first[value]);
+        }
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      ItemIt& operator++() {
+        Parent::operator=(_map->IterableIntMap::Parent::
+                          operator[](static_cast<Parent&>(*this)).next);
+        return *this;
+      }
+
+    private:
+      const IterableIntMap* _map;
+    };
+
+  protected:
+
+    virtual void erase(const Key& key) {
+      unlace(key);
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        unlace(keys[i]);
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void clear() {
+      _first.clear();
+      Parent::clear();
+    }
+
+  private:
+    std::vector<Key> _first;
+  };
+
+  namespace _maps_bits {
+    template <typename Item, typename Value>
+    struct IterableValueMapNode {
+      IterableValueMapNode(Value _value = Value()) : value(_value) {}
+      Item prev, next;
+      Value value;
+    };
+  }
+
+  /// \brief Dynamic iterable map for comparable values.
+  ///
+  /// This class provides a special graph map type which can store a
+  /// comparable value for graph items (\c Node, \c Arc or \c Edge).
+  /// For each value it is possible to iterate on the keys mapped to
+  /// the value (\c ItemIt), and the values of the map can be accessed
+  /// with an STL compatible forward iterator (\c ValueIt).
+  /// The map stores a linked list for each value, which contains
+  /// the items mapped to the value, and the used values are stored
+  /// in balanced binary tree (\c std::map).
+  ///
+  /// \ref IterableBoolMap and \ref IterableIntMap are similar classes
+  /// specialized for \c bool and \c int values, respectively.
+  ///
+  /// This type is not reference map, so it cannot be modified with
+  /// the subscript operator.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  /// \tparam V The value type of the map. It can be any comparable
+  /// value type.
+  ///
+  /// \see IterableBoolMap, IterableIntMap
+  /// \see CrossRefMap
+  template <typename GR, typename K, typename V>
+  class IterableValueMap
+    : protected ItemSetTraits<GR, K>::
+        template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
+  public:
+    typedef typename ItemSetTraits<GR, K>::
+      template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef V Value;
+    /// The graph type
+    typedef GR Graph;
+
+  public:
+
+    /// \brief Constructor of the map with a given value.
+    ///
+    /// Constructor of the map with a given value.
+    explicit IterableValueMap(const Graph& graph,
+                              const Value& value = Value())
+      : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
+      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+        lace(it);
+      }
+    }
+
+  protected:
+
+    void unlace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.prev != INVALID) {
+        Parent::operator[](node.prev).next = node.next;
+      } else {
+        if (node.next != INVALID) {
+          _first[node.value] = node.next;
+        } else {
+          _first.erase(node.value);
+        }
+      }
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = node.prev;
+      }
+    }
+
+    void lace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      typename std::map<Value, Key>::iterator it = _first.find(node.value);
+      if (it == _first.end()) {
+        node.prev = node.next = INVALID;
+        _first.insert(std::make_pair(node.value, key));
+      } else {
+        node.prev = INVALID;
+        node.next = it->second;
+        if (node.next != INVALID) {
+          Parent::operator[](node.next).prev = key;
+        }
+        it->second = key;
+      }
+    }
+
+  public:
+
+    /// \brief Forward iterator for values.
+    ///
+    /// This iterator is an STL compatible forward
+    /// iterator on the values of the map. The values can
+    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
+    class ValueIt
+      : public std::iterator<std::forward_iterator_tag, Value> {
+      friend class IterableValueMap;
+    private:
+      ValueIt(typename std::map<Value, Key>::const_iterator _it)
+        : it(_it) {}
+    public:
+
+      /// Constructor
+      ValueIt() {}
+
+      /// \e
+      ValueIt& operator++() { ++it; return *this; }
+      /// \e
+      ValueIt operator++(int) {
+        ValueIt tmp(*this);
+        operator++();
+        return tmp;
+      }
+
+      /// \e
+      const Value& operator*() const { return it->first; }
+      /// \e
+      const Value* operator->() const { return &(it->first); }
+
+      /// \e
+      bool operator==(ValueIt jt) const { return it == jt.it; }
+      /// \e
+      bool operator!=(ValueIt jt) const { return it != jt.it; }
+
+    private:
+      typename std::map<Value, Key>::const_iterator it;
+    };
+
+    /// \brief Returns an iterator to the first value.
+    ///
+    /// Returns an STL compatible iterator to the
+    /// first value of the map. The values of the
+    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
+    /// range.
+    ValueIt beginValue() const {
+      return ValueIt(_first.begin());
+    }
+
+    /// \brief Returns an iterator after the last value.
+    ///
+    /// Returns an STL compatible iterator after the
+    /// last value of the map. The values of the
+    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
+    /// range.
+    ValueIt endValue() const {
+      return ValueIt(_first.end());
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, const Value& value) {
+      unlace(key);
+      Parent::operator[](key).value = value;
+      lace(key);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    const Value& operator[](const Key& key) const {
+      return Parent::operator[](key).value;
+    }
+
+    /// \brief Iterator for the keys with the same value.
+    ///
+    /// Iterator for the keys with the same value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the item type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid item, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys which have the given value.
+      /// \param map The IterableValueMap
+      /// \param value The value
+      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
+        typename std::map<Value, Key>::const_iterator it =
+          map._first.find(value);
+        if (it == map._first.end()) {
+          Parent::operator=(INVALID);
+        } else {
+          Parent::operator=(it->second);
+        }
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment Operator.
+      ItemIt& operator++() {
+        Parent::operator=(_map->IterableValueMap::Parent::
+                          operator[](static_cast<Parent&>(*this)).next);
+        return *this;
+      }
+
+
+    private:
+      const IterableValueMap* _map;
+    };
+
+  protected:
+
+    virtual void add(const Key& key) {
+      Parent::add(key);
+      lace(key);
+    }
+
+    virtual void add(const std::vector<Key>& keys) {
+      Parent::add(keys);
+      for (int i = 0; i < int(keys.size()); ++i) {
+        lace(keys[i]);
+      }
+    }
+
+    virtual void erase(const Key& key) {
+      unlace(key);
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        unlace(keys[i]);
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void build() {
+      Parent::build();
+      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+        lace(it);
+      }
+    }
+
+    virtual void clear() {
+      _first.clear();
+      Parent::clear();
+    }
+
+  private:
+    std::map<Value, Key> _first;
+  };
+
+  /// \brief Map of the source nodes of arcs in a digraph.
+  ///
+  /// SourceMap provides access for the source node of each arc in a digraph,
+  /// which is returned by the \c source() function of the digraph.
+  /// \tparam GR The digraph type.
+  /// \see TargetMap
+  template <typename GR>
+  class SourceMap {
+  public:
+
+    /// The key type (the \c Arc type of the digraph).
+    typedef typename GR::Arc Key;
+    /// The value type (the \c Node type of the digraph).
+    typedef typename GR::Node Value;
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param digraph The digraph that the map belongs to.
+    explicit SourceMap(const GR& digraph) : _graph(digraph) {}
+
+    /// \brief Returns the source node of the given arc.
+    ///
+    /// Returns the source node of the given arc.
+    Value operator[](const Key& arc) const {
+      return _graph.source(arc);
+    }
+
+  private:
+    const GR& _graph;
+  };
+
+  /// \brief Returns a \c SourceMap class.
+  ///
+  /// This function just returns an \c SourceMap class.
+  /// \relates SourceMap
+  template <typename GR>
+  inline SourceMap<GR> sourceMap(const GR& graph) {
+    return SourceMap<GR>(graph);
+  }
+
+  /// \brief Map of the target nodes of arcs in a digraph.
+  ///
+  /// TargetMap provides access for the target node of each arc in a digraph,
+  /// which is returned by the \c target() function of the digraph.
+  /// \tparam GR The digraph type.
+  /// \see SourceMap
+  template <typename GR>
+  class TargetMap {
+  public:
+
+    /// The key type (the \c Arc type of the digraph).
+    typedef typename GR::Arc Key;
+    /// The value type (the \c Node type of the digraph).
+    typedef typename GR::Node Value;
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param digraph The digraph that the map belongs to.
+    explicit TargetMap(const GR& digraph) : _graph(digraph) {}
+
+    /// \brief Returns the target node of the given arc.
+    ///
+    /// Returns the target node of the given arc.
+    Value operator[](const Key& e) const {
+      return _graph.target(e);
+    }
+
+  private:
+    const GR& _graph;
+  };
+
+  /// \brief Returns a \c TargetMap class.
+  ///
+  /// This function just returns a \c TargetMap class.
+  /// \relates TargetMap
+  template <typename GR>
+  inline TargetMap<GR> targetMap(const GR& graph) {
+    return TargetMap<GR>(graph);
+  }
+
+  /// \brief Map of the "forward" directed arc view of edges in a graph.
+  ///
+  /// ForwardMap provides access for the "forward" directed arc view of
+  /// each edge in a graph, which is returned by the \c direct() function
+  /// of the graph with \c true parameter.
+  /// \tparam GR The graph type.
+  /// \see BackwardMap
+  template <typename GR>
+  class ForwardMap {
+  public:
+
+    /// The key type (the \c Edge type of the digraph).
+    typedef typename GR::Edge Key;
+    /// The value type (the \c Arc type of the digraph).
+    typedef typename GR::Arc Value;
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param graph The graph that the map belongs to.
+    explicit ForwardMap(const GR& graph) : _graph(graph) {}
+
+    /// \brief Returns the "forward" directed arc view of the given edge.
+    ///
+    /// Returns the "forward" directed arc view of the given edge.
+    Value operator[](const Key& key) const {
+      return _graph.direct(key, true);
+    }
+
+  private:
+    const GR& _graph;
+  };
+
+  /// \brief Returns a \c ForwardMap class.
+  ///
+  /// This function just returns an \c ForwardMap class.
+  /// \relates ForwardMap
+  template <typename GR>
+  inline ForwardMap<GR> forwardMap(const GR& graph) {
+    return ForwardMap<GR>(graph);
+  }
+
+  /// \brief Map of the "backward" directed arc view of edges in a graph.
+  ///
+  /// BackwardMap provides access for the "backward" directed arc view of
+  /// each edge in a graph, which is returned by the \c direct() function
+  /// of the graph with \c false parameter.
+  /// \tparam GR The graph type.
+  /// \see ForwardMap
+  template <typename GR>
+  class BackwardMap {
+  public:
+
+    /// The key type (the \c Edge type of the digraph).
+    typedef typename GR::Edge Key;
+    /// The value type (the \c Arc type of the digraph).
+    typedef typename GR::Arc Value;
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param graph The graph that the map belongs to.
+    explicit BackwardMap(const GR& graph) : _graph(graph) {}
+
+    /// \brief Returns the "backward" directed arc view of the given edge.
+    ///
+    /// Returns the "backward" directed arc view of the given edge.
+    Value operator[](const Key& key) const {
+      return _graph.direct(key, false);
+    }
+
+  private:
+    const GR& _graph;
+  };
+
+  /// \brief Returns a \c BackwardMap class
+
+  /// This function just returns a \c BackwardMap class.
+  /// \relates BackwardMap
+  template <typename GR>
+  inline BackwardMap<GR> backwardMap(const GR& graph) {
+    return BackwardMap<GR>(graph);
+  }
+
+  /// \brief Map of the in-degrees of nodes in a digraph.
+  ///
+  /// This map returns the in-degree of a node. Once it is constructed,
+  /// the degrees are stored in a standard \c NodeMap, so each query is done
+  /// in constant time. On the other hand, the values are updated automatically
+  /// whenever the digraph changes.
+  ///
+  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
+  /// may provide alternative ways to modify the digraph.
+  /// The correct behavior of InDegMap is not guarantied if these additional
+  /// features are used. For example, the functions
+  /// \ref ListDigraph::changeSource() "changeSource()",
+  /// \ref ListDigraph::changeTarget() "changeTarget()" and
+  /// \ref ListDigraph::reverseArc() "reverseArc()"
+  /// of \ref ListDigraph will \e not update the degree values correctly.
+  ///
+  /// \sa OutDegMap
+  template <typename GR>
+  class InDegMap
+    : protected ItemSetTraits<GR, typename GR::Arc>
+      ::ItemNotifier::ObserverBase {
+
+  public:
+
+    /// The graph type of InDegMap
+    typedef GR Graph;
+    typedef GR Digraph;
+    /// The key type
+    typedef typename Digraph::Node Key;
+    /// The value type
+    typedef int Value;
+
+    typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
+    ::ItemNotifier::ObserverBase Parent;
+
+  private:
+
+    class AutoNodeMap
+      : public ItemSetTraits<Digraph, Key>::template Map<int>::Type {
+    public:
+
+      typedef typename ItemSetTraits<Digraph, Key>::
+      template Map<int>::Type Parent;
+
+      AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {}
+
+      virtual void add(const Key& key) {
+        Parent::add(key);
+        Parent::set(key, 0);
+      }
+
+      virtual void add(const std::vector<Key>& keys) {
+        Parent::add(keys);
+        for (int i = 0; i < int(keys.size()); ++i) {
+          Parent::set(keys[i], 0);
+        }
+      }
+
+      virtual void build() {
+        Parent::build();
+        Key it;
+        typename Parent::Notifier* nf = Parent::notifier();
+        for (nf->first(it); it != INVALID; nf->next(it)) {
+          Parent::set(it, 0);
+        }
+      }
+    };
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor for creating an in-degree map.
+    explicit InDegMap(const Digraph& graph)
+      : _digraph(graph), _deg(graph) {
+      Parent::attach(_digraph.notifier(typename Digraph::Arc()));
+
+      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
+        _deg[it] = countInArcs(_digraph, it);
+      }
+    }
+
+    /// \brief Gives back the in-degree of a Node.
+    ///
+    /// Gives back the in-degree of a Node.
+    int operator[](const Key& key) const {
+      return _deg[key];
+    }
+
+  protected:
+
+    typedef typename Digraph::Arc Arc;
+
+    virtual void add(const Arc& arc) {
+      ++_deg[_digraph.target(arc)];
+    }
+
+    virtual void add(const std::vector<Arc>& arcs) {
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        ++_deg[_digraph.target(arcs[i])];
+      }
+    }
+
+    virtual void erase(const Arc& arc) {
+      --_deg[_digraph.target(arc)];
+    }
+
+    virtual void erase(const std::vector<Arc>& arcs) {
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        --_deg[_digraph.target(arcs[i])];
+      }
+    }
+
+    virtual void build() {
+      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
+        _deg[it] = countInArcs(_digraph, it);
+      }
+    }
+
+    virtual void clear() {
+      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
+        _deg[it] = 0;
+      }
+    }
+  private:
+
+    const Digraph& _digraph;
+    AutoNodeMap _deg;
+  };
+
+  /// \brief Map of the out-degrees of nodes in a digraph.
+  ///
+  /// This map returns the out-degree of a node. Once it is constructed,
+  /// the degrees are stored in a standard \c NodeMap, so each query is done
+  /// in constant time. On the other hand, the values are updated automatically
+  /// whenever the digraph changes.
+  ///
+  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
+  /// may provide alternative ways to modify the digraph.
+  /// The correct behavior of OutDegMap is not guarantied if these additional
+  /// features are used. For example, the functions
+  /// \ref ListDigraph::changeSource() "changeSource()",
+  /// \ref ListDigraph::changeTarget() "changeTarget()" and
+  /// \ref ListDigraph::reverseArc() "reverseArc()"
+  /// of \ref ListDigraph will \e not update the degree values correctly.
+  ///
+  /// \sa InDegMap
+  template <typename GR>
+  class OutDegMap
+    : protected ItemSetTraits<GR, typename GR::Arc>
+      ::ItemNotifier::ObserverBase {
+
+  public:
+
+    /// The graph type of OutDegMap
+    typedef GR Graph;
+    typedef GR Digraph;
+    /// The key type
+    typedef typename Digraph::Node Key;
+    /// The value type
+    typedef int Value;
+
+    typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
+    ::ItemNotifier::ObserverBase Parent;
+
+  private:
+
+    class AutoNodeMap
+      : public ItemSetTraits<Digraph, Key>::template Map<int>::Type {
+    public:
+
+      typedef typename ItemSetTraits<Digraph, Key>::
+      template Map<int>::Type Parent;
+
+      AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {}
+
+      virtual void add(const Key& key) {
+        Parent::add(key);
+        Parent::set(key, 0);
+      }
+      virtual void add(const std::vector<Key>& keys) {
+        Parent::add(keys);
+        for (int i = 0; i < int(keys.size()); ++i) {
+          Parent::set(keys[i], 0);
+        }
+      }
+      virtual void build() {
+        Parent::build();
+        Key it;
+        typename Parent::Notifier* nf = Parent::notifier();
+        for (nf->first(it); it != INVALID; nf->next(it)) {
+          Parent::set(it, 0);
+        }
+      }
+    };
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor for creating an out-degree map.
+    explicit OutDegMap(const Digraph& graph)
+      : _digraph(graph), _deg(graph) {
+      Parent::attach(_digraph.notifier(typename Digraph::Arc()));
+
+      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
+        _deg[it] = countOutArcs(_digraph, it);
+      }
+    }
+
+    /// \brief Gives back the out-degree of a Node.
+    ///
+    /// Gives back the out-degree of a Node.
+    int operator[](const Key& key) const {
+      return _deg[key];
+    }
+
+  protected:
+
+    typedef typename Digraph::Arc Arc;
+
+    virtual void add(const Arc& arc) {
+      ++_deg[_digraph.source(arc)];
+    }
+
+    virtual void add(const std::vector<Arc>& arcs) {
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        ++_deg[_digraph.source(arcs[i])];
+      }
+    }
+
+    virtual void erase(const Arc& arc) {
+      --_deg[_digraph.source(arc)];
+    }
+
+    virtual void erase(const std::vector<Arc>& arcs) {
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        --_deg[_digraph.source(arcs[i])];
+      }
+    }
+
+    virtual void build() {
+      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
+        _deg[it] = countOutArcs(_digraph, it);
+      }
+    }
+
+    virtual void clear() {
+      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
+        _deg[it] = 0;
+      }
+    }
+  private:
+
+    const Digraph& _digraph;
+    AutoNodeMap _deg;
+  };
+
+  /// \brief Potential difference map
+  ///
+  /// PotentialDifferenceMap returns the difference between the potentials of
+  /// the source and target nodes of each arc in a digraph, i.e. it returns
+  /// \code
+  ///   potential[gr.target(arc)] - potential[gr.source(arc)].
+  /// \endcode
+  /// \tparam GR The digraph type.
+  /// \tparam POT A node map storing the potentials.
+  template <typename GR, typename POT>
+  class PotentialDifferenceMap {
+  public:
+    /// Key type
+    typedef typename GR::Arc Key;
+    /// Value type
+    typedef typename POT::Value Value;
+
+    /// \brief Constructor
+    ///
+    /// Contructor of the map.
+    explicit PotentialDifferenceMap(const GR& gr,
+                                    const POT& potential)
+      : _digraph(gr), _potential(potential) {}
+
+    /// \brief Returns the potential difference for the given arc.
+    ///
+    /// Returns the potential difference for the given arc, i.e.
+    /// \code
+    ///   potential[gr.target(arc)] - potential[gr.source(arc)].
+    /// \endcode
+    Value operator[](const Key& arc) const {
+      return _potential[_digraph.target(arc)] -
+        _potential[_digraph.source(arc)];
+    }
+
+  private:
+    const GR& _digraph;
+    const POT& _potential;
+  };
+
+  /// \brief Returns a PotentialDifferenceMap.
+  ///
+  /// This function just returns a PotentialDifferenceMap.
+  /// \relates PotentialDifferenceMap
+  template <typename GR, typename POT>
+  PotentialDifferenceMap<GR, POT>
+  potentialDifferenceMap(const GR& gr, const POT& potential) {
+    return PotentialDifferenceMap<GR, POT>(gr, potential);
+  }
+
+
+  /// \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);
+    }
+  }
+
+  /// @}
+}
+
+#endif // LEMON_MAPS_H
diff --git a/lemon/matching.h b/lemon/matching.h
new file mode 100644
index 0000000..5ee2341
--- /dev/null
+++ b/lemon/matching.h
@@ -0,0 +1,3505 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_MATCHING_H
+#define LEMON_MATCHING_H
+
+#include <vector>
+#include <queue>
+#include <set>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/unionfind.h>
+#include <lemon/bin_heap.h>
+#include <lemon/maps.h>
+#include <lemon/fractional_matching.h>
+
+///\ingroup matching
+///\file
+///\brief Maximum matching algorithms in general graphs.
+
+namespace lemon {
+
+  /// \ingroup matching
+  ///
+  /// \brief Maximum cardinality matching in general graphs
+  ///
+  /// This class implements Edmonds' alternating forest matching algorithm
+  /// for finding a maximum cardinality matching in a general undirected graph.
+  /// It can be started from an arbitrary initial matching
+  /// (the default is the empty one).
+  ///
+  /// The dual solution of the problem is a map of the nodes to
+  /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
+  /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
+  /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
+  /// with factor-critical components, the nodes in \c ODD/A form the
+  /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
+  /// a perfect matching. The number of the factor-critical components
+  /// minus the number of barrier nodes is a lower bound on the
+  /// unmatched nodes, and the matching is optimal if and only if this bound is
+  /// tight. This decomposition can be obtained using \ref status() or
+  /// \ref statusMap() after running the algorithm.
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  template <typename GR>
+  class MaxMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    ///\brief Status constants for Gallai-Edmonds decomposition.
+    ///
+    ///These constants are used for indicating the Gallai-Edmonds
+    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
+    ///induce a subgraph with factor-critical components, the nodes with
+    ///status \c ODD (or \c A) form the canonical barrier, and the nodes
+    ///with status \c MATCHED (or \c C) induce a subgraph having a
+    ///perfect matching.
+    enum Status {
+      EVEN = 1,       ///< = 1. (\c D is an alias for \c EVEN.)
+      D = 1,
+      MATCHED = 0,    ///< = 0. (\c C is an alias for \c MATCHED.)
+      C = 0,
+      ODD = -1,       ///< = -1. (\c A is an alias for \c ODD.)
+      A = -1,
+      UNMATCHED = -2  ///< = -2.
+    };
+
+    /// The type of the status map
+    typedef typename Graph::template NodeMap<Status> StatusMap;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef UnionFindEnum<IntNodeMap> BlossomSet;
+    typedef ExtendFindEnum<IntNodeMap> TreeSet;
+    typedef RangeMap<Node> NodeIntMap;
+    typedef MatchingMap EarMap;
+    typedef std::vector<Node> NodeQueue;
+
+    const Graph& _graph;
+    MatchingMap* _matching;
+    StatusMap* _status;
+
+    EarMap* _ear;
+
+    IntNodeMap* _blossom_set_index;
+    BlossomSet* _blossom_set;
+    NodeIntMap* _blossom_rep;
+
+    IntNodeMap* _tree_set_index;
+    TreeSet* _tree_set;
+
+    NodeQueue _node_queue;
+    int _process, _postpone, _last;
+
+    int _node_num;
+
+  private:
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_status) {
+        _status = new StatusMap(_graph);
+      }
+      if (!_ear) {
+        _ear = new EarMap(_graph);
+      }
+      if (!_blossom_set) {
+        _blossom_set_index = new IntNodeMap(_graph);
+        _blossom_set = new BlossomSet(*_blossom_set_index);
+      }
+      if (!_blossom_rep) {
+        _blossom_rep = new NodeIntMap(_node_num);
+      }
+      if (!_tree_set) {
+        _tree_set_index = new IntNodeMap(_graph);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      _node_queue.resize(_node_num);
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_status) {
+        delete _status;
+      }
+      if (_ear) {
+        delete _ear;
+      }
+      if (_blossom_set) {
+        delete _blossom_set;
+        delete _blossom_set_index;
+      }
+      if (_blossom_rep) {
+        delete _blossom_rep;
+      }
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+    }
+
+    void processDense(const Node& n) {
+      _process = _postpone = _last = 0;
+      _node_queue[_last++] = n;
+
+      while (_process != _last) {
+        Node u = _node_queue[_process++];
+        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
+          Node v = _graph.target(a);
+          if ((*_status)[v] == MATCHED) {
+            extendOnArc(a);
+          } else if ((*_status)[v] == UNMATCHED) {
+            augmentOnArc(a);
+            return;
+          }
+        }
+      }
+
+      while (_postpone != _last) {
+        Node u = _node_queue[_postpone++];
+
+        for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
+          Node v = _graph.target(a);
+
+          if ((*_status)[v] == EVEN) {
+            if (_blossom_set->find(u) != _blossom_set->find(v)) {
+              shrinkOnEdge(a);
+            }
+          }
+
+          while (_process != _last) {
+            Node w = _node_queue[_process++];
+            for (OutArcIt b(_graph, w); b != INVALID; ++b) {
+              Node x = _graph.target(b);
+              if ((*_status)[x] == MATCHED) {
+                extendOnArc(b);
+              } else if ((*_status)[x] == UNMATCHED) {
+                augmentOnArc(b);
+                return;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    void processSparse(const Node& n) {
+      _process = _last = 0;
+      _node_queue[_last++] = n;
+      while (_process != _last) {
+        Node u = _node_queue[_process++];
+        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
+          Node v = _graph.target(a);
+
+          if ((*_status)[v] == EVEN) {
+            if (_blossom_set->find(u) != _blossom_set->find(v)) {
+              shrinkOnEdge(a);
+            }
+          } else if ((*_status)[v] == MATCHED) {
+            extendOnArc(a);
+          } else if ((*_status)[v] == UNMATCHED) {
+            augmentOnArc(a);
+            return;
+          }
+        }
+      }
+    }
+
+    void shrinkOnEdge(const Edge& e) {
+      Node nca = INVALID;
+
+      {
+        std::set<Node> left_set, right_set;
+
+        Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
+        left_set.insert(left);
+
+        Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
+        right_set.insert(right);
+
+        while (true) {
+          if ((*_matching)[left] == INVALID) break;
+          left = _graph.target((*_matching)[left]);
+          left = (*_blossom_rep)[_blossom_set->
+                                 find(_graph.target((*_ear)[left]))];
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+          left_set.insert(left);
+
+          if ((*_matching)[right] == INVALID) break;
+          right = _graph.target((*_matching)[right]);
+          right = (*_blossom_rep)[_blossom_set->
+                                  find(_graph.target((*_ear)[right]))];
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+          right_set.insert(right);
+        }
+
+        if (nca == INVALID) {
+          if ((*_matching)[left] == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              nca =(*_blossom_rep)[_blossom_set->
+                                   find(_graph.target((*_ear)[nca]))];
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              nca = (*_blossom_rep)[_blossom_set->
+                                   find(_graph.target((*_ear)[nca]))];
+            }
+          }
+        }
+      }
+
+      {
+
+        Node node = _graph.u(e);
+        Arc arc = _graph.direct(e, true);
+        Node base = (*_blossom_rep)[_blossom_set->find(node)];
+
+        while (base != nca) {
+          (*_ear)[node] = arc;
+
+          Node n = node;
+          while (n != base) {
+            n = _graph.target((*_matching)[n]);
+            Arc a = (*_ear)[n];
+            n = _graph.target(a);
+            (*_ear)[n] = _graph.oppositeArc(a);
+          }
+          node = _graph.target((*_matching)[base]);
+          _tree_set->erase(base);
+          _tree_set->erase(node);
+          _blossom_set->insert(node, _blossom_set->find(base));
+          (*_status)[node] = EVEN;
+          _node_queue[_last++] = node;
+          arc = _graph.oppositeArc((*_ear)[node]);
+          node = _graph.target((*_ear)[node]);
+          base = (*_blossom_rep)[_blossom_set->find(node)];
+          _blossom_set->join(_graph.target(arc), base);
+        }
+      }
+
+      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
+
+      {
+
+        Node node = _graph.v(e);
+        Arc arc = _graph.direct(e, false);
+        Node base = (*_blossom_rep)[_blossom_set->find(node)];
+
+        while (base != nca) {
+          (*_ear)[node] = arc;
+
+          Node n = node;
+          while (n != base) {
+            n = _graph.target((*_matching)[n]);
+            Arc a = (*_ear)[n];
+            n = _graph.target(a);
+            (*_ear)[n] = _graph.oppositeArc(a);
+          }
+          node = _graph.target((*_matching)[base]);
+          _tree_set->erase(base);
+          _tree_set->erase(node);
+          _blossom_set->insert(node, _blossom_set->find(base));
+          (*_status)[node] = EVEN;
+          _node_queue[_last++] = node;
+          arc = _graph.oppositeArc((*_ear)[node]);
+          node = _graph.target((*_ear)[node]);
+          base = (*_blossom_rep)[_blossom_set->find(node)];
+          _blossom_set->join(_graph.target(arc), base);
+        }
+      }
+
+      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
+    }
+
+    void extendOnArc(const Arc& a) {
+      Node base = _graph.source(a);
+      Node odd = _graph.target(a);
+
+      (*_ear)[odd] = _graph.oppositeArc(a);
+      Node even = _graph.target((*_matching)[odd]);
+      (*_blossom_rep)[_blossom_set->insert(even)] = even;
+      (*_status)[odd] = ODD;
+      (*_status)[even] = EVEN;
+      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
+      _tree_set->insert(odd, tree);
+      _tree_set->insert(even, tree);
+      _node_queue[_last++] = even;
+
+    }
+
+    void augmentOnArc(const Arc& a) {
+      Node even = _graph.source(a);
+      Node odd = _graph.target(a);
+
+      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
+
+      (*_matching)[odd] = _graph.oppositeArc(a);
+      (*_status)[odd] = MATCHED;
+
+      Arc arc = (*_matching)[even];
+      (*_matching)[even] = a;
+
+      while (arc != INVALID) {
+        odd = _graph.target(arc);
+        arc = (*_ear)[odd];
+        even = _graph.target(arc);
+        (*_matching)[odd] = arc;
+        arc = (*_matching)[even];
+        (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]);
+      }
+
+      for (typename TreeSet::ItemIt it(*_tree_set, tree);
+           it != INVALID; ++it) {
+        if ((*_status)[it] == ODD) {
+          (*_status)[it] = MATCHED;
+        } else {
+          int blossom = _blossom_set->find(it);
+          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
+               jt != INVALID; ++jt) {
+            (*_status)[jt] = MATCHED;
+          }
+          _blossom_set->eraseClass(blossom);
+        }
+      }
+      _tree_set->eraseClass(tree);
+
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxMatching(const Graph& graph)
+      : _graph(graph), _matching(0), _status(0), _ear(0),
+        _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
+        _tree_set_index(0), _tree_set(0) {}
+
+    ~MaxMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \c run() member function.\n
+    /// If you need better control on the execution, you have to call
+    /// one of the functions \ref init(), \ref greedyInit() or
+    /// \ref matchingInit() first, then you can start the algorithm with
+    /// \ref startSparse() or \ref startDense().
+
+    ///@{
+
+    /// \brief Set the initial matching to the empty matching.
+    ///
+    /// This function sets the initial matching to the empty matching.
+    void init() {
+      createStructures();
+      for(NodeIt n(_graph); n != INVALID; ++n) {
+        (*_matching)[n] = INVALID;
+        (*_status)[n] = UNMATCHED;
+      }
+    }
+
+    /// \brief Find an initial matching in a greedy way.
+    ///
+    /// This function finds an initial matching in a greedy way.
+    void greedyInit() {
+      createStructures();
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_matching)[n] = INVALID;
+        (*_status)[n] = UNMATCHED;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] == INVALID) {
+          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
+            Node v = _graph.target(a);
+            if ((*_matching)[v] == INVALID && v != n) {
+              (*_matching)[n] = a;
+              (*_status)[n] = MATCHED;
+              (*_matching)[v] = _graph.oppositeArc(a);
+              (*_status)[v] = MATCHED;
+              break;
+            }
+          }
+        }
+      }
+    }
+
+
+    /// \brief Initialize the matching from a map.
+    ///
+    /// This function initializes the matching from a \c bool valued edge
+    /// map. This map should have the property that there are no two incident
+    /// edges with \c true value, i.e. it really contains a matching.
+    /// \return \c true if the map contains a matching.
+    template <typename MatchingMap>
+    bool matchingInit(const MatchingMap& matching) {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_matching)[n] = INVALID;
+        (*_status)[n] = UNMATCHED;
+      }
+      for(EdgeIt e(_graph); e!=INVALID; ++e) {
+        if (matching[e]) {
+
+          Node u = _graph.u(e);
+          if ((*_matching)[u] != INVALID) return false;
+          (*_matching)[u] = _graph.direct(e, true);
+          (*_status)[u] = MATCHED;
+
+          Node v = _graph.v(e);
+          if ((*_matching)[v] != INVALID) return false;
+          (*_matching)[v] = _graph.direct(e, false);
+          (*_status)[v] = MATCHED;
+        }
+      }
+      return true;
+    }
+
+    /// \brief Start Edmonds' algorithm
+    ///
+    /// This function runs the original Edmonds' algorithm.
+    ///
+    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
+    /// called before using this function.
+    void startSparse() {
+      for(NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_status)[n] == UNMATCHED) {
+          (*_blossom_rep)[_blossom_set->insert(n)] = n;
+          _tree_set->insert(n);
+          (*_status)[n] = EVEN;
+          processSparse(n);
+        }
+      }
+    }
+
+    /// \brief Start Edmonds' algorithm with a heuristic improvement
+    /// for dense graphs
+    ///
+    /// This function runs Edmonds' algorithm with a heuristic of postponing
+    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
+    ///
+    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
+    /// called before using this function.
+    void startDense() {
+      for(NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_status)[n] == UNMATCHED) {
+          (*_blossom_rep)[_blossom_set->insert(n)] = n;
+          _tree_set->insert(n);
+          (*_status)[n] = EVEN;
+          processDense(n);
+        }
+      }
+    }
+
+
+    /// \brief Run Edmonds' algorithm
+    ///
+    /// This function runs Edmonds' algorithm. An additional heuristic of
+    /// postponing shrinks is used for relatively dense graphs
+    /// (for which <tt>m>=2*n</tt> holds).
+    void run() {
+      if (countEdges(_graph) < 2 * countNodes(_graph)) {
+        greedyInit();
+        startSparse();
+      } else {
+        init();
+        startDense();
+      }
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum matching.
+
+    /// @{
+
+    /// \brief Return the size (cardinality) of the matching.
+    ///
+    /// This function returns the size (cardinality) of the current matching.
+    /// After run() it returns the size of the maximum matching in the graph.
+    int matchingSize() const {
+      int size = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++size;
+        }
+      }
+      return size / 2;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the current
+    /// matching.
+    bool matching(const Edge& edge) const {
+      return edge == (*_matching)[_graph.u(edge)];
+    }
+
+    /// \brief Return the matching arc (or edge) incident to the given node.
+    ///
+    /// This function returns the matching arc (or edge) incident to the
+    /// given node in the current matching or \c INVALID if the node is
+    /// not covered by the matching.
+    Arc matching(const Node& n) const {
+      return (*_matching)[n];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return the mate of the given node.
+    ///
+    /// This function returns the mate of the given node in the current
+    /// matching or \c INVALID if the node is not covered by the matching.
+    Node mate(const Node& n) const {
+      return (*_matching)[n] != INVALID ?
+        _graph.target((*_matching)[n]) : INVALID;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution, i.e. the Gallai-Edmonds
+    /// decomposition.
+
+    /// @{
+
+    /// \brief Return the status of the given node in the Edmonds-Gallai
+    /// decomposition.
+    ///
+    /// This function returns the \ref Status "status" of the given node
+    /// in the Edmonds-Gallai decomposition.
+    Status status(const Node& n) const {
+      return (*_status)[n];
+    }
+
+    /// \brief Return a const reference to the status map, which stores
+    /// the Edmonds-Gallai decomposition.
+    ///
+    /// This function returns a const reference to a node map that stores the
+    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
+    const StatusMap& statusMap() const {
+      return *_status;
+    }
+
+    /// \brief Return \c true if the given node is in the barrier.
+    ///
+    /// This function returns \c true if the given node is in the barrier.
+    bool barrier(const Node& n) const {
+      return (*_status)[n] == ODD;
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted matching in general graphs
+  ///
+  /// This class provides an efficient implementation of Edmond's
+  /// maximum weighted matching algorithm. The implementation is based
+  /// on extensive use of priority queues and provides
+  /// \f$O(nm\log n)\f$ time complexity.
+  ///
+  /// The maximum weighted matching problem is to find a subset of the
+  /// edges in an undirected graph with maximum overall weight for which
+  /// each node has at most one incident edge.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
+  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
+      \quad \forall B\in\mathcal{O}\f] */
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_ew_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
+  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
+  /// subsets of the nodes.
+  ///
+  /// The algorithm calculates an optimal matching and a proof of the
+  /// optimality. The solution of the dual problem can be used to check
+  /// the result of the algorithm. The dual linear problem is the
+  /// following.
+  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
+      z_B \ge w_{uv} \quad \forall uv\in E\f] */
+  /// \f[y_u \ge 0 \quad \forall u \in V\f]
+  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
+  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
+      \frac{\vert B \vert - 1}{2}z_B\f] */
+  ///
+  /// The algorithm can be executed with the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions and the
+  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
+  /// which is able to iterate on the nodes of a blossom.
+  /// If the value type is integer, then the dual solution is multiplied
+  /// by \ref MaxWeightedMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    /// \brief Scaling factor for dual solution
+    ///
+    /// Scaling factor for dual solution. It is equal to 4 or 1
+    /// according to the value type.
+    static const int dualScale =
+      std::numeric_limits<Value>::is_integer ? 4 : 1;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+    typedef std::vector<Node> BlossomNodeList;
+
+    struct BlossomVariable {
+      int begin, end;
+      Value value;
+
+      BlossomVariable(int _begin, int _end, Value _value)
+        : begin(_begin), end(_end), value(_value) {}
+
+    };
+
+    typedef std::vector<BlossomVariable> BlossomPotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+
+    NodePotential* _node_potential;
+
+    BlossomPotential _blossom_potential;
+    BlossomNodeList _blossom_node_list;
+
+    int _node_num;
+    int _blossom_num;
+
+    typedef RangeMap<int> IntIntMap;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
+    struct BlossomData {
+      int tree;
+      Status status;
+      Arc pred, next;
+      Value pot, offset;
+      Node base;
+    };
+
+    IntNodeMap *_blossom_index;
+    BlossomSet *_blossom_set;
+    RangeMap<BlossomData>* _blossom_data;
+
+    IntNodeMap *_node_index;
+    IntArcMap *_node_heap_index;
+
+    struct NodeData {
+
+      NodeData(IntArcMap& node_heap_index)
+        : heap(node_heap_index) {}
+
+      int blossom;
+      Value pot;
+      BinHeap<Value, IntArcMap> heap;
+      std::map<int, Arc> heap_index;
+
+      int tree;
+    };
+
+    RangeMap<NodeData>* _node_data;
+
+    typedef ExtendFindEnum<IntIntMap> TreeSet;
+
+    IntIntMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntNodeMap *_delta1_index;
+    BinHeap<Value, IntNodeMap> *_delta1;
+
+    IntIntMap *_delta2_index;
+    BinHeap<Value, IntIntMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    IntIntMap *_delta4_index;
+    BinHeap<Value, IntIntMap> *_delta4;
+
+    Value _delta_sum;
+    int _unmatched;
+
+    typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
+    FractionalMatching *_fractional;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+      _blossom_num = _node_num * 3 / 2;
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+
+      if (!_blossom_set) {
+        _blossom_index = new IntNodeMap(_graph);
+        _blossom_set = new BlossomSet(*_blossom_index);
+        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
+      } else if (_blossom_data->size() != _blossom_num) {
+        delete _blossom_data;
+        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
+      }
+
+      if (!_node_index) {
+        _node_index = new IntNodeMap(_graph);
+        _node_heap_index = new IntArcMap(_graph);
+        _node_data = new RangeMap<NodeData>(_node_num,
+                                            NodeData(*_node_heap_index));
+      } else {
+        delete _node_data;
+        _node_data = new RangeMap<NodeData>(_node_num,
+                                            NodeData(*_node_heap_index));
+      }
+
+      if (!_tree_set) {
+        _tree_set_index = new IntIntMap(_blossom_num);
+        _tree_set = new TreeSet(*_tree_set_index);
+      } else {
+        _tree_set_index->resize(_blossom_num);
+      }
+
+      if (!_delta1) {
+        _delta1_index = new IntNodeMap(_graph);
+        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
+      }
+
+      if (!_delta2) {
+        _delta2_index = new IntIntMap(_blossom_num);
+        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
+      } else {
+        _delta2_index->resize(_blossom_num);
+      }
+
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+
+      if (!_delta4) {
+        _delta4_index = new IntIntMap(_blossom_num);
+        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
+      } else {
+        _delta4_index->resize(_blossom_num);
+      }
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_blossom_set) {
+        delete _blossom_index;
+        delete _blossom_set;
+        delete _blossom_data;
+      }
+
+      if (_node_index) {
+        delete _node_index;
+        delete _node_heap_index;
+        delete _node_data;
+      }
+
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta1) {
+        delete _delta1_index;
+        delete _delta1;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+      if (_delta4) {
+        delete _delta4_index;
+        delete _delta4;
+      }
+    }
+
+    void matchedToEven(int blossom, int tree) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      if (!_blossom_set->trivial(blossom)) {
+        (*_blossom_data)[blossom].pot -=
+          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+        int ni = (*_node_index)[n];
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+
+        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
+
+        _delta1->push(n, (*_node_data)[ni].pot);
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
+              _delta3->push(e, rw / 2);
+            }
+          } else {
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              if ((*_node_data)[vi].heap[it->second] > rw) {
+                (*_node_data)[vi].heap.replace(it->second, e);
+                (*_node_data)[vi].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[vi].heap.push(e, rw);
+              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
+            }
+
+            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
+              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_delta2->state(vb) != _delta2->IN_HEAP) {
+                  _delta2->push(vb, _blossom_set->classPrio(vb) -
+                               (*_blossom_data)[vb].offset);
+                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+      (*_blossom_data)[blossom].offset = 0;
+    }
+
+    void matchedToOdd(int blossom) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+      (*_blossom_data)[blossom].offset += _delta_sum;
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
+                      (*_blossom_data)[blossom].offset);
+      }
+    }
+
+    void evenToMatched(int blossom, int tree) {
+      if (!_blossom_set->trivial(blossom)) {
+        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+        (*_node_data)[ni].pot -= _delta_sum;
+
+        _delta1->erase(n);
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if (vb == blossom) {
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+          } else if ((*_blossom_data)[vb].status == EVEN) {
+
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+
+            int vt = _tree_set->find(vb);
+
+            if (vt != tree) {
+
+              Arc r = _graph.oppositeArc(e);
+
+              typename std::map<int, Arc>::iterator it =
+                (*_node_data)[ni].heap_index.find(vt);
+
+              if (it != (*_node_data)[ni].heap_index.end()) {
+                if ((*_node_data)[ni].heap[it->second] > rw) {
+                  (*_node_data)[ni].heap.replace(it->second, r);
+                  (*_node_data)[ni].heap.decrease(r, rw);
+                  it->second = r;
+                }
+              } else {
+                (*_node_data)[ni].heap.push(r, rw);
+                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
+              }
+
+              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
+                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+
+                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
+                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                               (*_blossom_data)[blossom].offset);
+                } else if ((*_delta2)[blossom] >
+                           _blossom_set->classPrio(blossom) -
+                           (*_blossom_data)[blossom].offset){
+                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
+                                   (*_blossom_data)[blossom].offset);
+                }
+              }
+            }
+          } else {
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              (*_node_data)[vi].heap.erase(it->second);
+              (*_node_data)[vi].heap_index.erase(it);
+              if ((*_node_data)[vi].heap.empty()) {
+                _blossom_set->increase(v, std::numeric_limits<Value>::max());
+              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
+                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
+              }
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_blossom_set->classPrio(vb) ==
+                    std::numeric_limits<Value>::max()) {
+                  _delta2->erase(vb);
+                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    void oddToMatched(int blossom) {
+      (*_blossom_data)[blossom].offset -= _delta_sum;
+
+      if (_blossom_set->classPrio(blossom) !=
+          std::numeric_limits<Value>::max()) {
+        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                      (*_blossom_data)[blossom].offset);
+      }
+
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->erase(blossom);
+      }
+    }
+
+    void oddToEven(int blossom, int tree) {
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->erase(blossom);
+        (*_blossom_data)[blossom].pot -=
+          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+        (*_node_data)[ni].pot +=
+          2 * _delta_sum - (*_blossom_data)[blossom].offset;
+
+        _delta1->push(n, (*_node_data)[ni].pot);
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
+              _delta3->push(e, rw / 2);
+            }
+          } else {
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              if ((*_node_data)[vi].heap[it->second] > rw) {
+                (*_node_data)[vi].heap.replace(it->second, e);
+                (*_node_data)[vi].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[vi].heap.push(e, rw);
+              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
+            }
+
+            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
+              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_delta2->state(vb) != _delta2->IN_HEAP) {
+                  _delta2->push(vb, _blossom_set->classPrio(vb) -
+                               (*_blossom_data)[vb].offset);
+                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+      (*_blossom_data)[blossom].offset = 0;
+    }
+
+    void alternatePath(int even, int tree) {
+      int odd;
+
+      evenToMatched(even, tree);
+      (*_blossom_data)[even].status = MATCHED;
+
+      while ((*_blossom_data)[even].pred != INVALID) {
+        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
+        (*_blossom_data)[odd].status = MATCHED;
+        oddToMatched(odd);
+        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
+
+        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
+        (*_blossom_data)[even].status = MATCHED;
+        evenToMatched(even, tree);
+        (*_blossom_data)[even].next =
+          _graph.oppositeArc((*_blossom_data)[odd].pred);
+      }
+
+    }
+
+    void destroyTree(int tree) {
+      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
+        if ((*_blossom_data)[b].status == EVEN) {
+          (*_blossom_data)[b].status = MATCHED;
+          evenToMatched(b, tree);
+        } else if ((*_blossom_data)[b].status == ODD) {
+          (*_blossom_data)[b].status = MATCHED;
+          oddToMatched(b);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+
+    void unmatchNode(const Node& node) {
+      int blossom = _blossom_set->find(node);
+      int tree = _tree_set->find(blossom);
+
+      alternatePath(blossom, tree);
+      destroyTree(tree);
+
+      (*_blossom_data)[blossom].base = node;
+      (*_blossom_data)[blossom].next = INVALID;
+    }
+
+    void augmentOnEdge(const Edge& edge) {
+
+      int left = _blossom_set->find(_graph.u(edge));
+      int right = _blossom_set->find(_graph.v(edge));
+
+      int left_tree = _tree_set->find(left);
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+
+      (*_blossom_data)[left].next = _graph.direct(edge, true);
+      (*_blossom_data)[right].next = _graph.direct(edge, false);
+    }
+
+    void augmentOnArc(const Arc& arc) {
+
+      int left = _blossom_set->find(_graph.source(arc));
+      int right = _blossom_set->find(_graph.target(arc));
+
+      (*_blossom_data)[left].status = MATCHED;
+
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+
+      (*_blossom_data)[left].next = arc;
+      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
+    }
+
+    void extendOnArc(const Arc& arc) {
+      int base = _blossom_set->find(_graph.target(arc));
+      int tree = _tree_set->find(base);
+
+      int odd = _blossom_set->find(_graph.source(arc));
+      _tree_set->insert(odd, tree);
+      (*_blossom_data)[odd].status = ODD;
+      matchedToOdd(odd);
+      (*_blossom_data)[odd].pred = arc;
+
+      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
+      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
+      _tree_set->insert(even, tree);
+      (*_blossom_data)[even].status = EVEN;
+      matchedToEven(even, tree);
+    }
+
+    void shrinkOnEdge(const Edge& edge, int tree) {
+      int nca = -1;
+      std::vector<int> left_path, right_path;
+
+      {
+        std::set<int> left_set, right_set;
+        int left = _blossom_set->find(_graph.u(edge));
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        int right = _blossom_set->find(_graph.v(edge));
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if ((*_blossom_data)[left].pred == INVALID) break;
+
+          left =
+            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
+          left_path.push_back(left);
+          left =
+            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_blossom_data)[right].pred == INVALID) break;
+
+          right =
+            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
+          right_path.push_back(right);
+          right =
+            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
+          right_path.push_back(right);
+
+          right_set.insert(right);
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+        }
+
+        if (nca == -1) {
+          if ((*_blossom_data)[left].pred == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              right_path.push_back(nca);
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              left_path.push_back(nca);
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      std::vector<int> subblossoms;
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        subblossoms.push_back(left_path[i]);
+        (*_blossom_data)[left_path[i]].next = prev;
+        _tree_set->erase(left_path[i]);
+
+        subblossoms.push_back(left_path[i + 1]);
+        (*_blossom_data)[left_path[i + 1]].status = EVEN;
+        oddToEven(left_path[i + 1], tree);
+        _tree_set->erase(left_path[i + 1]);
+        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
+      }
+
+      int k = 0;
+      while (right_path[k] != nca) ++k;
+
+      subblossoms.push_back(nca);
+      (*_blossom_data)[nca].next = prev;
+
+      for (int i = k - 2; i >= 0; i -= 2) {
+        subblossoms.push_back(right_path[i + 1]);
+        (*_blossom_data)[right_path[i + 1]].status = EVEN;
+        oddToEven(right_path[i + 1], tree);
+        _tree_set->erase(right_path[i + 1]);
+
+        (*_blossom_data)[right_path[i + 1]].next =
+          (*_blossom_data)[right_path[i + 1]].pred;
+
+        subblossoms.push_back(right_path[i]);
+        _tree_set->erase(right_path[i]);
+      }
+
+      int surface =
+        _blossom_set->join(subblossoms.begin(), subblossoms.end());
+
+      for (int i = 0; i < int(subblossoms.size()); ++i) {
+        if (!_blossom_set->trivial(subblossoms[i])) {
+          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
+        }
+        (*_blossom_data)[subblossoms[i]].status = MATCHED;
+      }
+
+      (*_blossom_data)[surface].pot = -2 * _delta_sum;
+      (*_blossom_data)[surface].offset = 0;
+      (*_blossom_data)[surface].status = EVEN;
+      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
+      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
+
+      _tree_set->insert(surface, tree);
+      _tree_set->erase(nca);
+    }
+
+    void splitBlossom(int blossom) {
+      Arc next = (*_blossom_data)[blossom].next;
+      Arc pred = (*_blossom_data)[blossom].pred;
+
+      int tree = _tree_set->find(blossom);
+
+      (*_blossom_data)[blossom].status = MATCHED;
+      oddToMatched(blossom);
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      std::vector<int> subblossoms;
+      _blossom_set->split(blossom, std::back_inserter(subblossoms));
+
+      Value offset = (*_blossom_data)[blossom].offset;
+      int b = _blossom_set->find(_graph.source(pred));
+      int d = _blossom_set->find(_graph.source(next));
+
+      int ib = -1, id = -1;
+      for (int i = 0; i < int(subblossoms.size()); ++i) {
+        if (subblossoms[i] == b) ib = i;
+        if (subblossoms[i] == d) id = i;
+
+        (*_blossom_data)[subblossoms[i]].offset = offset;
+        if (!_blossom_set->trivial(subblossoms[i])) {
+          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
+        }
+        if (_blossom_set->classPrio(subblossoms[i]) !=
+            std::numeric_limits<Value>::max()) {
+          _delta2->push(subblossoms[i],
+                        _blossom_set->classPrio(subblossoms[i]) -
+                        (*_blossom_data)[subblossoms[i]].offset);
+        }
+      }
+
+      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
+        for (int i = (id + 1) % subblossoms.size();
+             i != ib; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+        }
+
+        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          int ub = subblossoms[(i + 2) % subblossoms.size()];
+
+          (*_blossom_data)[sb].status = ODD;
+          matchedToOdd(sb);
+          _tree_set->insert(sb, tree);
+          (*_blossom_data)[sb].pred = pred;
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+
+          pred = (*_blossom_data)[ub].next;
+
+          (*_blossom_data)[tb].status = EVEN;
+          matchedToEven(tb, tree);
+          _tree_set->insert(tb, tree);
+          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
+        }
+
+        (*_blossom_data)[subblossoms[id]].status = ODD;
+        matchedToOdd(subblossoms[id]);
+        _tree_set->insert(subblossoms[id], tree);
+        (*_blossom_data)[subblossoms[id]].next = next;
+        (*_blossom_data)[subblossoms[id]].pred = pred;
+
+      } else {
+
+        for (int i = (ib + 1) % subblossoms.size();
+             i != id; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+        }
+
+        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          int ub = subblossoms[(i + 2) % subblossoms.size()];
+
+          (*_blossom_data)[sb].status = ODD;
+          matchedToOdd(sb);
+          _tree_set->insert(sb, tree);
+          (*_blossom_data)[sb].next = next;
+          (*_blossom_data)[sb].pred =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+
+          (*_blossom_data)[tb].status = EVEN;
+          matchedToEven(tb, tree);
+          _tree_set->insert(tb, tree);
+          (*_blossom_data)[tb].pred =
+            (*_blossom_data)[tb].next =
+            _graph.oppositeArc((*_blossom_data)[ub].next);
+          next = (*_blossom_data)[ub].next;
+        }
+
+        (*_blossom_data)[subblossoms[ib]].status = ODD;
+        matchedToOdd(subblossoms[ib]);
+        _tree_set->insert(subblossoms[ib], tree);
+        (*_blossom_data)[subblossoms[ib]].next = next;
+        (*_blossom_data)[subblossoms[ib]].pred = pred;
+      }
+      _tree_set->erase(blossom);
+    }
+
+    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
+      if (_blossom_set->trivial(blossom)) {
+        int bi = (*_node_index)[base];
+        Value pot = (*_node_data)[bi].pot;
+
+        (*_matching)[base] = matching;
+        _blossom_node_list.push_back(base);
+        (*_node_potential)[base] = pot;
+      } else {
+
+        Value pot = (*_blossom_data)[blossom].pot;
+        int bn = _blossom_node_list.size();
+
+        std::vector<int> subblossoms;
+        _blossom_set->split(blossom, std::back_inserter(subblossoms));
+        int b = _blossom_set->find(base);
+        int ib = -1;
+        for (int i = 0; i < int(subblossoms.size()); ++i) {
+          if (subblossoms[i] == b) { ib = i; break; }
+        }
+
+        for (int i = 1; i < int(subblossoms.size()); i += 2) {
+          int sb = subblossoms[(ib + i) % subblossoms.size()];
+          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
+
+          Arc m = (*_blossom_data)[tb].next;
+          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
+          extractBlossom(tb, _graph.source(m), m);
+        }
+        extractBlossom(subblossoms[ib], base, matching);
+
+        int en = _blossom_node_list.size();
+
+        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
+      }
+    }
+
+    void extractMatching() {
+      std::vector<int> blossoms;
+      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
+        blossoms.push_back(c);
+      }
+
+      for (int i = 0; i < int(blossoms.size()); ++i) {
+        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
+
+          Value offset = (*_blossom_data)[blossoms[i]].offset;
+          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
+          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
+               n != INVALID; ++n) {
+            (*_node_data)[(*_node_index)[n]].pot -= offset;
+          }
+
+          Arc matching = (*_blossom_data)[blossoms[i]].next;
+          Node base = _graph.source(matching);
+          extractBlossom(blossoms[i], base, matching);
+        } else {
+          Node base = (*_blossom_data)[blossoms[i]].base;
+          extractBlossom(blossoms[i], base, INVALID);
+        }
+      }
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
+      : _graph(graph), _weight(weight), _matching(0),
+        _node_potential(0), _blossom_potential(), _blossom_node_list(),
+        _node_num(0), _blossom_num(0),
+
+        _blossom_index(0), _blossom_set(0), _blossom_data(0),
+        _node_index(0), _node_heap_index(0), _node_data(0),
+        _tree_set_index(0), _tree_set(0),
+
+        _delta1_index(0), _delta1(0),
+        _delta2_index(0), _delta2(0),
+        _delta3_index(0), _delta3(0),
+        _delta4_index(0), _delta4(0),
+
+        _delta_sum(), _unmatched(0),
+
+        _fractional(0)
+    {}
+
+    ~MaxWeightedMatching() {
+      destroyStructures();
+      if (_fractional) {
+        delete _fractional;
+      }
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta1_index)[n] = _delta1->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = _node_num;
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = 0;
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        (*_node_index)[n] = index;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        (*_node_data)[index].pot = max;
+        _delta1->push(n, max);
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        _tree_set->insert(blossom);
+
+        (*_blossom_data)[blossom].status = EVEN;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = INVALID;
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int ti = (*_node_index)[_graph.v(e)];
+        if (_graph.u(e) != _graph.v(e)) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+    }
+
+    /// \brief Initialize the algorithm with fractional matching
+    ///
+    /// This function initializes the algorithm with a fractional
+    /// matching. This initialization is also called jumpstart heuristic.
+    void fractionalInit() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      if (_fractional == 0) {
+        _fractional = new FractionalMatching(_graph, _weight, false);
+      }
+      _fractional->run();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta1_index)[n] = _delta1->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = 0;
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value pot = _fractional->nodeValue(n);
+        (*_node_index)[n] = index;
+        (*_node_data)[index].pot = pot;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        (*_blossom_data)[blossom].status = MATCHED;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = _fractional->matching(n);
+        if (_fractional->matching(n) == INVALID) {
+          (*_blossom_data)[blossom].base = n;
+        }
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+
+      typename Graph::template NodeMap<bool> processed(_graph, false);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (processed[n]) continue;
+        processed[n] = true;
+        if (_fractional->matching(n) == INVALID) continue;
+        int num = 1;
+        Node v = _graph.target(_fractional->matching(n));
+        while (n != v) {
+          processed[v] = true;
+          v = _graph.target(_fractional->matching(v));
+          ++num;
+        }
+
+        if (num % 2 == 1) {
+          std::vector<int> subblossoms(num);
+
+          subblossoms[--num] = _blossom_set->find(n);
+          _delta1->push(n, _fractional->nodeValue(n));
+          v = _graph.target(_fractional->matching(n));
+          while (n != v) {
+            subblossoms[--num] = _blossom_set->find(v);
+            _delta1->push(v, _fractional->nodeValue(v));
+            v = _graph.target(_fractional->matching(v));
+          }
+
+          int surface =
+            _blossom_set->join(subblossoms.begin(), subblossoms.end());
+          (*_blossom_data)[surface].status = EVEN;
+          (*_blossom_data)[surface].pred = INVALID;
+          (*_blossom_data)[surface].next = INVALID;
+          (*_blossom_data)[surface].pot = 0;
+          (*_blossom_data)[surface].offset = 0;
+
+          _tree_set->insert(surface);
+          ++_unmatched;
+        }
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int sb = _blossom_set->find(_graph.u(e));
+        int ti = (*_node_index)[_graph.v(e)];
+        int tb = _blossom_set->find(_graph.v(e));
+        if ((*_blossom_data)[sb].status == EVEN &&
+            (*_blossom_data)[tb].status == EVEN && sb != tb) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        int nb = _blossom_set->find(n);
+        if ((*_blossom_data)[nb].status != MATCHED) continue;
+        int ni = (*_node_index)[n];
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.target(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+
+            int vt = _tree_set->find(vb);
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[ni].heap_index.find(vt);
+
+            if (it != (*_node_data)[ni].heap_index.end()) {
+              if ((*_node_data)[ni].heap[it->second] > rw) {
+                (*_node_data)[ni].heap.replace(it->second, e);
+                (*_node_data)[ni].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[ni].heap.push(e, rw);
+              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
+            }
+          }
+        }
+
+        if (!(*_node_data)[ni].heap.empty()) {
+          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+          _delta2->push(nb, _blossom_set->classPrio(nb));
+        }
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() or \ref fractionalInit() must be called
+    /// before using this function.
+    void start() {
+      enum OpType {
+        D1, D2, D3, D4
+      };
+
+      while (_unmatched > 0) {
+        Value d1 = !_delta1->empty() ?
+          _delta1->prio() : std::numeric_limits<Value>::max();
+
+        Value d2 = !_delta2->empty() ?
+          _delta2->prio() : std::numeric_limits<Value>::max();
+
+        Value d3 = !_delta3->empty() ?
+          _delta3->prio() : std::numeric_limits<Value>::max();
+
+        Value d4 = !_delta4->empty() ?
+          _delta4->prio() : std::numeric_limits<Value>::max();
+
+        _delta_sum = d3; OpType ot = D3;
+        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
+
+        switch (ot) {
+        case D1:
+          {
+            Node n = _delta1->top();
+            unmatchNode(n);
+            --_unmatched;
+          }
+          break;
+        case D2:
+          {
+            int blossom = _delta2->top();
+            Node n = _blossom_set->classTop(blossom);
+            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
+            if ((*_blossom_data)[blossom].next == INVALID) {
+              augmentOnArc(a);
+              --_unmatched;
+            } else {
+              extendOnArc(a);
+            }
+          }
+          break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            int left_blossom = _blossom_set->find(_graph.u(e));
+            int right_blossom = _blossom_set->find(_graph.v(e));
+
+            if (left_blossom == right_blossom) {
+              _delta3->pop();
+            } else {
+              int left_tree = _tree_set->find(left_blossom);
+              int right_tree = _tree_set->find(right_blossom);
+
+              if (left_tree == right_tree) {
+                shrinkOnEdge(e, left_tree);
+              } else {
+                augmentOnEdge(e);
+                _unmatched -= 2;
+              }
+            }
+          } break;
+        case D4:
+          splitBlossom(_delta4->top());
+          break;
+        }
+      }
+      extractMatching();
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedMatching algorithm.
+    ///
+    /// \note mwm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwm.fractionalInit();
+    ///   mwm.start();
+    /// \endcode
+    void run() {
+      fractionalInit();
+      start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum / 2;
+    }
+
+    /// \brief Return the size (cardinality) of the matching.
+    ///
+    /// This function returns the size (cardinality) of the found matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num /= 2;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the found
+    /// matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    bool matching(const Edge& edge) const {
+      return edge == (*_matching)[_graph.u(edge)];
+    }
+
+    /// \brief Return the matching arc (or edge) incident to the given node.
+    ///
+    /// This function returns the matching arc (or edge) incident to the
+    /// given node in the found matching or \c INVALID if the node is
+    /// not covered by the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return the mate of the given node.
+    ///
+    /// This function returns the mate of the given node in the found
+    /// matching or \c INVALID if the node is not covered by the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Node mate(const Node& node) const {
+      return (*_matching)[node] != INVALID ?
+        _graph.target((*_matching)[node]) : INVALID;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      for (int i = 0; i < blossomNum(); ++i) {
+        sum += blossomValue(i) * (blossomSize(i) / 2);
+      }
+      return sum;
+    }
+
+    /// \brief Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// \brief Return the number of the blossoms in the basis.
+    ///
+    /// This function returns the number of the blossoms in the basis.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    /// \see BlossomIt
+    int blossomNum() const {
+      return _blossom_potential.size();
+    }
+
+    /// \brief Return the number of the nodes in the given blossom.
+    ///
+    /// This function returns the number of the nodes in the given blossom.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    /// \see BlossomIt
+    int blossomSize(int k) const {
+      return _blossom_potential[k].end - _blossom_potential[k].begin;
+    }
+
+    /// \brief Return the dual value (ptential) of the given blossom.
+    ///
+    /// This function returns the dual value (ptential) of the given blossom.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value blossomValue(int k) const {
+      return _blossom_potential[k].value;
+    }
+
+    /// \brief Iterator for obtaining the nodes of a blossom.
+    ///
+    /// This class provides an iterator for obtaining the nodes of the
+    /// given blossom. It lists a subset of the nodes.
+    /// Before using this iterator, you must allocate a
+    /// MaxWeightedMatching class and execute it.
+    class BlossomIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor to get the nodes of the given variable.
+      ///
+      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
+      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
+      /// called before initializing this iterator.
+      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
+        : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_blossom_potential[variable].begin;
+        _last = _algorithm->_blossom_potential[variable].end;
+      }
+
+      /// \brief Conversion to \c Node.
+      ///
+      /// Conversion to \c Node.
+      operator Node() const {
+        return _algorithm->_blossom_node_list[_index];
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      BlossomIt& operator++() {
+        ++_index;
+        return *this;
+      }
+
+      /// \brief Validity checking
+      ///
+      /// Checks whether the iterator is invalid.
+      bool operator==(Invalid) const { return _index == _last; }
+
+      /// \brief Validity checking
+      ///
+      /// Checks whether the iterator is valid.
+      bool operator!=(Invalid) const { return _index != _last; }
+
+    private:
+      const MaxWeightedMatching* _algorithm;
+      int _last;
+      int _index;
+    };
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted perfect matching in general graphs
+  ///
+  /// This class provides an efficient implementation of Edmond's
+  /// maximum weighted perfect matching algorithm. The implementation
+  /// is based on extensive use of priority queues and provides
+  /// \f$O(nm\log n)\f$ time complexity.
+  ///
+  /// The maximum weighted perfect matching problem is to find a subset of
+  /// the edges in an undirected graph with maximum overall weight for which
+  /// each node has exactly one incident edge.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
+  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
+      \quad \forall B\in\mathcal{O}\f] */
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_ew_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
+  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
+  /// subsets of the nodes.
+  ///
+  /// The algorithm calculates an optimal matching and a proof of the
+  /// optimality. The solution of the dual problem can be used to check
+  /// the result of the algorithm. The dual linear problem is the
+  /// following.
+  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
+      w_{uv} \quad \forall uv\in E\f] */
+  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
+  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
+      \frac{\vert B \vert - 1}{2}z_B\f] */
+  ///
+  /// The algorithm can be executed with the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions and the
+  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
+  /// which is able to iterate on the nodes of a blossom.
+  /// If the value type is integer, then the dual solution is multiplied
+  /// by \ref MaxWeightedMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedPerfectMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// \brief Scaling factor for dual solution
+    ///
+    /// Scaling factor for dual solution, it is equal to 4 or 1
+    /// according to the value type.
+    static const int dualScale =
+      std::numeric_limits<Value>::is_integer ? 4 : 1;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+    typedef std::vector<Node> BlossomNodeList;
+
+    struct BlossomVariable {
+      int begin, end;
+      Value value;
+
+      BlossomVariable(int _begin, int _end, Value _value)
+        : begin(_begin), end(_end), value(_value) {}
+
+    };
+
+    typedef std::vector<BlossomVariable> BlossomPotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+
+    NodePotential* _node_potential;
+
+    BlossomPotential _blossom_potential;
+    BlossomNodeList _blossom_node_list;
+
+    int _node_num;
+    int _blossom_num;
+
+    typedef RangeMap<int> IntIntMap;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
+    struct BlossomData {
+      int tree;
+      Status status;
+      Arc pred, next;
+      Value pot, offset;
+    };
+
+    IntNodeMap *_blossom_index;
+    BlossomSet *_blossom_set;
+    RangeMap<BlossomData>* _blossom_data;
+
+    IntNodeMap *_node_index;
+    IntArcMap *_node_heap_index;
+
+    struct NodeData {
+
+      NodeData(IntArcMap& node_heap_index)
+        : heap(node_heap_index) {}
+
+      int blossom;
+      Value pot;
+      BinHeap<Value, IntArcMap> heap;
+      std::map<int, Arc> heap_index;
+
+      int tree;
+    };
+
+    RangeMap<NodeData>* _node_data;
+
+    typedef ExtendFindEnum<IntIntMap> TreeSet;
+
+    IntIntMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntIntMap *_delta2_index;
+    BinHeap<Value, IntIntMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    IntIntMap *_delta4_index;
+    BinHeap<Value, IntIntMap> *_delta4;
+
+    Value _delta_sum;
+    int _unmatched;
+
+    typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap>
+    FractionalMatching;
+    FractionalMatching *_fractional;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+      _blossom_num = _node_num * 3 / 2;
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+
+      if (!_blossom_set) {
+        _blossom_index = new IntNodeMap(_graph);
+        _blossom_set = new BlossomSet(*_blossom_index);
+        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
+      } else if (_blossom_data->size() != _blossom_num) {
+        delete _blossom_data;
+        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
+      }
+
+      if (!_node_index) {
+        _node_index = new IntNodeMap(_graph);
+        _node_heap_index = new IntArcMap(_graph);
+        _node_data = new RangeMap<NodeData>(_node_num,
+                                            NodeData(*_node_heap_index));
+      } else if (_node_data->size() != _node_num) {
+        delete _node_data;
+        _node_data = new RangeMap<NodeData>(_node_num,
+                                            NodeData(*_node_heap_index));
+      }
+
+      if (!_tree_set) {
+        _tree_set_index = new IntIntMap(_blossom_num);
+        _tree_set = new TreeSet(*_tree_set_index);
+      } else {
+        _tree_set_index->resize(_blossom_num);
+      }
+
+      if (!_delta2) {
+        _delta2_index = new IntIntMap(_blossom_num);
+        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
+      } else {
+        _delta2_index->resize(_blossom_num);
+      }
+
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+
+      if (!_delta4) {
+        _delta4_index = new IntIntMap(_blossom_num);
+        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
+      } else {
+        _delta4_index->resize(_blossom_num);
+      }
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_blossom_set) {
+        delete _blossom_index;
+        delete _blossom_set;
+        delete _blossom_data;
+      }
+
+      if (_node_index) {
+        delete _node_index;
+        delete _node_heap_index;
+        delete _node_data;
+      }
+
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+      if (_delta4) {
+        delete _delta4_index;
+        delete _delta4;
+      }
+    }
+
+    void matchedToEven(int blossom, int tree) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      if (!_blossom_set->trivial(blossom)) {
+        (*_blossom_data)[blossom].pot -=
+          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+        int ni = (*_node_index)[n];
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+
+        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
+              _delta3->push(e, rw / 2);
+            }
+          } else {
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              if ((*_node_data)[vi].heap[it->second] > rw) {
+                (*_node_data)[vi].heap.replace(it->second, e);
+                (*_node_data)[vi].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[vi].heap.push(e, rw);
+              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
+            }
+
+            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
+              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_delta2->state(vb) != _delta2->IN_HEAP) {
+                  _delta2->push(vb, _blossom_set->classPrio(vb) -
+                               (*_blossom_data)[vb].offset);
+                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset){
+                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+      (*_blossom_data)[blossom].offset = 0;
+    }
+
+    void matchedToOdd(int blossom) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+      (*_blossom_data)[blossom].offset += _delta_sum;
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
+                     (*_blossom_data)[blossom].offset);
+      }
+    }
+
+    void evenToMatched(int blossom, int tree) {
+      if (!_blossom_set->trivial(blossom)) {
+        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+        (*_node_data)[ni].pot -= _delta_sum;
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if (vb == blossom) {
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+          } else if ((*_blossom_data)[vb].status == EVEN) {
+
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+
+            int vt = _tree_set->find(vb);
+
+            if (vt != tree) {
+
+              Arc r = _graph.oppositeArc(e);
+
+              typename std::map<int, Arc>::iterator it =
+                (*_node_data)[ni].heap_index.find(vt);
+
+              if (it != (*_node_data)[ni].heap_index.end()) {
+                if ((*_node_data)[ni].heap[it->second] > rw) {
+                  (*_node_data)[ni].heap.replace(it->second, r);
+                  (*_node_data)[ni].heap.decrease(r, rw);
+                  it->second = r;
+                }
+              } else {
+                (*_node_data)[ni].heap.push(r, rw);
+                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
+              }
+
+              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
+                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+
+                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
+                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                               (*_blossom_data)[blossom].offset);
+                } else if ((*_delta2)[blossom] >
+                           _blossom_set->classPrio(blossom) -
+                           (*_blossom_data)[blossom].offset){
+                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
+                                   (*_blossom_data)[blossom].offset);
+                }
+              }
+            }
+          } else {
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              (*_node_data)[vi].heap.erase(it->second);
+              (*_node_data)[vi].heap_index.erase(it);
+              if ((*_node_data)[vi].heap.empty()) {
+                _blossom_set->increase(v, std::numeric_limits<Value>::max());
+              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
+                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
+              }
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_blossom_set->classPrio(vb) ==
+                    std::numeric_limits<Value>::max()) {
+                  _delta2->erase(vb);
+                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    void oddToMatched(int blossom) {
+      (*_blossom_data)[blossom].offset -= _delta_sum;
+
+      if (_blossom_set->classPrio(blossom) !=
+          std::numeric_limits<Value>::max()) {
+        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                       (*_blossom_data)[blossom].offset);
+      }
+
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->erase(blossom);
+      }
+    }
+
+    void oddToEven(int blossom, int tree) {
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->erase(blossom);
+        (*_blossom_data)[blossom].pot -=
+          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+        (*_node_data)[ni].pot +=
+          2 * _delta_sum - (*_blossom_data)[blossom].offset;
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
+              _delta3->push(e, rw / 2);
+            }
+          } else {
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              if ((*_node_data)[vi].heap[it->second] > rw) {
+                (*_node_data)[vi].heap.replace(it->second, e);
+                (*_node_data)[vi].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[vi].heap.push(e, rw);
+              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
+            }
+
+            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
+              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_delta2->state(vb) != _delta2->IN_HEAP) {
+                  _delta2->push(vb, _blossom_set->classPrio(vb) -
+                               (*_blossom_data)[vb].offset);
+                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+      (*_blossom_data)[blossom].offset = 0;
+    }
+
+    void alternatePath(int even, int tree) {
+      int odd;
+
+      evenToMatched(even, tree);
+      (*_blossom_data)[even].status = MATCHED;
+
+      while ((*_blossom_data)[even].pred != INVALID) {
+        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
+        (*_blossom_data)[odd].status = MATCHED;
+        oddToMatched(odd);
+        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
+
+        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
+        (*_blossom_data)[even].status = MATCHED;
+        evenToMatched(even, tree);
+        (*_blossom_data)[even].next =
+          _graph.oppositeArc((*_blossom_data)[odd].pred);
+      }
+
+    }
+
+    void destroyTree(int tree) {
+      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
+        if ((*_blossom_data)[b].status == EVEN) {
+          (*_blossom_data)[b].status = MATCHED;
+          evenToMatched(b, tree);
+        } else if ((*_blossom_data)[b].status == ODD) {
+          (*_blossom_data)[b].status = MATCHED;
+          oddToMatched(b);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+    void augmentOnEdge(const Edge& edge) {
+
+      int left = _blossom_set->find(_graph.u(edge));
+      int right = _blossom_set->find(_graph.v(edge));
+
+      int left_tree = _tree_set->find(left);
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+
+      (*_blossom_data)[left].next = _graph.direct(edge, true);
+      (*_blossom_data)[right].next = _graph.direct(edge, false);
+    }
+
+    void extendOnArc(const Arc& arc) {
+      int base = _blossom_set->find(_graph.target(arc));
+      int tree = _tree_set->find(base);
+
+      int odd = _blossom_set->find(_graph.source(arc));
+      _tree_set->insert(odd, tree);
+      (*_blossom_data)[odd].status = ODD;
+      matchedToOdd(odd);
+      (*_blossom_data)[odd].pred = arc;
+
+      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
+      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
+      _tree_set->insert(even, tree);
+      (*_blossom_data)[even].status = EVEN;
+      matchedToEven(even, tree);
+    }
+
+    void shrinkOnEdge(const Edge& edge, int tree) {
+      int nca = -1;
+      std::vector<int> left_path, right_path;
+
+      {
+        std::set<int> left_set, right_set;
+        int left = _blossom_set->find(_graph.u(edge));
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        int right = _blossom_set->find(_graph.v(edge));
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if ((*_blossom_data)[left].pred == INVALID) break;
+
+          left =
+            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
+          left_path.push_back(left);
+          left =
+            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_blossom_data)[right].pred == INVALID) break;
+
+          right =
+            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
+          right_path.push_back(right);
+          right =
+            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
+          right_path.push_back(right);
+
+          right_set.insert(right);
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+        }
+
+        if (nca == -1) {
+          if ((*_blossom_data)[left].pred == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              right_path.push_back(nca);
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              left_path.push_back(nca);
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      std::vector<int> subblossoms;
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        subblossoms.push_back(left_path[i]);
+        (*_blossom_data)[left_path[i]].next = prev;
+        _tree_set->erase(left_path[i]);
+
+        subblossoms.push_back(left_path[i + 1]);
+        (*_blossom_data)[left_path[i + 1]].status = EVEN;
+        oddToEven(left_path[i + 1], tree);
+        _tree_set->erase(left_path[i + 1]);
+        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
+      }
+
+      int k = 0;
+      while (right_path[k] != nca) ++k;
+
+      subblossoms.push_back(nca);
+      (*_blossom_data)[nca].next = prev;
+
+      for (int i = k - 2; i >= 0; i -= 2) {
+        subblossoms.push_back(right_path[i + 1]);
+        (*_blossom_data)[right_path[i + 1]].status = EVEN;
+        oddToEven(right_path[i + 1], tree);
+        _tree_set->erase(right_path[i + 1]);
+
+        (*_blossom_data)[right_path[i + 1]].next =
+          (*_blossom_data)[right_path[i + 1]].pred;
+
+        subblossoms.push_back(right_path[i]);
+        _tree_set->erase(right_path[i]);
+      }
+
+      int surface =
+        _blossom_set->join(subblossoms.begin(), subblossoms.end());
+
+      for (int i = 0; i < int(subblossoms.size()); ++i) {
+        if (!_blossom_set->trivial(subblossoms[i])) {
+          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
+        }
+        (*_blossom_data)[subblossoms[i]].status = MATCHED;
+      }
+
+      (*_blossom_data)[surface].pot = -2 * _delta_sum;
+      (*_blossom_data)[surface].offset = 0;
+      (*_blossom_data)[surface].status = EVEN;
+      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
+      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
+
+      _tree_set->insert(surface, tree);
+      _tree_set->erase(nca);
+    }
+
+    void splitBlossom(int blossom) {
+      Arc next = (*_blossom_data)[blossom].next;
+      Arc pred = (*_blossom_data)[blossom].pred;
+
+      int tree = _tree_set->find(blossom);
+
+      (*_blossom_data)[blossom].status = MATCHED;
+      oddToMatched(blossom);
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      std::vector<int> subblossoms;
+      _blossom_set->split(blossom, std::back_inserter(subblossoms));
+
+      Value offset = (*_blossom_data)[blossom].offset;
+      int b = _blossom_set->find(_graph.source(pred));
+      int d = _blossom_set->find(_graph.source(next));
+
+      int ib = -1, id = -1;
+      for (int i = 0; i < int(subblossoms.size()); ++i) {
+        if (subblossoms[i] == b) ib = i;
+        if (subblossoms[i] == d) id = i;
+
+        (*_blossom_data)[subblossoms[i]].offset = offset;
+        if (!_blossom_set->trivial(subblossoms[i])) {
+          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
+        }
+        if (_blossom_set->classPrio(subblossoms[i]) !=
+            std::numeric_limits<Value>::max()) {
+          _delta2->push(subblossoms[i],
+                        _blossom_set->classPrio(subblossoms[i]) -
+                        (*_blossom_data)[subblossoms[i]].offset);
+        }
+      }
+
+      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
+        for (int i = (id + 1) % subblossoms.size();
+             i != ib; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+        }
+
+        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          int ub = subblossoms[(i + 2) % subblossoms.size()];
+
+          (*_blossom_data)[sb].status = ODD;
+          matchedToOdd(sb);
+          _tree_set->insert(sb, tree);
+          (*_blossom_data)[sb].pred = pred;
+          (*_blossom_data)[sb].next =
+                           _graph.oppositeArc((*_blossom_data)[tb].next);
+
+          pred = (*_blossom_data)[ub].next;
+
+          (*_blossom_data)[tb].status = EVEN;
+          matchedToEven(tb, tree);
+          _tree_set->insert(tb, tree);
+          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
+        }
+
+        (*_blossom_data)[subblossoms[id]].status = ODD;
+        matchedToOdd(subblossoms[id]);
+        _tree_set->insert(subblossoms[id], tree);
+        (*_blossom_data)[subblossoms[id]].next = next;
+        (*_blossom_data)[subblossoms[id]].pred = pred;
+
+      } else {
+
+        for (int i = (ib + 1) % subblossoms.size();
+             i != id; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+        }
+
+        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          int ub = subblossoms[(i + 2) % subblossoms.size()];
+
+          (*_blossom_data)[sb].status = ODD;
+          matchedToOdd(sb);
+          _tree_set->insert(sb, tree);
+          (*_blossom_data)[sb].next = next;
+          (*_blossom_data)[sb].pred =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+
+          (*_blossom_data)[tb].status = EVEN;
+          matchedToEven(tb, tree);
+          _tree_set->insert(tb, tree);
+          (*_blossom_data)[tb].pred =
+            (*_blossom_data)[tb].next =
+            _graph.oppositeArc((*_blossom_data)[ub].next);
+          next = (*_blossom_data)[ub].next;
+        }
+
+        (*_blossom_data)[subblossoms[ib]].status = ODD;
+        matchedToOdd(subblossoms[ib]);
+        _tree_set->insert(subblossoms[ib], tree);
+        (*_blossom_data)[subblossoms[ib]].next = next;
+        (*_blossom_data)[subblossoms[ib]].pred = pred;
+      }
+      _tree_set->erase(blossom);
+    }
+
+    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
+      if (_blossom_set->trivial(blossom)) {
+        int bi = (*_node_index)[base];
+        Value pot = (*_node_data)[bi].pot;
+
+        (*_matching)[base] = matching;
+        _blossom_node_list.push_back(base);
+        (*_node_potential)[base] = pot;
+      } else {
+
+        Value pot = (*_blossom_data)[blossom].pot;
+        int bn = _blossom_node_list.size();
+
+        std::vector<int> subblossoms;
+        _blossom_set->split(blossom, std::back_inserter(subblossoms));
+        int b = _blossom_set->find(base);
+        int ib = -1;
+        for (int i = 0; i < int(subblossoms.size()); ++i) {
+          if (subblossoms[i] == b) { ib = i; break; }
+        }
+
+        for (int i = 1; i < int(subblossoms.size()); i += 2) {
+          int sb = subblossoms[(ib + i) % subblossoms.size()];
+          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
+
+          Arc m = (*_blossom_data)[tb].next;
+          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
+          extractBlossom(tb, _graph.source(m), m);
+        }
+        extractBlossom(subblossoms[ib], base, matching);
+
+        int en = _blossom_node_list.size();
+
+        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
+      }
+    }
+
+    void extractMatching() {
+      std::vector<int> blossoms;
+      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
+        blossoms.push_back(c);
+      }
+
+      for (int i = 0; i < int(blossoms.size()); ++i) {
+
+        Value offset = (*_blossom_data)[blossoms[i]].offset;
+        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
+        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
+             n != INVALID; ++n) {
+          (*_node_data)[(*_node_index)[n]].pot -= offset;
+        }
+
+        Arc matching = (*_blossom_data)[blossoms[i]].next;
+        Node base = _graph.source(matching);
+        extractBlossom(blossoms[i], base, matching);
+      }
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
+      : _graph(graph), _weight(weight), _matching(0),
+        _node_potential(0), _blossom_potential(), _blossom_node_list(),
+        _node_num(0), _blossom_num(0),
+
+        _blossom_index(0), _blossom_set(0), _blossom_data(0),
+        _node_index(0), _node_heap_index(0), _node_data(0),
+        _tree_set_index(0), _tree_set(0),
+
+        _delta2_index(0), _delta2(0),
+        _delta3_index(0), _delta3(0),
+        _delta4_index(0), _delta4(0),
+
+        _delta_sum(), _unmatched(0),
+
+        _fractional(0)
+    {}
+
+    ~MaxWeightedPerfectMatching() {
+      destroyStructures();
+      if (_fractional) {
+        delete _fractional;
+      }
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = _node_num;
+
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = - std::numeric_limits<Value>::max();
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        (*_node_index)[n] = index;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        (*_node_data)[index].pot = max;
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        _tree_set->insert(blossom);
+
+        (*_blossom_data)[blossom].status = EVEN;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = INVALID;
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int ti = (*_node_index)[_graph.v(e)];
+        if (_graph.u(e) != _graph.v(e)) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+    }
+
+    /// \brief Initialize the algorithm with fractional matching
+    ///
+    /// This function initializes the algorithm with a fractional
+    /// matching. This initialization is also called jumpstart heuristic.
+    void fractionalInit() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      if (_fractional == 0) {
+        _fractional = new FractionalMatching(_graph, _weight, false);
+      }
+      if (!_fractional->run()) {
+        _unmatched = -1;
+        return;
+      }
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = 0;
+
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value pot = _fractional->nodeValue(n);
+        (*_node_index)[n] = index;
+        (*_node_data)[index].pot = pot;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        (*_blossom_data)[blossom].status = MATCHED;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = _fractional->matching(n);
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+
+      typename Graph::template NodeMap<bool> processed(_graph, false);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (processed[n]) continue;
+        processed[n] = true;
+        if (_fractional->matching(n) == INVALID) continue;
+        int num = 1;
+        Node v = _graph.target(_fractional->matching(n));
+        while (n != v) {
+          processed[v] = true;
+          v = _graph.target(_fractional->matching(v));
+          ++num;
+        }
+
+        if (num % 2 == 1) {
+          std::vector<int> subblossoms(num);
+
+          subblossoms[--num] = _blossom_set->find(n);
+          v = _graph.target(_fractional->matching(n));
+          while (n != v) {
+            subblossoms[--num] = _blossom_set->find(v);
+            v = _graph.target(_fractional->matching(v));
+          }
+
+          int surface =
+            _blossom_set->join(subblossoms.begin(), subblossoms.end());
+          (*_blossom_data)[surface].status = EVEN;
+          (*_blossom_data)[surface].pred = INVALID;
+          (*_blossom_data)[surface].next = INVALID;
+          (*_blossom_data)[surface].pot = 0;
+          (*_blossom_data)[surface].offset = 0;
+
+          _tree_set->insert(surface);
+          ++_unmatched;
+        }
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int sb = _blossom_set->find(_graph.u(e));
+        int ti = (*_node_index)[_graph.v(e)];
+        int tb = _blossom_set->find(_graph.v(e));
+        if ((*_blossom_data)[sb].status == EVEN &&
+            (*_blossom_data)[tb].status == EVEN && sb != tb) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        int nb = _blossom_set->find(n);
+        if ((*_blossom_data)[nb].status != MATCHED) continue;
+        int ni = (*_node_index)[n];
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.target(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+
+            int vt = _tree_set->find(vb);
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[ni].heap_index.find(vt);
+
+            if (it != (*_node_data)[ni].heap_index.end()) {
+              if ((*_node_data)[ni].heap[it->second] > rw) {
+                (*_node_data)[ni].heap.replace(it->second, e);
+                (*_node_data)[ni].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[ni].heap.push(e, rw);
+              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
+            }
+          }
+        }
+
+        if (!(*_node_data)[ni].heap.empty()) {
+          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+          _delta2->push(nb, _blossom_set->classPrio(nb));
+        }
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() or \ref fractionalInit() must be called before
+    /// using this function.
+    bool start() {
+      enum OpType {
+        D2, D3, D4
+      };
+
+      if (_unmatched == -1) return false;
+
+      while (_unmatched > 0) {
+        Value d2 = !_delta2->empty() ?
+          _delta2->prio() : std::numeric_limits<Value>::max();
+
+        Value d3 = !_delta3->empty() ?
+          _delta3->prio() : std::numeric_limits<Value>::max();
+
+        Value d4 = !_delta4->empty() ?
+          _delta4->prio() : std::numeric_limits<Value>::max();
+
+        _delta_sum = d3; OpType ot = D3;
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
+
+        if (_delta_sum == std::numeric_limits<Value>::max()) {
+          return false;
+        }
+
+        switch (ot) {
+        case D2:
+          {
+            int blossom = _delta2->top();
+            Node n = _blossom_set->classTop(blossom);
+            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
+            extendOnArc(e);
+          }
+          break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            int left_blossom = _blossom_set->find(_graph.u(e));
+            int right_blossom = _blossom_set->find(_graph.v(e));
+
+            if (left_blossom == right_blossom) {
+              _delta3->pop();
+            } else {
+              int left_tree = _tree_set->find(left_blossom);
+              int right_tree = _tree_set->find(right_blossom);
+
+              if (left_tree == right_tree) {
+                shrinkOnEdge(e, left_tree);
+              } else {
+                augmentOnEdge(e);
+                _unmatched -= 2;
+              }
+            }
+          } break;
+        case D4:
+          splitBlossom(_delta4->top());
+          break;
+        }
+      }
+      extractMatching();
+      return true;
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
+    ///
+    /// \note mwpm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwpm.fractionalInit();
+    ///   mwpm.start();
+    /// \endcode
+    bool run() {
+      fractionalInit();
+      return start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// perfect matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum / 2;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the found
+    /// matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    bool matching(const Edge& edge) const {
+      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
+    }
+
+    /// \brief Return the matching arc (or edge) incident to the given node.
+    ///
+    /// This function returns the matching arc (or edge) incident to the
+    /// given node in the found matching or \c INVALID if the node is
+    /// not covered by the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return the mate of the given node.
+    ///
+    /// This function returns the mate of the given node in the found
+    /// matching or \c INVALID if the node is not covered by the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Node mate(const Node& node) const {
+      return _graph.target((*_matching)[node]);
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      for (int i = 0; i < blossomNum(); ++i) {
+        sum += blossomValue(i) * (blossomSize(i) / 2);
+      }
+      return sum;
+    }
+
+    /// \brief Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// \brief Return the number of the blossoms in the basis.
+    ///
+    /// This function returns the number of the blossoms in the basis.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    /// \see BlossomIt
+    int blossomNum() const {
+      return _blossom_potential.size();
+    }
+
+    /// \brief Return the number of the nodes in the given blossom.
+    ///
+    /// This function returns the number of the nodes in the given blossom.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    /// \see BlossomIt
+    int blossomSize(int k) const {
+      return _blossom_potential[k].end - _blossom_potential[k].begin;
+    }
+
+    /// \brief Return the dual value (ptential) of the given blossom.
+    ///
+    /// This function returns the dual value (ptential) of the given blossom.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value blossomValue(int k) const {
+      return _blossom_potential[k].value;
+    }
+
+    /// \brief Iterator for obtaining the nodes of a blossom.
+    ///
+    /// This class provides an iterator for obtaining the nodes of the
+    /// given blossom. It lists a subset of the nodes.
+    /// Before using this iterator, you must allocate a
+    /// MaxWeightedPerfectMatching class and execute it.
+    class BlossomIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor to get the nodes of the given variable.
+      ///
+      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
+      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
+      /// must be called before initializing this iterator.
+      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
+        : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_blossom_potential[variable].begin;
+        _last = _algorithm->_blossom_potential[variable].end;
+      }
+
+      /// \brief Conversion to \c Node.
+      ///
+      /// Conversion to \c Node.
+      operator Node() const {
+        return _algorithm->_blossom_node_list[_index];
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      BlossomIt& operator++() {
+        ++_index;
+        return *this;
+      }
+
+      /// \brief Validity checking
+      ///
+      /// This function checks whether the iterator is invalid.
+      bool operator==(Invalid) const { return _index == _last; }
+
+      /// \brief Validity checking
+      ///
+      /// This function checks whether the iterator is valid.
+      bool operator!=(Invalid) const { return _index != _last; }
+
+    private:
+      const MaxWeightedPerfectMatching* _algorithm;
+      int _last;
+      int _index;
+    };
+
+    /// @}
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_MATCHING_H
diff --git a/lemon/math.h b/lemon/math.h
new file mode 100644
index 0000000..5da50b0
--- /dev/null
+++ b/lemon/math.h
@@ -0,0 +1,77 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_MATH_H
+#define LEMON_MATH_H
+
+///\ingroup misc
+///\file
+///\brief Some extensions to the standard \c cmath library.
+///
+///Some extensions to the standard \c cmath library.
+///
+///This file includes the standard math library (cmath).
+
+#include<cmath>
+
+namespace lemon {
+
+  /// \addtogroup misc
+  /// @{
+
+  /// The Euler constant
+  const long double E       = 2.7182818284590452353602874713526625L;
+  /// log_2(e)
+  const long double LOG2E   = 1.4426950408889634073599246810018921L;
+  /// log_10(e)
+  const long double LOG10E  = 0.4342944819032518276511289189166051L;
+  /// ln(2)
+  const long double LN2     = 0.6931471805599453094172321214581766L;
+  /// ln(10)
+  const long double LN10    = 2.3025850929940456840179914546843642L;
+  /// pi
+  const long double PI      = 3.1415926535897932384626433832795029L;
+  /// pi/2
+  const long double PI_2    = 1.5707963267948966192313216916397514L;
+  /// pi/4
+  const long double PI_4    = 0.7853981633974483096156608458198757L;
+  /// sqrt(2)
+  const long double SQRT2   = 1.4142135623730950488016887242096981L;
+  /// 1/sqrt(2)
+  const long double SQRT1_2 = 0.7071067811865475244008443621048490L;
+
+  ///Check whether the parameter is NaN or not
+
+  ///This function checks whether the parameter is NaN or not.
+  ///Is should be equivalent with std::isnan(), but it is not
+  ///provided by all compilers.
+  inline bool isNaN(double v)
+    {
+      return v!=v;
+    }
+
+  ///Round a value to its closest integer
+  inline double round(double r) {
+    return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5);
+  }
+
+  /// @}
+
+} //namespace lemon
+
+#endif //LEMON_MATH_H
diff --git a/lemon/max_cardinality_search.h b/lemon/max_cardinality_search.h
new file mode 100644
index 0000000..bfa9edb
--- /dev/null
+++ b/lemon/max_cardinality_search.h
@@ -0,0 +1,794 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_MAX_CARDINALITY_SEARCH_H
+#define LEMON_MAX_CARDINALITY_SEARCH_H
+
+
+/// \ingroup search
+/// \file
+/// \brief Maximum cardinality search in undirected digraphs.
+
+#include <lemon/bin_heap.h>
+#include <lemon/bucket_heap.h>
+
+#include <lemon/error.h>
+#include <lemon/maps.h>
+
+#include <functional>
+
+namespace lemon {
+
+  /// \brief Default traits class of MaxCardinalitySearch class.
+  ///
+  /// Default traits class of MaxCardinalitySearch class.
+  /// \param Digraph Digraph type.
+  /// \param CapacityMap Type of capacity map.
+  template <typename GR, typename CAP>
+  struct MaxCardinalitySearchDefaultTraits {
+    /// The digraph type the algorithm runs on.
+    typedef GR Digraph;
+
+    template <typename CM>
+    struct CapMapSelector {
+
+      typedef CM CapacityMap;
+
+      static CapacityMap *createCapacityMap(const Digraph& g) {
+        return new CapacityMap(g);
+      }
+    };
+
+    template <typename CM>
+    struct CapMapSelector<ConstMap<CM, Const<int, 1> > > {
+
+      typedef ConstMap<CM, Const<int, 1> > CapacityMap;
+
+      static CapacityMap *createCapacityMap(const Digraph&) {
+        return new CapacityMap;
+      }
+    };
+
+    /// \brief The type of the map that stores the arc capacities.
+    ///
+    /// The type of the map that stores the arc capacities.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef typename CapMapSelector<CAP>::CapacityMap CapacityMap;
+
+    /// \brief The type of the capacity of the arcs.
+    typedef typename CapacityMap::Value Value;
+
+    /// \brief Instantiates a CapacityMap.
+    ///
+    /// This function instantiates a \ref CapacityMap.
+    /// \param digraph is the digraph, to which we would like to define
+    /// the CapacityMap.
+    static CapacityMap *createCapacityMap(const Digraph& digraph) {
+      return CapMapSelector<CapacityMap>::createCapacityMap(digraph);
+    }
+
+    /// \brief The cross reference type used by heap.
+    ///
+    /// The cross reference type used by heap.
+    /// Usually it is \c Digraph::NodeMap<int>.
+    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
+
+    /// \brief Instantiates a HeapCrossRef.
+    ///
+    /// This function instantiates a \ref HeapCrossRef.
+    /// \param digraph is the digraph, to which we would like to define the
+    /// HeapCrossRef.
+    static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
+      return new HeapCrossRef(digraph);
+    }
+
+    template <typename CapacityMap>
+    struct HeapSelector {
+      template <typename Value, typename Ref>
+      struct Selector {
+        typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
+      };
+    };
+
+    template <typename CapacityKey>
+    struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
+      template <typename Value, typename Ref>
+      struct Selector {
+        typedef BucketHeap<Ref, false > Heap;
+      };
+    };
+
+    /// \brief The heap type used by MaxCardinalitySearch algorithm.
+    ///
+    /// The heap type used by MaxCardinalitySearch algorithm. It should
+    /// maximalize the priorities. The default heap type is
+    /// the \ref BinHeap, but it is specialized when the
+    /// CapacityMap is ConstMap<Digraph::Node, Const<int, 1> >
+    /// to BucketHeap.
+    ///
+    /// \sa MaxCardinalitySearch
+    typedef typename HeapSelector<CapacityMap>
+    ::template Selector<Value, HeapCrossRef>
+    ::Heap Heap;
+
+    /// \brief Instantiates a Heap.
+    ///
+    /// This function instantiates a \ref Heap.
+    /// \param crossref The cross reference of the heap.
+    static Heap *createHeap(HeapCrossRef& crossref) {
+      return new Heap(crossref);
+    }
+
+    /// \brief The type of the map that stores whether a node is processed.
+    ///
+    /// The type of the map that stores whether a node is processed.
+    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    /// By default it is a NullMap.
+    typedef NullMap<typename Digraph::Node, bool> ProcessedMap;
+
+    /// \brief Instantiates a ProcessedMap.
+    ///
+    /// This function instantiates a \ref ProcessedMap.
+    /// \param digraph is the digraph, to which
+    /// we would like to define the \ref ProcessedMap
+#ifdef DOXYGEN
+    static ProcessedMap *createProcessedMap(const Digraph &digraph)
+#else
+    static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+    {
+      return new ProcessedMap();
+    }
+
+    /// \brief The type of the map that stores the cardinalities of the nodes.
+    ///
+    /// The type of the map that stores the cardinalities of the nodes.
+    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<Value> CardinalityMap;
+
+    /// \brief Instantiates a CardinalityMap.
+    ///
+    /// This function instantiates a \ref CardinalityMap.
+    /// \param digraph is the digraph, to which we would like to
+    /// define the \ref CardinalityMap
+    static CardinalityMap *createCardinalityMap(const Digraph &digraph) {
+      return new CardinalityMap(digraph);
+    }
+
+
+  };
+
+  /// \ingroup search
+  ///
+  /// \brief Maximum Cardinality Search algorithm class.
+  ///
+  /// This class provides an efficient implementation of Maximum Cardinality
+  /// Search algorithm. The maximum cardinality search first chooses any
+  /// node of the digraph. Then every time it chooses one unprocessed node
+  /// with maximum cardinality, i.e the sum of capacities on out arcs
+  /// to the nodes
+  /// which were previusly processed.
+  /// If there is a cut in the digraph the algorithm should choose
+  /// again any unprocessed node of the digraph.
+
+  /// The arc capacities are passed to the algorithm using a
+  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
+  /// kind of capacity.
+  ///
+  /// The type of the capacity is determined by the \ref
+  /// concepts::ReadMap::Value "Value" of the capacity map.
+  ///
+  /// It is also possible to change the underlying priority heap.
+  ///
+  ///
+  /// \param GR The digraph type the algorithm runs on. The value of
+  /// Digraph is not used directly by the search algorithm, it
+  /// is only passed to \ref MaxCardinalitySearchDefaultTraits.
+  /// \param CAP This read-only ArcMap determines the capacities of
+  /// the arcs. It is read once for each arc, so the map may involve in
+  /// relatively time consuming process to compute the arc capacity if
+  /// it is necessary. The default map type is \ref
+  /// ConstMap "ConstMap<concepts::Digraph::Arc, Const<int,1> >". The value
+  /// of CapacityMap is not used directly by search algorithm, it is only
+  /// passed to \ref MaxCardinalitySearchDefaultTraits.
+  /// \param TR Traits class to set various data types used by the
+  /// algorithm.  The default traits class is
+  /// \ref MaxCardinalitySearchDefaultTraits
+  /// "MaxCardinalitySearchDefaultTraits<GR, CAP>".
+  /// See \ref MaxCardinalitySearchDefaultTraits
+  /// for the documentation of a MaxCardinalitySearch traits class.
+
+#ifdef DOXYGEN
+  template <typename GR, typename CAP, typename TR>
+#else
+  template <typename GR, typename CAP =
+            ConstMap<typename GR::Arc, Const<int,1> >,
+            typename TR =
+            MaxCardinalitySearchDefaultTraits<GR, CAP> >
+#endif
+  class MaxCardinalitySearch {
+  public:
+
+    typedef TR Traits;
+    ///The type of the underlying digraph.
+    typedef typename Traits::Digraph Digraph;
+
+    ///The type of the capacity of the arcs.
+    typedef typename Traits::CapacityMap::Value Value;
+    ///The type of the map that stores the arc capacities.
+    typedef typename Traits::CapacityMap CapacityMap;
+    ///The type of the map indicating if a node is processed.
+    typedef typename Traits::ProcessedMap ProcessedMap;
+    ///The type of the map that stores the cardinalities of the nodes.
+    typedef typename Traits::CardinalityMap CardinalityMap;
+    ///The cross reference type used for the current heap.
+    typedef typename Traits::HeapCrossRef HeapCrossRef;
+    ///The heap type used by the algorithm. It maximizes the priorities.
+    typedef typename Traits::Heap Heap;
+  private:
+    // Pointer to the underlying digraph.
+    const Digraph *_graph;
+    // Pointer to the capacity map
+    const CapacityMap *_capacity;
+    // Indicates if \ref _capacity is locally allocated (\c true) or not.
+    bool local_capacity;
+    // Pointer to the map of cardinality.
+    CardinalityMap *_cardinality;
+    // Indicates if \ref _cardinality is locally allocated (\c true) or not.
+    bool local_cardinality;
+    // Pointer to the map of processed status of the nodes.
+    ProcessedMap *_processed;
+    // Indicates if \ref _processed is locally allocated (\c true) or not.
+    bool local_processed;
+    // Pointer to the heap cross references.
+    HeapCrossRef *_heap_cross_ref;
+    // Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
+    bool local_heap_cross_ref;
+    // Pointer to the heap.
+    Heap *_heap;
+    // Indicates if \ref _heap is locally allocated (\c true) or not.
+    bool local_heap;
+
+  public :
+
+    typedef MaxCardinalitySearch Create;
+
+    ///\name Named template parameters
+
+    ///@{
+
+    template <class T>
+    struct DefCapacityMapTraits : public Traits {
+      typedef T CapacityMap;
+      static CapacityMap *createCapacityMap(const Digraph &) {
+               LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// CapacityMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting CapacityMap type
+    /// for the algorithm.
+    template <class T>
+    struct SetCapacityMap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefCapacityMapTraits<T> > {
+      typedef MaxCardinalitySearch<Digraph, CapacityMap,
+                                   DefCapacityMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct DefCardinalityMapTraits : public Traits {
+      typedef T CardinalityMap;
+      static CardinalityMap *createCardinalityMap(const Digraph &)
+      {
+        LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// CardinalityMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting CardinalityMap
+    /// type for the algorithm.
+    template <class T>
+    struct SetCardinalityMap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefCardinalityMapTraits<T> > {
+      typedef MaxCardinalitySearch<Digraph, CapacityMap,
+                                   DefCardinalityMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct DefProcessedMapTraits : public Traits {
+      typedef T ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &) {
+               LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// ProcessedMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
+    /// for the algorithm.
+    template <class T>
+    struct SetProcessedMap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefProcessedMapTraits<T> > {
+      typedef MaxCardinalitySearch<Digraph, CapacityMap,
+                                   DefProcessedMapTraits<T> > Create;
+    };
+
+    template <class H, class CR>
+    struct DefHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
+             LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+      static Heap *createHeap(HeapCrossRef &) {
+               LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting heap
+    /// and cross reference type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting heap and cross
+    /// reference type for the algorithm.
+    template <class H, class CR = typename Digraph::template NodeMap<int> >
+    struct SetHeap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefHeapTraits<H, CR> > {
+      typedef MaxCardinalitySearch< Digraph, CapacityMap,
+                                    DefHeapTraits<H, CR> > Create;
+    };
+
+    template <class H, class CR>
+    struct DefStandardHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
+        return new HeapCrossRef(digraph);
+      }
+      static Heap *createHeap(HeapCrossRef &crossref) {
+        return new Heap(crossref);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting heap and
+    /// cross reference type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting heap and cross
+    /// reference type. It can allocate the heap and the cross reference
+    /// object if the cross reference's constructor waits for the digraph as
+    /// parameter and the heap's constructor waits for the cross reference.
+    template <class H, class CR = typename Digraph::template NodeMap<int> >
+    struct SetStandardHeap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefStandardHeapTraits<H, CR> > {
+      typedef MaxCardinalitySearch<Digraph, CapacityMap,
+                                   DefStandardHeapTraits<H, CR> >
+      Create;
+    };
+
+    ///@}
+
+
+  protected:
+
+    MaxCardinalitySearch() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    ///\param digraph the digraph the algorithm will run on.
+    ///\param capacity the capacity map used by the algorithm.
+    MaxCardinalitySearch(const Digraph& digraph,
+                         const CapacityMap& capacity) :
+      _graph(&digraph),
+      _capacity(&capacity), local_capacity(false),
+      _cardinality(0), local_cardinality(false),
+      _processed(0), local_processed(false),
+      _heap_cross_ref(0), local_heap_cross_ref(false),
+      _heap(0), local_heap(false)
+    { }
+
+    /// \brief Constructor.
+    ///
+    ///\param digraph the digraph the algorithm will run on.
+    ///
+    ///A constant 1 capacity map will be allocated.
+    MaxCardinalitySearch(const Digraph& digraph) :
+      _graph(&digraph),
+      _capacity(0), local_capacity(false),
+      _cardinality(0), local_cardinality(false),
+      _processed(0), local_processed(false),
+      _heap_cross_ref(0), local_heap_cross_ref(false),
+      _heap(0), local_heap(false)
+    { }
+
+    /// \brief Destructor.
+    ~MaxCardinalitySearch() {
+      if(local_capacity) delete _capacity;
+      if(local_cardinality) delete _cardinality;
+      if(local_processed) delete _processed;
+      if(local_heap_cross_ref) delete _heap_cross_ref;
+      if(local_heap) delete _heap;
+    }
+
+    /// \brief Sets the capacity map.
+    ///
+    /// Sets the capacity map.
+    /// \return <tt> (*this) </tt>
+    MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
+      if (local_capacity) {
+        delete _capacity;
+        local_capacity=false;
+      }
+      _capacity=&m;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the capacity map.
+    ///
+    /// Returns a const reference to the capacity map used by
+    /// the algorithm.
+    const CapacityMap &capacityMap() const {
+      return *_capacity;
+    }
+
+    /// \brief Sets the map storing the cardinalities calculated by the
+    /// algorithm.
+    ///
+    /// Sets the map storing the cardinalities calculated by the algorithm.
+    /// If you don't use this function before calling \ref run(),
+    /// it will allocate one. The destuctor deallocates this
+    /// automatically allocated map, of course.
+    /// \return <tt> (*this) </tt>
+    MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
+      if(local_cardinality) {
+        delete _cardinality;
+        local_cardinality=false;
+      }
+      _cardinality = &m;
+      return *this;
+    }
+
+    /// \brief Sets the map storing the processed nodes.
+    ///
+    /// Sets the map storing the processed nodes.
+    /// If you don't use this function before calling \ref run(),
+    /// it will allocate one. The destuctor deallocates this
+    /// automatically allocated map, of course.
+    /// \return <tt> (*this) </tt>
+    MaxCardinalitySearch &processedMap(ProcessedMap &m)
+    {
+      if(local_processed) {
+        delete _processed;
+        local_processed=false;
+      }
+      _processed = &m;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the cardinality map.
+    ///
+    /// Returns a const reference to the cardinality map used by
+    /// the algorithm.
+    const ProcessedMap &processedMap() const {
+      return *_processed;
+    }
+
+    /// \brief Sets the heap and the cross reference used by algorithm.
+    ///
+    /// Sets the heap and the cross reference used by algorithm.
+    /// If you don't use this function before calling \ref run(),
+    /// it will allocate one. The destuctor deallocates this
+    /// automatically allocated map, of course.
+    /// \return <tt> (*this) </tt>
+    MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) {
+      if(local_heap_cross_ref) {
+        delete _heap_cross_ref;
+        local_heap_cross_ref = false;
+      }
+      _heap_cross_ref = &cr;
+      if(local_heap) {
+        delete _heap;
+        local_heap = false;
+      }
+      _heap = &hp;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the heap.
+    ///
+    /// Returns a const reference to the heap used by
+    /// the algorithm.
+    const Heap &heap() const {
+      return *_heap;
+    }
+
+    /// \brief Returns a const reference to the cross reference.
+    ///
+    /// Returns a const reference to the cross reference
+    /// of the heap.
+    const HeapCrossRef &heapCrossRef() const {
+      return *_heap_cross_ref;
+    }
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::InArcIt InArcIt;
+
+    void create_maps() {
+      if(!_capacity) {
+        local_capacity = true;
+        _capacity = Traits::createCapacityMap(*_graph);
+      }
+      if(!_cardinality) {
+        local_cardinality = true;
+        _cardinality = Traits::createCardinalityMap(*_graph);
+      }
+      if(!_processed) {
+        local_processed = true;
+        _processed = Traits::createProcessedMap(*_graph);
+      }
+      if (!_heap_cross_ref) {
+        local_heap_cross_ref = true;
+        _heap_cross_ref = Traits::createHeapCrossRef(*_graph);
+      }
+      if (!_heap) {
+        local_heap = true;
+        _heap = Traits::createHeap(*_heap_cross_ref);
+      }
+    }
+
+    void finalizeNodeData(Node node, Value capacity) {
+      _processed->set(node, true);
+      _cardinality->set(node, capacity);
+    }
+
+  public:
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use
+    /// one of the member functions called \ref run().
+    /// \n
+    /// If you need more control on the execution,
+    /// first you must call \ref init(), then you can add several source nodes
+    /// with \ref addSource().
+    /// Finally \ref start() will perform the computation.
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures, and clears the heap.
+    void init() {
+      create_maps();
+      _heap->clear();
+      for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
+        _processed->set(it, false);
+        _heap_cross_ref->set(it, Heap::PRE_HEAP);
+      }
+    }
+
+    /// \brief Adds a new source node.
+    ///
+    /// Adds a new source node to the priority heap.
+    ///
+    /// It checks if the node has not yet been added to the heap.
+    void addSource(Node source, Value capacity = 0) {
+      if(_heap->state(source) == Heap::PRE_HEAP) {
+        _heap->push(source, capacity);
+      }
+    }
+
+    /// \brief Processes the next node in the priority heap
+    ///
+    /// Processes the next node in the priority heap.
+    ///
+    /// \return The processed node.
+    ///
+    /// \warning The priority heap must not be empty!
+    Node processNextNode() {
+      Node node = _heap->top();
+      finalizeNodeData(node, _heap->prio());
+      _heap->pop();
+
+      for (InArcIt it(*_graph, node); it != INVALID; ++it) {
+        Node source = _graph->source(it);
+        switch (_heap->state(source)) {
+        case Heap::PRE_HEAP:
+          _heap->push(source, (*_capacity)[it]);
+          break;
+        case Heap::IN_HEAP:
+          _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]);
+          break;
+        case Heap::POST_HEAP:
+          break;
+        }
+      }
+      return node;
+    }
+
+    /// \brief Next node to be processed.
+    ///
+    /// Next node to be processed.
+    ///
+    /// \return The next node to be processed or INVALID if the
+    /// priority heap is empty.
+    Node nextNode() {
+      return !_heap->empty() ? _heap->top() : INVALID;
+    }
+
+    /// \brief Returns \c false if there are nodes
+    /// to be processed in the priority heap
+    ///
+    /// Returns \c false if there are nodes
+    /// to be processed in the priority heap
+    bool emptyQueue() { return _heap->empty(); }
+    /// \brief Returns the number of the nodes to be processed
+    /// in the priority heap
+    ///
+    /// Returns the number of the nodes to be processed in the priority heap
+    int emptySize() { return _heap->size(); }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    ///\pre init() must be called and at least one node should be added
+    /// with addSource() before using this function.
+    ///
+    /// This method runs the Maximum Cardinality Search algorithm from the
+    /// source node(s).
+    void start() {
+      while ( !_heap->empty() ) processNextNode();
+    }
+
+    /// \brief Executes the algorithm until \c dest is reached.
+    ///
+    /// Executes the algorithm until \c dest is reached.
+    ///
+    /// \pre init() must be called and at least one node should be added
+    /// with addSource() before using this function.
+    ///
+    /// This method runs the %MaxCardinalitySearch algorithm from the source
+    /// nodes.
+    void start(Node dest) {
+      while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
+      if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
+    }
+
+    /// \brief Executes the algorithm until a condition is met.
+    ///
+    /// Executes the algorithm until a condition is met.
+    ///
+    /// \pre init() must be called and at least one node should be added
+    /// with addSource() before using this function.
+    ///
+    /// \param nm must be a bool (or convertible) node map. The algorithm
+    /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
+    template <typename NodeBoolMap>
+    void start(const NodeBoolMap &nm) {
+      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
+      if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
+    }
+
+    /// \brief Runs the maximum cardinality search algorithm from node \c s.
+    ///
+    /// This method runs the %MaxCardinalitySearch algorithm from a root
+    /// node \c s.
+    ///
+    ///\note d.run(s) is just a shortcut of the following code.
+    ///\code
+    ///  d.init();
+    ///  d.addSource(s);
+    ///  d.start();
+    ///\endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    /// \brief Runs the maximum cardinality search algorithm for the
+    /// whole digraph.
+    ///
+    /// This method runs the %MaxCardinalitySearch algorithm from all
+    /// unprocessed node of the digraph.
+    ///
+    ///\note d.run(s) is just a shortcut of the following code.
+    ///\code
+    ///  d.init();
+    ///  for (NodeIt it(digraph); it != INVALID; ++it) {
+    ///    if (!d.reached(it)) {
+    ///      d.addSource(s);
+    ///      d.start();
+    ///    }
+    ///  }
+    ///\endcode
+    void run() {
+      init();
+      for (NodeIt it(*_graph); it != INVALID; ++it) {
+        if (!reached(it)) {
+          addSource(it);
+          start();
+        }
+      }
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    /// The results of the maximum cardinality search algorithm can be
+    /// obtained using these functions.
+    /// \n
+    /// Before the use of these functions, either run() or start() must be
+    /// called.
+
+    ///@{
+
+    /// \brief The cardinality of a node.
+    ///
+    /// Returns the cardinality of a node.
+    /// \pre \ref run() must be called before using this function.
+    /// \warning If node \c v in unreachable from the root the return value
+    /// of this funcion is undefined.
+    Value cardinality(Node node) const { return (*_cardinality)[node]; }
+
+    /// \brief The current cardinality of a node.
+    ///
+    /// Returns the current cardinality of a node.
+    /// \pre the given node should be reached but not processed
+    Value currentCardinality(Node node) const { return (*_heap)[node]; }
+
+    /// \brief Returns a reference to the NodeMap of cardinalities.
+    ///
+    /// Returns a reference to the NodeMap of cardinalities. \pre \ref run()
+    /// must be called before using this function.
+    const CardinalityMap &cardinalityMap() const { return *_cardinality;}
+
+    /// \brief Checks if a node is reachable from the root.
+    ///
+    /// Returns \c true if \c v is reachable from the root.
+    /// \warning The source nodes are initated as unreached.
+    /// \pre \ref run() must be called before using this function.
+    bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
+
+    /// \brief Checks if a node is processed.
+    ///
+    /// Returns \c true if \c v is processed, i.e. the shortest
+    /// path to \c v has already found.
+    /// \pre \ref run() must be called before using this function.
+    bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }
+
+    ///@}
+  };
+
+}
+
+#endif
diff --git a/lemon/min_cost_arborescence.h b/lemon/min_cost_arborescence.h
new file mode 100644
index 0000000..1d0a2b1
--- /dev/null
+++ b/lemon/min_cost_arborescence.h
@@ -0,0 +1,808 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_MIN_COST_ARBORESCENCE_H
+#define LEMON_MIN_COST_ARBORESCENCE_H
+
+///\ingroup spantree
+///\file
+///\brief Minimum Cost Arborescence algorithm.
+
+#include <vector>
+
+#include <lemon/list_graph.h>
+#include <lemon/bin_heap.h>
+#include <lemon/assert.h>
+
+namespace lemon {
+
+
+  /// \brief Default traits class for MinCostArborescence class.
+  ///
+  /// Default traits class for MinCostArborescence class.
+  /// \param GR Digraph type.
+  /// \param CM Type of the cost map.
+  template <class GR, class CM>
+  struct MinCostArborescenceDefaultTraits{
+
+    /// \brief The digraph type the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc costs.
+    ///
+    /// The type of the map that stores the arc costs.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef CM CostMap;
+
+    /// \brief The value type of the costs.
+    ///
+    /// The value type of the costs.
+    typedef typename CostMap::Value Value;
+
+    /// \brief The type of the map that stores which arcs are in the
+    /// arborescence.
+    ///
+    /// The type of the map that stores which arcs are in the
+    /// arborescence.  It must conform to the \ref concepts::WriteMap
+    /// "WriteMap" concept, and its value type must be \c bool
+    /// (or convertible). Initially it will be set to \c false on each
+    /// arc, then it will be set on each arborescence arc once.
+    typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
+
+    /// \brief Instantiates a \c ArborescenceMap.
+    ///
+    /// This function instantiates a \c ArborescenceMap.
+    /// \param digraph The digraph to which we would like to calculate
+    /// the \c ArborescenceMap.
+    static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
+      return new ArborescenceMap(digraph);
+    }
+
+    /// \brief The type of the \c PredMap
+    ///
+    /// The type of the \c PredMap. It must confrom to the
+    /// \ref concepts::WriteMap "WriteMap" concept, and its value type
+    /// must be the \c Arc type of the digraph.
+    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+
+    /// \brief Instantiates a \c PredMap.
+    ///
+    /// This function instantiates a \c PredMap.
+    /// \param digraph The digraph to which we would like to define the
+    /// \c PredMap.
+    static PredMap *createPredMap(const Digraph &digraph){
+      return new PredMap(digraph);
+    }
+
+  };
+
+  /// \ingroup spantree
+  ///
+  /// \brief Minimum Cost Arborescence algorithm class.
+  ///
+  /// This class provides an efficient implementation of the
+  /// Minimum Cost Arborescence algorithm. The arborescence is a tree
+  /// which is directed from a given source node of the digraph. One or
+  /// more sources should be given to the algorithm and it will calculate
+  /// the minimum cost subgraph that is the union of arborescences with the
+  /// given sources and spans all the nodes which are reachable from the
+  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+m).
+  ///
+  /// The algorithm also provides an optimal dual solution, therefore
+  /// the optimality of the solution can be checked.
+  ///
+  /// \param GR The digraph type the algorithm runs on.
+  /// \param CM A read-only arc map storing the costs of the
+  /// arcs. It is read once for each arc, so the map may involve in
+  /// relatively time consuming process to compute the arc costs if
+  /// it is necessary. The default map type is \ref
+  /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
+  /// \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,
+            typename CM = typename GR::template ArcMap<int>,
+            typename TR =
+              MinCostArborescenceDefaultTraits<GR, CM> >
+#else
+  template <typename GR, typename CM, typename TR>
+#endif
+  class MinCostArborescence {
+  public:
+
+    /// \brief The \ref lemon::MinCostArborescenceDefaultTraits "traits class"
+    /// of the algorithm.
+    typedef TR Traits;
+    /// The type of the underlying digraph.
+    typedef typename Traits::Digraph Digraph;
+    /// The type of the map that stores the arc costs.
+    typedef typename Traits::CostMap CostMap;
+    ///The type of the costs of the arcs.
+    typedef typename Traits::Value Value;
+    ///The type of the predecessor map.
+    typedef typename Traits::PredMap PredMap;
+    ///The type of the map that stores which arcs are in the arborescence.
+    typedef typename Traits::ArborescenceMap ArborescenceMap;
+
+    typedef MinCostArborescence Create;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    struct CostArc {
+
+      Arc arc;
+      Value value;
+
+      CostArc() {}
+      CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
+
+    };
+
+    const Digraph *_digraph;
+    const CostMap *_cost;
+
+    PredMap *_pred;
+    bool local_pred;
+
+    ArborescenceMap *_arborescence;
+    bool local_arborescence;
+
+    typedef typename Digraph::template ArcMap<int> ArcOrder;
+    ArcOrder *_arc_order;
+
+    typedef typename Digraph::template NodeMap<int> NodeOrder;
+    NodeOrder *_node_order;
+
+    typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
+    CostArcMap *_cost_arcs;
+
+    struct StackLevel {
+
+      std::vector<CostArc> arcs;
+      int node_level;
+
+    };
+
+    std::vector<StackLevel> level_stack;
+    std::vector<Node> queue;
+
+    typedef std::vector<typename Digraph::Node> DualNodeList;
+
+    DualNodeList _dual_node_list;
+
+    struct DualVariable {
+      int begin, end;
+      Value value;
+
+      DualVariable(int _begin, int _end, Value _value)
+        : begin(_begin), end(_end), value(_value) {}
+
+    };
+
+    typedef std::vector<DualVariable> DualVariables;
+
+    DualVariables _dual_variables;
+
+    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
+
+    HeapCrossRef *_heap_cross_ref;
+
+    typedef BinHeap<int, HeapCrossRef> Heap;
+
+    Heap *_heap;
+
+  protected:
+
+    MinCostArborescence() {}
+
+  private:
+
+    void createStructures() {
+      if (!_pred) {
+        local_pred = true;
+        _pred = Traits::createPredMap(*_digraph);
+      }
+      if (!_arborescence) {
+        local_arborescence = true;
+        _arborescence = Traits::createArborescenceMap(*_digraph);
+      }
+      if (!_arc_order) {
+        _arc_order = new ArcOrder(*_digraph);
+      }
+      if (!_node_order) {
+        _node_order = new NodeOrder(*_digraph);
+      }
+      if (!_cost_arcs) {
+        _cost_arcs = new CostArcMap(*_digraph);
+      }
+      if (!_heap_cross_ref) {
+        _heap_cross_ref = new HeapCrossRef(*_digraph, -1);
+      }
+      if (!_heap) {
+        _heap = new Heap(*_heap_cross_ref);
+      }
+    }
+
+    void destroyStructures() {
+      if (local_arborescence) {
+        delete _arborescence;
+      }
+      if (local_pred) {
+        delete _pred;
+      }
+      if (_arc_order) {
+        delete _arc_order;
+      }
+      if (_node_order) {
+        delete _node_order;
+      }
+      if (_cost_arcs) {
+        delete _cost_arcs;
+      }
+      if (_heap) {
+        delete _heap;
+      }
+      if (_heap_cross_ref) {
+        delete _heap_cross_ref;
+      }
+    }
+
+    Arc prepare(Node node) {
+      std::vector<Node> nodes;
+      (*_node_order)[node] = _dual_node_list.size();
+      StackLevel level;
+      level.node_level = _dual_node_list.size();
+      _dual_node_list.push_back(node);
+      for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
+        Arc arc = it;
+        Node source = _digraph->source(arc);
+        Value value = (*_cost)[it];
+        if (source == node || (*_node_order)[source] == -3) continue;
+        if ((*_cost_arcs)[source].arc == INVALID) {
+          (*_cost_arcs)[source].arc = arc;
+          (*_cost_arcs)[source].value = value;
+          nodes.push_back(source);
+        } else {
+          if ((*_cost_arcs)[source].value > value) {
+            (*_cost_arcs)[source].arc = arc;
+            (*_cost_arcs)[source].value = value;
+          }
+        }
+      }
+      CostArc minimum = (*_cost_arcs)[nodes[0]];
+      for (int i = 1; i < int(nodes.size()); ++i) {
+        if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
+          minimum = (*_cost_arcs)[nodes[i]];
+        }
+      }
+      (*_arc_order)[minimum.arc] = _dual_variables.size();
+      DualVariable var(_dual_node_list.size() - 1,
+                       _dual_node_list.size(), minimum.value);
+      _dual_variables.push_back(var);
+      for (int i = 0; i < int(nodes.size()); ++i) {
+        (*_cost_arcs)[nodes[i]].value -= minimum.value;
+        level.arcs.push_back((*_cost_arcs)[nodes[i]]);
+        (*_cost_arcs)[nodes[i]].arc = INVALID;
+      }
+      level_stack.push_back(level);
+      return minimum.arc;
+    }
+
+    Arc contract(Node node) {
+      int node_bottom = bottom(node);
+      std::vector<Node> nodes;
+      while (!level_stack.empty() &&
+             level_stack.back().node_level >= node_bottom) {
+        for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) {
+          Arc arc = level_stack.back().arcs[i].arc;
+          Node source = _digraph->source(arc);
+          Value value = level_stack.back().arcs[i].value;
+          if ((*_node_order)[source] >= node_bottom) continue;
+          if ((*_cost_arcs)[source].arc == INVALID) {
+            (*_cost_arcs)[source].arc = arc;
+            (*_cost_arcs)[source].value = value;
+            nodes.push_back(source);
+          } else {
+            if ((*_cost_arcs)[source].value > value) {
+              (*_cost_arcs)[source].arc = arc;
+              (*_cost_arcs)[source].value = value;
+            }
+          }
+        }
+        level_stack.pop_back();
+      }
+      CostArc minimum = (*_cost_arcs)[nodes[0]];
+      for (int i = 1; i < int(nodes.size()); ++i) {
+        if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
+          minimum = (*_cost_arcs)[nodes[i]];
+        }
+      }
+      (*_arc_order)[minimum.arc] = _dual_variables.size();
+      DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
+      _dual_variables.push_back(var);
+      StackLevel level;
+      level.node_level = node_bottom;
+      for (int i = 0; i < int(nodes.size()); ++i) {
+        (*_cost_arcs)[nodes[i]].value -= minimum.value;
+        level.arcs.push_back((*_cost_arcs)[nodes[i]]);
+        (*_cost_arcs)[nodes[i]].arc = INVALID;
+      }
+      level_stack.push_back(level);
+      return minimum.arc;
+    }
+
+    int bottom(Node node) {
+      int k = level_stack.size() - 1;
+      while (level_stack[k].node_level > (*_node_order)[node]) {
+        --k;
+      }
+      return level_stack[k].node_level;
+    }
+
+    void finalize(Arc arc) {
+      Node node = _digraph->target(arc);
+      _heap->push(node, (*_arc_order)[arc]);
+      _pred->set(node, arc);
+      while (!_heap->empty()) {
+        Node source = _heap->top();
+        _heap->pop();
+        (*_node_order)[source] = -1;
+        for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
+          if ((*_arc_order)[it] < 0) continue;
+          Node target = _digraph->target(it);
+          switch(_heap->state(target)) {
+          case Heap::PRE_HEAP:
+            _heap->push(target, (*_arc_order)[it]);
+            _pred->set(target, it);
+            break;
+          case Heap::IN_HEAP:
+            if ((*_arc_order)[it] < (*_heap)[target]) {
+              _heap->decrease(target, (*_arc_order)[it]);
+              _pred->set(target, it);
+            }
+            break;
+          case Heap::POST_HEAP:
+            break;
+          }
+        }
+        _arborescence->set((*_pred)[source], true);
+      }
+    }
+
+
+  public:
+
+    /// \name Named Template Parameters
+
+    /// @{
+
+    template <class T>
+    struct SetArborescenceMapTraits : public Traits {
+      typedef T ArborescenceMap;
+      static ArborescenceMap *createArborescenceMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "ArborescenceMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for
+    /// setting \c ArborescenceMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c ArborescenceMap type.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
+    /// and its value type must be \c bool (or convertible).
+    /// Initially it will be set to \c false on each arc,
+    /// then it will be set on each arborescence arc once.
+    template <class T>
+    struct SetArborescenceMap
+      : public MinCostArborescence<Digraph, CostMap,
+                                   SetArborescenceMapTraits<T> > {
+    };
+
+    template <class T>
+    struct SetPredMapTraits : public Traits {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &)
+      {
+        LEMON_ASSERT(false, "PredMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for
+    /// setting \c PredMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c PredMap type.
+    /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
+    /// and its value type must be the \c Arc type of the digraph.
+    template <class T>
+    struct SetPredMap
+      : public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
+    };
+
+    /// @}
+
+    /// \brief Constructor.
+    ///
+    /// \param digraph The digraph the algorithm will run on.
+    /// \param cost The cost map used by the algorithm.
+    MinCostArborescence(const Digraph& digraph, const CostMap& cost)
+      : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
+        _arborescence(0), local_arborescence(false),
+        _arc_order(0), _node_order(0), _cost_arcs(0),
+        _heap_cross_ref(0), _heap(0) {}
+
+    /// \brief Destructor.
+    ~MinCostArborescence() {
+      destroyStructures();
+    }
+
+    /// \brief Sets the arborescence map.
+    ///
+    /// Sets the arborescence map.
+    /// \return <tt>(*this)</tt>
+    MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
+      if (local_arborescence) {
+        delete _arborescence;
+      }
+      local_arborescence = false;
+      _arborescence = &m;
+      return *this;
+    }
+
+    /// \brief Sets the predecessor map.
+    ///
+    /// Sets the predecessor map.
+    /// \return <tt>(*this)</tt>
+    MinCostArborescence& predMap(PredMap& m) {
+      if (local_pred) {
+        delete _pred;
+      }
+      local_pred = false;
+      _pred = &m;
+      return *this;
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use
+    /// one of the member functions called \c run(...). \n
+    /// If you need better control on the execution,
+    /// you have to call \ref init() first, then you can add several
+    /// source nodes with \ref addSource().
+    /// Finally \ref start() will perform the arborescence
+    /// computation.
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures.
+    ///
+    void init() {
+      createStructures();
+      _heap->clear();
+      for (NodeIt it(*_digraph); it != INVALID; ++it) {
+        (*_cost_arcs)[it].arc = INVALID;
+        (*_node_order)[it] = -3;
+        (*_heap_cross_ref)[it] = Heap::PRE_HEAP;
+        _pred->set(it, INVALID);
+      }
+      for (ArcIt it(*_digraph); it != INVALID; ++it) {
+        _arborescence->set(it, false);
+        (*_arc_order)[it] = -1;
+      }
+      _dual_node_list.clear();
+      _dual_variables.clear();
+    }
+
+    /// \brief Adds a new source node.
+    ///
+    /// Adds a new source node to the algorithm.
+    void addSource(Node source) {
+      std::vector<Node> nodes;
+      nodes.push_back(source);
+      while (!nodes.empty()) {
+        Node node = nodes.back();
+        nodes.pop_back();
+        for (OutArcIt it(*_digraph, node); it != INVALID; ++it) {
+          Node target = _digraph->target(it);
+          if ((*_node_order)[target] == -3) {
+            (*_node_order)[target] = -2;
+            nodes.push_back(target);
+            queue.push_back(target);
+          }
+        }
+      }
+      (*_node_order)[source] = -1;
+    }
+
+    /// \brief Processes the next node in the priority queue.
+    ///
+    /// Processes the next node in the priority queue.
+    ///
+    /// \return The processed node.
+    ///
+    /// \warning The queue must not be empty.
+    Node processNextNode() {
+      Node node = queue.back();
+      queue.pop_back();
+      if ((*_node_order)[node] == -2) {
+        Arc arc = prepare(node);
+        Node source = _digraph->source(arc);
+        while ((*_node_order)[source] != -1) {
+          if ((*_node_order)[source] >= 0) {
+            arc = contract(source);
+          } else {
+            arc = prepare(source);
+          }
+          source = _digraph->source(arc);
+        }
+        finalize(arc);
+        level_stack.clear();
+      }
+      return node;
+    }
+
+    /// \brief Returns the number of the nodes to be processed.
+    ///
+    /// Returns the number of the nodes to be processed in the priority
+    /// queue.
+    int queueSize() const {
+      return queue.size();
+    }
+
+    /// \brief Returns \c false if there are nodes to be processed.
+    ///
+    /// Returns \c false if there are nodes to be processed.
+    bool emptyQueue() const {
+      return queue.empty();
+    }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    /// \pre init() must be called and at least one node should be added
+    /// with addSource() before using this function.
+    ///
+    ///\note mca.start() is just a shortcut of the following code.
+    ///\code
+    ///while (!mca.emptyQueue()) {
+    ///  mca.processNextNode();
+    ///}
+    ///\endcode
+    void start() {
+      while (!emptyQueue()) {
+        processNextNode();
+      }
+    }
+
+    /// \brief Runs %MinCostArborescence algorithm from node \c s.
+    ///
+    /// This method runs the %MinCostArborescence algorithm from
+    /// a root node \c s.
+    ///
+    /// \note mca.run(s) is just a shortcut of the following code.
+    /// \code
+    /// mca.init();
+    /// mca.addSource(s);
+    /// mca.start();
+    /// \endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    /// The result of the %MinCostArborescence algorithm can be obtained
+    /// using these functions.\n
+    /// Either run() or start() must be called before using them.
+
+    /// @{
+
+    /// \brief Returns the cost of the arborescence.
+    ///
+    /// Returns the cost of the arborescence.
+    Value arborescenceCost() const {
+      Value sum = 0;
+      for (ArcIt it(*_digraph); it != INVALID; ++it) {
+        if (arborescence(it)) {
+          sum += (*_cost)[it];
+        }
+      }
+      return sum;
+    }
+
+    /// \brief Returns \c true if the arc is in the arborescence.
+    ///
+    /// Returns \c true if the given arc is in the arborescence.
+    /// \param arc An arc of the digraph.
+    /// \pre \ref run() must be called before using this function.
+    bool arborescence(Arc arc) const {
+      return (*_pred)[_digraph->target(arc)] == arc;
+    }
+
+    /// \brief Returns a const reference to the arborescence map.
+    ///
+    /// Returns a const reference to the arborescence map.
+    /// \pre \ref run() must be called before using this function.
+    const ArborescenceMap& arborescenceMap() const {
+      return *_arborescence;
+    }
+
+    /// \brief Returns the predecessor arc of the given node.
+    ///
+    /// Returns the predecessor arc of the given node.
+    /// \pre \ref run() must be called before using this function.
+    Arc pred(Node node) const {
+      return (*_pred)[node];
+    }
+
+    /// \brief Returns a const reference to the pred map.
+    ///
+    /// Returns a const reference to the pred map.
+    /// \pre \ref run() must be called before using this function.
+    const PredMap& predMap() const {
+      return *_pred;
+    }
+
+    /// \brief Indicates that a node is reachable from the sources.
+    ///
+    /// Indicates that a node is reachable from the sources.
+    bool reached(Node node) const {
+      return (*_node_order)[node] != -3;
+    }
+
+    /// \brief Indicates that a node is processed.
+    ///
+    /// Indicates that a node is processed. The arborescence path exists
+    /// from the source to the given node.
+    bool processed(Node node) const {
+      return (*_node_order)[node] == -1;
+    }
+
+    /// \brief Returns the number of the dual variables in basis.
+    ///
+    /// Returns the number of the dual variables in basis.
+    int dualNum() const {
+      return _dual_variables.size();
+    }
+
+    /// \brief Returns the value of the dual solution.
+    ///
+    /// Returns the value of the dual solution. It should be
+    /// equal to the arborescence value.
+    Value dualValue() const {
+      Value sum = 0;
+      for (int i = 0; i < int(_dual_variables.size()); ++i) {
+        sum += _dual_variables[i].value;
+      }
+      return sum;
+    }
+
+    /// \brief Returns the number of the nodes in the dual variable.
+    ///
+    /// Returns the number of the nodes in the dual variable.
+    int dualSize(int k) const {
+      return _dual_variables[k].end - _dual_variables[k].begin;
+    }
+
+    /// \brief Returns the value of the dual variable.
+    ///
+    /// Returns the the value of the dual variable.
+    Value dualValue(int k) const {
+      return _dual_variables[k].value;
+    }
+
+    /// \brief LEMON iterator for getting a dual variable.
+    ///
+    /// This class provides a common style LEMON iterator for getting a
+    /// dual variable of \ref MinCostArborescence algorithm.
+    /// It iterates over a subset of the nodes.
+    class DualIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor for getting the nodeset of the dual variable
+      /// of \ref MinCostArborescence algorithm.
+      DualIt(const MinCostArborescence& algorithm, int variable)
+        : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_dual_variables[variable].begin;
+        _last = _algorithm->_dual_variables[variable].end;
+      }
+
+      /// \brief Conversion to \c Node.
+      ///
+      /// Conversion to \c Node.
+      operator Node() const {
+        return _algorithm->_dual_node_list[_index];
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      DualIt& operator++() {
+        ++_index;
+        return *this;
+      }
+
+      /// \brief Validity checking
+      ///
+      /// Checks whether the iterator is invalid.
+      bool operator==(Invalid) const {
+        return _index == _last;
+      }
+
+      /// \brief Validity checking
+      ///
+      /// Checks whether the iterator is valid.
+      bool operator!=(Invalid) const {
+        return _index != _last;
+      }
+
+    private:
+      const MinCostArborescence* _algorithm;
+      int _index, _last;
+    };
+
+    /// @}
+
+  };
+
+  /// \ingroup spantree
+  ///
+  /// \brief Function type interface for MinCostArborescence algorithm.
+  ///
+  /// Function type interface for MinCostArborescence algorithm.
+  /// \param digraph The digraph the algorithm runs on.
+  /// \param cost An arc map storing the costs.
+  /// \param source The source node of the arborescence.
+  /// \retval arborescence An arc map with \c bool (or convertible) value
+  /// type that stores the arborescence.
+  /// \return The total cost of the arborescence.
+  ///
+  /// \sa MinCostArborescence
+  template <typename Digraph, typename CostMap, typename ArborescenceMap>
+  typename CostMap::Value minCostArborescence(const Digraph& digraph,
+                                              const CostMap& cost,
+                                              typename Digraph::Node source,
+                                              ArborescenceMap& arborescence) {
+    typename MinCostArborescence<Digraph, CostMap>
+      ::template SetArborescenceMap<ArborescenceMap>
+      ::Create mca(digraph, cost);
+    mca.arborescenceMap(arborescence);
+    mca.run(source);
+    return mca.arborescenceCost();
+  }
+
+}
+
+#endif
diff --git a/lemon/nagamochi_ibaraki.h b/lemon/nagamochi_ibaraki.h
new file mode 100644
index 0000000..57a6ba6
--- /dev/null
+++ b/lemon/nagamochi_ibaraki.h
@@ -0,0 +1,702 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_NAGAMOCHI_IBARAKI_H
+#define LEMON_NAGAMOCHI_IBARAKI_H
+
+
+/// \ingroup min_cut
+/// \file
+/// \brief Implementation of the Nagamochi-Ibaraki algorithm.
+
+#include <lemon/core.h>
+#include <lemon/bin_heap.h>
+#include <lemon/bucket_heap.h>
+#include <lemon/maps.h>
+#include <lemon/radix_sort.h>
+#include <lemon/unionfind.h>
+
+#include <cassert>
+
+namespace lemon {
+
+  /// \brief Default traits class for NagamochiIbaraki class.
+  ///
+  /// Default traits class for NagamochiIbaraki class.
+  /// \param GR The undirected graph type.
+  /// \param CM Type of capacity map.
+  template <typename GR, typename CM>
+  struct NagamochiIbarakiDefaultTraits {
+    /// The type of the capacity map.
+    typedef typename CM::Value Value;
+
+    /// The undirected graph type the algorithm runs on.
+    typedef GR Graph;
+
+    /// \brief The type of the map that stores the edge capacities.
+    ///
+    /// The type of the map that stores the edge capacities.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef CM CapacityMap;
+
+    /// \brief Instantiates a CapacityMap.
+    ///
+    /// This function instantiates a \ref CapacityMap.
+#ifdef DOXYGEN
+    static CapacityMap *createCapacityMap(const Graph& graph)
+#else
+    static CapacityMap *createCapacityMap(const Graph&)
+#endif
+    {
+        LEMON_ASSERT(false, "CapacityMap is not initialized");
+        return 0; // ignore warnings
+    }
+
+    /// \brief The cross reference type used by heap.
+    ///
+    /// The cross reference type used by heap.
+    /// Usually \c Graph::NodeMap<int>.
+    typedef typename Graph::template NodeMap<int> HeapCrossRef;
+
+    /// \brief Instantiates a HeapCrossRef.
+    ///
+    /// This function instantiates a \ref HeapCrossRef.
+    /// \param g is the graph, to which we would like to define the
+    /// \ref HeapCrossRef.
+    static HeapCrossRef *createHeapCrossRef(const Graph& g) {
+      return new HeapCrossRef(g);
+    }
+
+    /// \brief The heap type used by NagamochiIbaraki algorithm.
+    ///
+    /// The heap type used by NagamochiIbaraki algorithm. It has to
+    /// maximize the priorities.
+    ///
+    /// \sa BinHeap
+    /// \sa NagamochiIbaraki
+    typedef BinHeap<Value, HeapCrossRef, std::greater<Value> > Heap;
+
+    /// \brief Instantiates a Heap.
+    ///
+    /// This function instantiates a \ref Heap.
+    /// \param r is the cross reference of the heap.
+    static Heap *createHeap(HeapCrossRef& r) {
+      return new Heap(r);
+    }
+  };
+
+  /// \ingroup min_cut
+  ///
+  /// \brief Calculates the minimum cut in an undirected graph.
+  ///
+  /// Calculates the minimum cut in an undirected graph with the
+  /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
+  /// nodes into two partitions with the minimum sum of edge capacities
+  /// between the two partitions. The algorithm can be used to test
+  /// the network reliability, especially to test how many links have
+  /// to be destroyed in the network to split it to at least two
+  /// distinict subnetworks.
+  ///
+  /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
+  /// \ref FibHeap "Fibonacci heap" it can be decreased to
+  /// \f$ O(nm+n^2\log(n)) \f$.  When the edges have unit capacities,
+  /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
+  /// complexity.
+  ///
+  /// \warning The value type of the capacity map should be able to
+  /// hold any cut value of the graph, otherwise the result can
+  /// overflow.
+  /// \note This capacity is supposed to be integer type.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template <typename GR,
+            typename CM = typename GR::template EdgeMap<int>,
+            typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
+#endif
+  class NagamochiIbaraki {
+  public:
+
+    typedef TR Traits;
+    /// The type of the underlying graph.
+    typedef typename Traits::Graph Graph;
+
+    /// The type of the capacity map.
+    typedef typename Traits::CapacityMap CapacityMap;
+    /// The value type of the capacity map.
+    typedef typename Traits::CapacityMap::Value Value;
+
+    /// The heap type used by the algorithm.
+    typedef typename Traits::Heap Heap;
+    /// The cross reference type used for the heap.
+    typedef typename Traits::HeapCrossRef HeapCrossRef;
+
+    ///\name Named template parameters
+
+    ///@{
+
+    struct SetUnitCapacityTraits : public Traits {
+      typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
+      static CapacityMap *createCapacityMap(const Graph&) {
+        return new CapacityMap();
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// the capacity map to a constMap<Edge, int, 1>() instance
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// the capacity map to a constMap<Edge, int, 1>() instance
+    struct SetUnitCapacity
+      : public NagamochiIbaraki<Graph, CapacityMap,
+                                SetUnitCapacityTraits> {
+      typedef NagamochiIbaraki<Graph, CapacityMap,
+                               SetUnitCapacityTraits> Create;
+    };
+
+
+    template <class H, class CR>
+    struct SetHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(int num) {
+        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
+        return 0; // ignore warnings
+      }
+      static Heap *createHeap(HeapCrossRef &) {
+        LEMON_ASSERT(false, "Heap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// heap and cross reference type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting heap and
+    /// cross reference type. The heap has to maximize the priorities.
+    template <class H, class CR = RangeMap<int> >
+    struct SetHeap
+      : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
+      typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
+      Create;
+    };
+
+    template <class H, class CR>
+    struct SetStandardHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(int size) {
+        return new HeapCrossRef(size);
+      }
+      static Heap *createHeap(HeapCrossRef &crossref) {
+        return new Heap(crossref);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// heap and cross reference type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting heap and
+    /// cross reference type with automatic allocation. They should
+    /// have standard constructor interfaces to be able to
+    /// automatically created by the algorithm (i.e. the graph should
+    /// be passed to the constructor of the cross reference and the
+    /// cross reference should be passed to the constructor of the
+    /// heap). However, external heap and cross reference objects
+    /// could also be passed to the algorithm using the \ref heap()
+    /// function before calling \ref run() or \ref init(). The heap
+    /// has to maximize the priorities.
+    /// \sa SetHeap
+    template <class H, class CR = RangeMap<int> >
+    struct SetStandardHeap
+      : public NagamochiIbaraki<Graph, CapacityMap,
+                                SetStandardHeapTraits<H, CR> > {
+      typedef NagamochiIbaraki<Graph, CapacityMap,
+                               SetStandardHeapTraits<H, CR> > Create;
+    };
+
+    ///@}
+
+
+  private:
+
+    const Graph &_graph;
+    const CapacityMap *_capacity;
+    bool _local_capacity; // unit capacity
+
+    struct ArcData {
+      typename Graph::Node target;
+      int prev, next;
+    };
+    struct EdgeData {
+      Value capacity;
+      Value cut;
+    };
+
+    struct NodeData {
+      int first_arc;
+      typename Graph::Node prev, next;
+      int curr_arc;
+      typename Graph::Node last_rep;
+      Value sum;
+    };
+
+    typename Graph::template NodeMap<NodeData> *_nodes;
+    std::vector<ArcData> _arcs;
+    std::vector<EdgeData> _edges;
+
+    typename Graph::Node _first_node;
+    int _node_num;
+
+    Value _min_cut;
+
+    HeapCrossRef *_heap_cross_ref;
+    bool _local_heap_cross_ref;
+    Heap *_heap;
+    bool _local_heap;
+
+    typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
+    NodeList *_next_rep;
+
+    typedef typename Graph::template NodeMap<bool> MinCutMap;
+    MinCutMap *_cut_map;
+
+    void createStructures() {
+      if (!_nodes) {
+        _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
+      }
+      if (!_capacity) {
+        _local_capacity = true;
+        _capacity = Traits::createCapacityMap(_graph);
+      }
+      if (!_heap_cross_ref) {
+        _local_heap_cross_ref = true;
+        _heap_cross_ref = Traits::createHeapCrossRef(_graph);
+      }
+      if (!_heap) {
+        _local_heap = true;
+        _heap = Traits::createHeap(*_heap_cross_ref);
+      }
+      if (!_next_rep) {
+        _next_rep = new NodeList(_graph);
+      }
+      if (!_cut_map) {
+        _cut_map = new MinCutMap(_graph);
+      }
+    }
+
+  protected:
+    //This is here to avoid a gcc-3.3 compilation error.
+    //It should never be called.
+    NagamochiIbaraki() {}
+
+  public:
+
+    typedef NagamochiIbaraki Create;
+
+
+    /// \brief Constructor.
+    ///
+    /// \param graph The graph the algorithm runs on.
+    /// \param capacity The capacity map used by the algorithm.
+    NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
+      : _graph(graph), _capacity(&capacity), _local_capacity(false),
+        _nodes(0), _arcs(), _edges(), _min_cut(),
+        _heap_cross_ref(0), _local_heap_cross_ref(false),
+        _heap(0), _local_heap(false),
+        _next_rep(0), _cut_map(0) {}
+
+    /// \brief Constructor.
+    ///
+    /// This constructor can be used only when the Traits class
+    /// defines how can the local capacity map be instantiated.
+    /// If the SetUnitCapacity used the algorithm automatically
+    /// constructs the capacity map.
+    ///
+    ///\param graph The graph the algorithm runs on.
+    NagamochiIbaraki(const Graph& graph)
+      : _graph(graph), _capacity(0), _local_capacity(false),
+        _nodes(0), _arcs(), _edges(), _min_cut(),
+        _heap_cross_ref(0), _local_heap_cross_ref(false),
+        _heap(0), _local_heap(false),
+        _next_rep(0), _cut_map(0) {}
+
+    /// \brief Destructor.
+    ///
+    /// Destructor.
+    ~NagamochiIbaraki() {
+      if (_local_capacity) delete _capacity;
+      if (_nodes) delete _nodes;
+      if (_local_heap) delete _heap;
+      if (_local_heap_cross_ref) delete _heap_cross_ref;
+      if (_next_rep) delete _next_rep;
+      if (_cut_map) delete _cut_map;
+    }
+
+    /// \brief Sets the heap and the cross reference used by algorithm.
+    ///
+    /// Sets the heap and the cross reference used by algorithm.
+    /// If you don't use this function before calling \ref run(),
+    /// it will allocate one. The destuctor deallocates this
+    /// automatically allocated heap and cross reference, of course.
+    /// \return <tt> (*this) </tt>
+    NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
+    {
+      if (_local_heap_cross_ref) {
+        delete _heap_cross_ref;
+        _local_heap_cross_ref = false;
+      }
+      _heap_cross_ref = &cr;
+      if (_local_heap) {
+        delete _heap;
+        _local_heap = false;
+      }
+      _heap = &hp;
+      return *this;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use
+    /// one of the member functions called \c run().
+    /// \n
+    /// If you need more control on the execution,
+    /// first you must call \ref init() and then call the start()
+    /// or proper times the processNextPhase() member functions.
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures.
+    void init() {
+      createStructures();
+
+      int edge_num = countEdges(_graph);
+      _edges.resize(edge_num);
+      _arcs.resize(2 * edge_num);
+
+      typename Graph::Node prev = INVALID;
+      _node_num = 0;
+      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+        (*_cut_map)[n] = false;
+        (*_next_rep)[n] = INVALID;
+        (*_nodes)[n].last_rep = n;
+        (*_nodes)[n].first_arc = -1;
+        (*_nodes)[n].curr_arc = -1;
+        (*_nodes)[n].prev = prev;
+        if (prev != INVALID) {
+          (*_nodes)[prev].next = n;
+        }
+        (*_nodes)[n].next = INVALID;
+        (*_nodes)[n].sum = 0;
+        prev = n;
+        ++_node_num;
+      }
+
+      _first_node = typename Graph::NodeIt(_graph);
+
+      int index = 0;
+      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+        for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) {
+          typename Graph::Node m = _graph.target(a);
+
+          if (!(n < m)) continue;
+
+          (*_nodes)[n].sum += (*_capacity)[a];
+          (*_nodes)[m].sum += (*_capacity)[a];
+
+          int c = (*_nodes)[m].curr_arc;
+          if (c != -1 && _arcs[c ^ 1].target == n) {
+            _edges[c >> 1].capacity += (*_capacity)[a];
+          } else {
+            _edges[index].capacity = (*_capacity)[a];
+
+            _arcs[index << 1].prev = -1;
+            if ((*_nodes)[n].first_arc != -1) {
+              _arcs[(*_nodes)[n].first_arc].prev = (index << 1);
+            }
+            _arcs[index << 1].next = (*_nodes)[n].first_arc;
+            (*_nodes)[n].first_arc = (index << 1);
+            _arcs[index << 1].target = m;
+
+            (*_nodes)[m].curr_arc = (index << 1);
+
+            _arcs[(index << 1) | 1].prev = -1;
+            if ((*_nodes)[m].first_arc != -1) {
+              _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1);
+            }
+            _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc;
+            (*_nodes)[m].first_arc = ((index << 1) | 1);
+            _arcs[(index << 1) | 1].target = n;
+
+            ++index;
+          }
+        }
+      }
+
+      typename Graph::Node cut_node = INVALID;
+      _min_cut = std::numeric_limits<Value>::max();
+
+      for (typename Graph::Node n = _first_node;
+           n != INVALID; n = (*_nodes)[n].next) {
+        if ((*_nodes)[n].sum < _min_cut) {
+          cut_node = n;
+          _min_cut = (*_nodes)[n].sum;
+        }
+      }
+      (*_cut_map)[cut_node] = true;
+      if (_min_cut == 0) {
+        _first_node = INVALID;
+      }
+    }
+
+  public:
+
+    /// \brief Processes the next phase
+    ///
+    /// Processes the next phase in the algorithm. It must be called
+    /// at most one less the number of the nodes in the graph.
+    ///
+    ///\return %True when the algorithm finished.
+    bool processNextPhase() {
+      if (_first_node == INVALID) return true;
+
+      _heap->clear();
+      for (typename Graph::Node n = _first_node;
+           n != INVALID; n = (*_nodes)[n].next) {
+        (*_heap_cross_ref)[n] = Heap::PRE_HEAP;
+      }
+
+      std::vector<typename Graph::Node> order;
+      order.reserve(_node_num);
+      int sep = 0;
+
+      Value alpha = 0;
+      Value pmc = std::numeric_limits<Value>::max();
+
+      _heap->push(_first_node, static_cast<Value>(0));
+      while (!_heap->empty()) {
+        typename Graph::Node n = _heap->top();
+        Value v = _heap->prio();
+
+        _heap->pop();
+        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
+          switch (_heap->state(_arcs[a].target)) {
+          case Heap::PRE_HEAP:
+            {
+              Value nv = _edges[a >> 1].capacity;
+              _heap->push(_arcs[a].target, nv);
+              _edges[a >> 1].cut = nv;
+            } break;
+          case Heap::IN_HEAP:
+            {
+              Value nv = _edges[a >> 1].capacity + (*_heap)[_arcs[a].target];
+              _heap->decrease(_arcs[a].target, nv);
+              _edges[a >> 1].cut = nv;
+            } break;
+          case Heap::POST_HEAP:
+            break;
+          }
+        }
+
+        alpha += (*_nodes)[n].sum;
+        alpha -= 2 * v;
+
+        order.push_back(n);
+        if (!_heap->empty()) {
+          if (alpha < pmc) {
+            pmc = alpha;
+            sep = order.size();
+          }
+        }
+      }
+
+      if (static_cast<int>(order.size()) < _node_num) {
+        _first_node = INVALID;
+        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+          (*_cut_map)[n] = false;
+        }
+        for (int i = 0; i < static_cast<int>(order.size()); ++i) {
+          typename Graph::Node n = order[i];
+          while (n != INVALID) {
+            (*_cut_map)[n] = true;
+            n = (*_next_rep)[n];
+          }
+        }
+        _min_cut = 0;
+        return true;
+      }
+
+      if (pmc < _min_cut) {
+        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+          (*_cut_map)[n] = false;
+        }
+        for (int i = 0; i < sep; ++i) {
+          typename Graph::Node n = order[i];
+          while (n != INVALID) {
+            (*_cut_map)[n] = true;
+            n = (*_next_rep)[n];
+          }
+        }
+        _min_cut = pmc;
+      }
+
+      for (typename Graph::Node n = _first_node;
+           n != INVALID; n = (*_nodes)[n].next) {
+        bool merged = false;
+        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
+          if (!(_edges[a >> 1].cut < pmc)) {
+            if (!merged) {
+              for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) {
+                (*_nodes)[_arcs[b].target].curr_arc = b;
+              }
+              merged = true;
+            }
+            typename Graph::Node m = _arcs[a].target;
+            int nb = 0;
+            for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) {
+              nb = _arcs[b].next;
+              if ((b ^ a) == 1) continue;
+              typename Graph::Node o = _arcs[b].target;
+              int c = (*_nodes)[o].curr_arc;
+              if (c != -1 && _arcs[c ^ 1].target == n) {
+                _edges[c >> 1].capacity += _edges[b >> 1].capacity;
+                (*_nodes)[n].sum += _edges[b >> 1].capacity;
+                if (_edges[b >> 1].cut < _edges[c >> 1].cut) {
+                  _edges[b >> 1].cut = _edges[c >> 1].cut;
+                }
+                if (_arcs[b ^ 1].prev != -1) {
+                  _arcs[_arcs[b ^ 1].prev].next = _arcs[b ^ 1].next;
+                } else {
+                  (*_nodes)[o].first_arc = _arcs[b ^ 1].next;
+                }
+                if (_arcs[b ^ 1].next != -1) {
+                  _arcs[_arcs[b ^ 1].next].prev = _arcs[b ^ 1].prev;
+                }
+              } else {
+                if (_arcs[a].next != -1) {
+                  _arcs[_arcs[a].next].prev = b;
+                }
+                _arcs[b].next = _arcs[a].next;
+                _arcs[b].prev = a;
+                _arcs[a].next = b;
+                _arcs[b ^ 1].target = n;
+
+                (*_nodes)[n].sum += _edges[b >> 1].capacity;
+                (*_nodes)[o].curr_arc = b;
+              }
+            }
+
+            if (_arcs[a].prev != -1) {
+              _arcs[_arcs[a].prev].next = _arcs[a].next;
+            } else {
+              (*_nodes)[n].first_arc = _arcs[a].next;
+            }
+            if (_arcs[a].next != -1) {
+              _arcs[_arcs[a].next].prev = _arcs[a].prev;
+            }
+
+            (*_nodes)[n].sum -= _edges[a >> 1].capacity;
+            (*_next_rep)[(*_nodes)[n].last_rep] = m;
+            (*_nodes)[n].last_rep = (*_nodes)[m].last_rep;
+
+            if ((*_nodes)[m].prev != INVALID) {
+              (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next;
+            } else{
+              _first_node = (*_nodes)[m].next;
+            }
+            if ((*_nodes)[m].next != INVALID) {
+              (*_nodes)[(*_nodes)[m].next].prev = (*_nodes)[m].prev;
+            }
+            --_node_num;
+          }
+        }
+      }
+
+      if (_node_num == 1) {
+        _first_node = INVALID;
+        return true;
+      }
+
+      return false;
+    }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    /// \pre init() must be called
+    void start() {
+      while (!processNextPhase()) {}
+    }
+
+
+    /// \brief Runs %NagamochiIbaraki algorithm.
+    ///
+    /// This method runs the %Min cut algorithm
+    ///
+    /// \note mc.run(s) is just a shortcut of the following code.
+    ///\code
+    ///  mc.init();
+    ///  mc.start();
+    ///\endcode
+    void run() {
+      init();
+      start();
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    ///
+    /// The result of the %NagamochiIbaraki
+    /// algorithm can be obtained using these functions.\n
+    /// Before the use of these functions, either run() or start()
+    /// must be called.
+
+    ///@{
+
+    /// \brief Returns the min cut value.
+    ///
+    /// Returns the min cut value if the algorithm finished.
+    /// After the first processNextPhase() it is a value of a
+    /// valid cut in the graph.
+    Value minCutValue() const {
+      return _min_cut;
+    }
+
+    /// \brief Returns a min cut in a NodeMap.
+    ///
+    /// It sets the nodes of one of the two partitions to true and
+    /// the other partition to false.
+    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
+    /// \c bool (or convertible) value type.
+    template <typename CutMap>
+    Value minCutMap(CutMap& cutMap) const {
+      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+        cutMap.set(n, (*_cut_map)[n]);
+      }
+      return minCutValue();
+    }
+
+    ///@}
+
+  };
+}
+
+#endif
diff --git a/lemon/nauty_reader.h b/lemon/nauty_reader.h
new file mode 100644
index 0000000..896f2a6
--- /dev/null
+++ b/lemon/nauty_reader.h
@@ -0,0 +1,113 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_NAUTY_READER_H
+#define LEMON_NAUTY_READER_H
+
+#include <vector>
+#include <iostream>
+#include <string>
+
+/// \ingroup nauty_group
+/// \file
+/// \brief Nauty file reader.
+
+namespace lemon {
+
+  /// \ingroup nauty_group
+  ///
+  /// \brief Nauty file reader
+  ///
+  /// The \e geng program is in the \e gtools suite of the nauty
+  /// package. This tool can generate all non-isomorphic undirected
+  /// graphs of several classes with given node number (e.g.
+  /// general, connected, biconnected, triangle-free, 4-cycle-free,
+  /// bipartite and graphs with given edge number and degree
+  /// constraints). This function reads a \e nauty \e graph6 \e format
+  /// line from the given stream and builds it in the given graph.
+  ///
+  /// The site of nauty package: http://cs.anu.edu.au/~bdm/nauty/
+  ///
+  /// For example, the number of all non-isomorphic planar graphs
+  /// can be computed with the following code.
+  ///\code
+  /// int num = 0;
+  /// SmartGraph graph;
+  /// while (readNautyGraph(graph, std::cin)) {
+  ///   PlanarityChecking<SmartGraph> pc(graph);
+  ///   if (pc.run()) ++num;
+  /// }
+  /// std::cout << "Number of planar graphs: " << num << std::endl;
+  ///\endcode
+  ///
+  /// The nauty files are quite huge, therefore instead of the direct
+  /// file generation pipelining is recommended. For example,
+  ///\code
+  /// ./geng -c 10 | ./num_of_planar_graphs
+  ///\endcode
+  template <typename Graph>
+  std::istream& readNautyGraph(Graph& graph, std::istream& is = std::cin) {
+    graph.clear();
+
+    std::string line;
+    if (getline(is, line)) {
+      int index = 0;
+
+      int n;
+
+      if (line[index] == '>') {
+        index += 10;
+      }
+
+      char c = line[index++]; c -= 63;
+      if (c != 63) {
+        n = int(c);
+      } else {
+        c = line[index++]; c -= 63;
+        n = (int(c) << 12);
+        c = line[index++]; c -= 63;
+        n |= (int(c) << 6);
+        c = line[index++]; c -= 63;
+        n |= int(c);
+      }
+
+      std::vector<typename Graph::Node> nodes;
+      for (int i = 0; i < n; ++i) {
+        nodes.push_back(graph.addNode());
+      }
+
+      int bit = -1;
+      for (int j = 0; j < n; ++j) {
+        for (int i = 0; i < j; ++i) {
+          if (bit == -1) {
+            c = line[index++]; c -= 63;
+            bit = 5;
+          }
+          bool b = (c & (1 << (bit--))) != 0;
+
+          if (b) {
+            graph.addEdge(nodes[i], nodes[j]);
+          }
+        }
+      }
+    }
+    return is;
+  }
+}
+
+#endif
diff --git a/lemon/nearest_neighbor_tsp.h b/lemon/nearest_neighbor_tsp.h
new file mode 100644
index 0000000..065e145
--- /dev/null
+++ b/lemon/nearest_neighbor_tsp.h
@@ -0,0 +1,238 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_NEAREST_NEIGHBOUR_TSP_H
+#define LEMON_NEAREST_NEIGHBOUR_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief Nearest neighbor algorithm for symmetric TSP
+
+#include <deque>
+#include <vector>
+#include <limits>
+#include <lemon/full_graph.h>
+#include <lemon/maps.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief Nearest neighbor algorithm for symmetric TSP.
+  ///
+  /// NearestNeighborTsp implements the nearest neighbor heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This is probably the simplest TSP heuristic.
+  /// It starts with a minimum cost edge and at each step, it connects the
+  /// nearest unvisited node to the current path.
+  /// Finally, it connects the two end points of the path to form a tour.
+  ///
+  /// This method runs in O(n<sup>2</sup>) time.
+  /// It quickly finds a relatively short tour for most TSP instances,
+  /// but it could also yield a really bad (or even the worst) solution
+  /// in special cases.
+  ///
+  /// \tparam CM Type of the cost map.
+  template <typename CM>
+  class NearestNeighborTsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      Cost _sum;
+      std::vector<Node> _path;
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      NearestNeighborTsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm.
+      ///
+      /// This function runs the algorithm.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run() {
+        _path.clear();
+        if (_gr.nodeNum() == 0) {
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+
+        std::deque<Node> path_dq;
+        Edge min_edge1 = INVALID,
+             min_edge2 = INVALID;
+
+        min_edge1 = mapMin(_gr, _cost);
+        Node n1 = _gr.u(min_edge1),
+             n2 = _gr.v(min_edge1);
+        path_dq.push_back(n1);
+        path_dq.push_back(n2);
+
+        FullGraph::NodeMap<bool> used(_gr, false);
+        used[n1] = true;
+        used[n2] = true;
+
+        min_edge1 = INVALID;
+        while (int(path_dq.size()) != _gr.nodeNum()) {
+          if (min_edge1 == INVALID) {
+            for (IncEdgeIt e(_gr, n1); e != INVALID; ++e) {
+              if (!used[_gr.runningNode(e)] &&
+                  (min_edge1 == INVALID || _cost[e] < _cost[min_edge1])) {
+                min_edge1 = e;
+              }
+            }
+          }
+
+          if (min_edge2 == INVALID) {
+            for (IncEdgeIt e(_gr, n2); e != INVALID; ++e) {
+              if (!used[_gr.runningNode(e)] &&
+                  (min_edge2 == INVALID||_cost[e] < _cost[min_edge2])) {
+                min_edge2 = e;
+              }
+            }
+          }
+
+          if (_cost[min_edge1] < _cost[min_edge2]) {
+            n1 = _gr.oppositeNode(n1, min_edge1);
+            path_dq.push_front(n1);
+
+            used[n1] = true;
+            min_edge1 = INVALID;
+
+            if (_gr.u(min_edge2) == n1 || _gr.v(min_edge2) == n1)
+              min_edge2 = INVALID;
+          } else {
+            n2 = _gr.oppositeNode(n2, min_edge2);
+            path_dq.push_back(n2);
+
+            used[n2] = true;
+            min_edge2 = INVALID;
+
+            if (_gr.u(min_edge1) == n2 || _gr.v(min_edge1) == n2)
+              min_edge1 = INVALID;
+          }
+        }
+
+        n1 = path_dq.back();
+        n2 = path_dq.front();
+        _path.push_back(n2);
+        _sum = _cost[_gr.edge(n1, n2)];
+        for (int i = 1; i < int(path_dq.size()); ++i) {
+          n1 = n2;
+          n2 = path_dq[i];
+          _path.push_back(n2);
+          _sum += _cost[_gr.edge(n1, n2)];
+        }
+
+        return _sum;
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _path;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_path.begin(), _path.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_path.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_path[i], _path[i+1]));
+        }
+        if (int(_path.size()) >= 2) {
+          path.addBack(_gr.arc(_path.back(), _path.front()));
+        }
+      }
+
+      /// @}
+
+  };
+
+}; // namespace lemon
+
+#endif
diff --git a/lemon/network_simplex.h b/lemon/network_simplex.h
new file mode 100644
index 0000000..6ccad33
--- /dev/null
+++ b/lemon/network_simplex.h
@@ -0,0 +1,1659 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_NETWORK_SIMPLEX_H
+#define LEMON_NETWORK_SIMPLEX_H
+
+/// \ingroup min_cost_flow_algs
+///
+/// \file
+/// \brief Network Simplex algorithm for finding a minimum cost flow.
+
+#include <vector>
+#include <limits>
+#include <algorithm>
+
+#include <lemon/core.h>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \addtogroup min_cost_flow_algs
+  /// @{
+
+  /// \brief Implementation of the primal Network Simplex algorithm
+  /// for finding a \ref min_cost_flow "minimum cost flow".
+  ///
+  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
+  /// for finding a \ref min_cost_flow "minimum cost flow"
+  /// \cite amo93networkflows, \cite dantzig63linearprog,
+  /// \cite kellyoneill91netsimplex.
+  /// This algorithm is a highly efficient specialized version of the
+  /// linear programming simplex method directly for the minimum cost
+  /// flow problem.
+  ///
+  /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest
+  /// implementations available in LEMON for solving this problem.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
+  /// Furthermore, this class supports both directions of the supply/demand
+  /// inequality constraints. For more information, see \ref SupplyType.
+  ///
+  /// Most of the parameters of the problem (except for the digraph)
+  /// can be given using separate functions, and the algorithm can be
+  /// executed using the \ref run() function. If some parameters are not
+  /// specified, then default values will be used.
+  ///
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam V The number type used for flow amounts, capacity bounds
+  /// and supply values in the algorithm. By default, it is \c int.
+  /// \tparam C The number type used for costs and potentials in the
+  /// algorithm. By default, it is the same as \c V.
+  ///
+  /// \warning Both \c V and \c C must be signed number types.
+  /// \warning All input data (capacities, supply values, and costs) must
+  /// be integer.
+  ///
+  /// \note %NetworkSimplex provides five different pivot rule
+  /// implementations, from which the most efficient one is used
+  /// by default. For more information, see \ref PivotRule.
+  template <typename GR, typename V = int, typename C = V>
+  class NetworkSimplex
+  {
+  public:
+
+    /// The type of the flow amounts, capacity bounds and supply values
+    typedef V Value;
+    /// The type of the arc costs
+    typedef C Cost;
+
+  public:
+
+    /// \brief Problem type constants for the \c run() function.
+    ///
+    /// Enum type containing the problem type constants that can be
+    /// returned by the \ref run() function of the algorithm.
+    enum ProblemType {
+      /// The problem has no feasible solution (flow).
+      INFEASIBLE,
+      /// The problem has optimal solution (i.e. it is feasible and
+      /// bounded), and the algorithm has found optimal flow and node
+      /// potentials (primal and dual solutions).
+      OPTIMAL,
+      /// The objective function of the problem is unbounded, i.e.
+      /// there is a directed cycle having negative total cost and
+      /// infinite upper bound.
+      UNBOUNDED
+    };
+
+    /// \brief Constants for selecting the type of the supply constraints.
+    ///
+    /// Enum type containing constants for selecting the supply type,
+    /// i.e. the direction of the inequalities in the supply/demand
+    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
+    ///
+    /// The default supply type is \c GEQ, the \c LEQ type can be
+    /// selected using \ref supplyType().
+    /// The equality form is a special case of both supply types.
+    enum SupplyType {
+      /// This option means that there are <em>"greater or equal"</em>
+      /// supply/demand constraints in the definition of the problem.
+      GEQ,
+      /// This option means that there are <em>"less or equal"</em>
+      /// supply/demand constraints in the definition of the problem.
+      LEQ
+    };
+
+    /// \brief Constants for selecting the pivot rule.
+    ///
+    /// Enum type containing constants for selecting the pivot rule for
+    /// the \ref run() function.
+    ///
+    /// \ref NetworkSimplex provides five different implementations for
+    /// the pivot strategy that significantly affects the running time
+    /// of the algorithm.
+    /// According to experimental tests conducted on various problem
+    /// instances, \ref BLOCK_SEARCH "Block Search" and
+    /// \ref ALTERING_LIST "Altering Candidate List" rules turned out
+    /// to be the most efficient.
+    /// Since \ref BLOCK_SEARCH "Block Search" is a simpler strategy that
+    /// seemed to be slightly more robust, it is used by default.
+    /// However, another pivot rule can easily be selected using the
+    /// \ref run() function with the proper parameter.
+    enum PivotRule {
+
+      /// The \e First \e Eligible pivot rule.
+      /// The next eligible arc is selected in a wraparound fashion
+      /// in every iteration.
+      FIRST_ELIGIBLE,
+
+      /// The \e Best \e Eligible pivot rule.
+      /// The best eligible arc is selected in every iteration.
+      BEST_ELIGIBLE,
+
+      /// The \e Block \e Search pivot rule.
+      /// A specified number of arcs are examined in every iteration
+      /// in a wraparound fashion and the best eligible arc is selected
+      /// from this block.
+      BLOCK_SEARCH,
+
+      /// The \e Candidate \e List pivot rule.
+      /// In a major iteration a candidate list is built from eligible arcs
+      /// in a wraparound fashion and in the following minor iterations
+      /// the best eligible arc is selected from this list.
+      CANDIDATE_LIST,
+
+      /// The \e Altering \e Candidate \e List pivot rule.
+      /// It is a modified version of the Candidate List method.
+      /// It keeps only a few of the best eligible arcs from the former
+      /// candidate list and extends this list in every iteration.
+      ALTERING_LIST
+    };
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+    typedef std::vector<int> IntVector;
+    typedef std::vector<Value> ValueVector;
+    typedef std::vector<Cost> CostVector;
+    typedef std::vector<signed char> CharVector;
+    // Note: vector<signed char> is used instead of vector<ArcState> and
+    // vector<ArcDirection> for efficiency reasons
+
+    // State constants for arcs
+    enum ArcState {
+      STATE_UPPER = -1,
+      STATE_TREE  =  0,
+      STATE_LOWER =  1
+    };
+
+    // Direction constants for tree arcs
+    enum ArcDirection {
+      DIR_DOWN = -1,
+      DIR_UP   =  1
+    };
+
+  private:
+
+    // Data related to the underlying digraph
+    const GR &_graph;
+    int _node_num;
+    int _arc_num;
+    int _all_arc_num;
+    int _search_arc_num;
+
+    // Parameters of the problem
+    bool _has_lower;
+    SupplyType _stype;
+    Value _sum_supply;
+
+    // Data structures for storing the digraph
+    IntNodeMap _node_id;
+    IntArcMap _arc_id;
+    IntVector _source;
+    IntVector _target;
+    bool _arc_mixing;
+
+    // Node and arc data
+    ValueVector _lower;
+    ValueVector _upper;
+    ValueVector _cap;
+    CostVector _cost;
+    ValueVector _supply;
+    ValueVector _flow;
+    CostVector _pi;
+
+    // Data for storing the spanning tree structure
+    IntVector _parent;
+    IntVector _pred;
+    IntVector _thread;
+    IntVector _rev_thread;
+    IntVector _succ_num;
+    IntVector _last_succ;
+    CharVector _pred_dir;
+    CharVector _state;
+    IntVector _dirty_revs;
+    int _root;
+
+    // Temporary data used in the current pivot iteration
+    int in_arc, join, u_in, v_in, u_out, v_out;
+    Value delta;
+
+    const Value MAX;
+
+  public:
+
+    /// \brief Constant for infinite upper bounds (capacities).
+    ///
+    /// Constant for infinite upper bounds (capacities).
+    /// It is \c std::numeric_limits<Value>::infinity() if available,
+    /// \c std::numeric_limits<Value>::max() otherwise.
+    const Value INF;
+
+  private:
+
+    // Implementation of the First Eligible pivot rule
+    class FirstEligiblePivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const CharVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+      // Pivot rule data
+      int _next_arc;
+
+    public:
+
+      // Constructor
+      FirstEligiblePivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
+        _next_arc(0)
+      {}
+
+      // Find next entering arc
+      bool findEnteringArc() {
+        Cost c;
+        for (int e = _next_arc; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _in_arc = e;
+            _next_arc = e + 1;
+            return true;
+          }
+        }
+        for (int e = 0; e != _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _in_arc = e;
+            _next_arc = e + 1;
+            return true;
+          }
+        }
+        return false;
+      }
+
+    }; //class FirstEligiblePivotRule
+
+
+    // Implementation of the Best Eligible pivot rule
+    class BestEligiblePivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const CharVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+    public:
+
+      // Constructor
+      BestEligiblePivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
+      {}
+
+      // Find next entering arc
+      bool findEnteringArc() {
+        Cost c, min = 0;
+        for (int e = 0; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < min) {
+            min = c;
+            _in_arc = e;
+          }
+        }
+        return min < 0;
+      }
+
+    }; //class BestEligiblePivotRule
+
+
+    // Implementation of the Block Search pivot rule
+    class BlockSearchPivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const CharVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+      // Pivot rule data
+      int _block_size;
+      int _next_arc;
+
+    public:
+
+      // Constructor
+      BlockSearchPivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
+        _next_arc(0)
+      {
+        // The main parameters of the pivot rule
+        const double BLOCK_SIZE_FACTOR = 1.0;
+        const int MIN_BLOCK_SIZE = 10;
+
+        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
+                                    std::sqrt(double(_search_arc_num))),
+                                MIN_BLOCK_SIZE );
+      }
+
+      // Find next entering arc
+      bool findEnteringArc() {
+        Cost c, min = 0;
+        int cnt = _block_size;
+        int e;
+        for (e = _next_arc; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < min) {
+            min = c;
+            _in_arc = e;
+          }
+          if (--cnt == 0) {
+            if (min < 0) goto search_end;
+            cnt = _block_size;
+          }
+        }
+        for (e = 0; e != _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < min) {
+            min = c;
+            _in_arc = e;
+          }
+          if (--cnt == 0) {
+            if (min < 0) goto search_end;
+            cnt = _block_size;
+          }
+        }
+        if (min >= 0) return false;
+
+      search_end:
+        _next_arc = e;
+        return true;
+      }
+
+    }; //class BlockSearchPivotRule
+
+
+    // Implementation of the Candidate List pivot rule
+    class CandidateListPivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const CharVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+      // Pivot rule data
+      IntVector _candidates;
+      int _list_length, _minor_limit;
+      int _curr_length, _minor_count;
+      int _next_arc;
+
+    public:
+
+      /// Constructor
+      CandidateListPivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
+        _next_arc(0)
+      {
+        // The main parameters of the pivot rule
+        const double LIST_LENGTH_FACTOR = 0.25;
+        const int MIN_LIST_LENGTH = 10;
+        const double MINOR_LIMIT_FACTOR = 0.1;
+        const int MIN_MINOR_LIMIT = 3;
+
+        _list_length = std::max( int(LIST_LENGTH_FACTOR *
+                                     std::sqrt(double(_search_arc_num))),
+                                 MIN_LIST_LENGTH );
+        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
+                                 MIN_MINOR_LIMIT );
+        _curr_length = _minor_count = 0;
+        _candidates.resize(_list_length);
+      }
+
+      /// Find next entering arc
+      bool findEnteringArc() {
+        Cost min, c;
+        int e;
+        if (_curr_length > 0 && _minor_count < _minor_limit) {
+          // Minor iteration: select the best eligible arc from the
+          // current candidate list
+          ++_minor_count;
+          min = 0;
+          for (int i = 0; i < _curr_length; ++i) {
+            e = _candidates[i];
+            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+            if (c < min) {
+              min = c;
+              _in_arc = e;
+            }
+            else if (c >= 0) {
+              _candidates[i--] = _candidates[--_curr_length];
+            }
+          }
+          if (min < 0) return true;
+        }
+
+        // Major iteration: build a new candidate list
+        min = 0;
+        _curr_length = 0;
+        for (e = _next_arc; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _candidates[_curr_length++] = e;
+            if (c < min) {
+              min = c;
+              _in_arc = e;
+            }
+            if (_curr_length == _list_length) goto search_end;
+          }
+        }
+        for (e = 0; e != _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _candidates[_curr_length++] = e;
+            if (c < min) {
+              min = c;
+              _in_arc = e;
+            }
+            if (_curr_length == _list_length) goto search_end;
+          }
+        }
+        if (_curr_length == 0) return false;
+
+      search_end:
+        _minor_count = 1;
+        _next_arc = e;
+        return true;
+      }
+
+    }; //class CandidateListPivotRule
+
+
+    // Implementation of the Altering Candidate List pivot rule
+    class AlteringListPivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const CharVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+      // Pivot rule data
+      int _block_size, _head_length, _curr_length;
+      int _next_arc;
+      IntVector _candidates;
+      CostVector _cand_cost;
+
+      // Functor class to compare arcs during sort of the candidate list
+      class SortFunc
+      {
+      private:
+        const CostVector &_map;
+      public:
+        SortFunc(const CostVector &map) : _map(map) {}
+        bool operator()(int left, int right) {
+          return _map[left] < _map[right];
+        }
+      };
+
+      SortFunc _sort_func;
+
+    public:
+
+      // Constructor
+      AlteringListPivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
+        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
+      {
+        // The main parameters of the pivot rule
+        const double BLOCK_SIZE_FACTOR = 1.0;
+        const int MIN_BLOCK_SIZE = 10;
+        const double HEAD_LENGTH_FACTOR = 0.01;
+        const int MIN_HEAD_LENGTH = 3;
+
+        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
+                                    std::sqrt(double(_search_arc_num))),
+                                MIN_BLOCK_SIZE );
+        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
+                                 MIN_HEAD_LENGTH );
+        _candidates.resize(_head_length + _block_size);
+        _curr_length = 0;
+      }
+
+      // Find next entering arc
+      bool findEnteringArc() {
+        // Check the current candidate list
+        int e;
+        Cost c;
+        for (int i = 0; i != _curr_length; ++i) {
+          e = _candidates[i];
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _cand_cost[e] = c;
+          } else {
+            _candidates[i--] = _candidates[--_curr_length];
+          }
+        }
+
+        // Extend the list
+        int cnt = _block_size;
+        int limit = _head_length;
+
+        for (e = _next_arc; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _cand_cost[e] = c;
+            _candidates[_curr_length++] = e;
+          }
+          if (--cnt == 0) {
+            if (_curr_length > limit) goto search_end;
+            limit = 0;
+            cnt = _block_size;
+          }
+        }
+        for (e = 0; e != _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _cand_cost[e] = c;
+            _candidates[_curr_length++] = e;
+          }
+          if (--cnt == 0) {
+            if (_curr_length > limit) goto search_end;
+            limit = 0;
+            cnt = _block_size;
+          }
+        }
+        if (_curr_length == 0) return false;
+
+      search_end:
+
+        // Perform partial sort operation on the candidate list
+        int new_length = std::min(_head_length + 1, _curr_length);
+        std::partial_sort(_candidates.begin(), _candidates.begin() + new_length,
+                          _candidates.begin() + _curr_length, _sort_func);
+
+        // Select the entering arc and remove it from the list
+        _in_arc = _candidates[0];
+        _next_arc = e;
+        _candidates[0] = _candidates[new_length - 1];
+        _curr_length = new_length - 1;
+        return true;
+      }
+
+    }; //class AlteringListPivotRule
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    /// \param arc_mixing Indicate if the arcs will be stored in a
+    /// mixed order in the internal data structure.
+    /// In general, it leads to similar performance as using the original
+    /// arc order, but it makes the algorithm more robust and in special
+    /// cases, even significantly faster. Therefore, it is enabled by default.
+    NetworkSimplex(const GR& graph, bool arc_mixing = true) :
+      _graph(graph), _node_id(graph), _arc_id(graph),
+      _arc_mixing(arc_mixing),
+      MAX(std::numeric_limits<Value>::max()),
+      INF(std::numeric_limits<Value>::has_infinity ?
+          std::numeric_limits<Value>::infinity() : MAX)
+    {
+      // Check the number types
+      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
+        "The flow type of NetworkSimplex must be signed");
+      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
+        "The cost type of NetworkSimplex must be signed");
+
+      // Reset data structures
+      reset();
+    }
+
+    /// \name Parameters
+    /// The parameters of the algorithm can be specified using these
+    /// functions.
+
+    /// @{
+
+    /// \brief Set the lower bounds on the arcs.
+    ///
+    /// This function sets the lower bounds on the arcs.
+    /// If it is not used before calling \ref run(), the lower bounds
+    /// will be set to zero on all arcs.
+    ///
+    /// \param map An arc map storing the lower bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template <typename LowerMap>
+    NetworkSimplex& lowerMap(const LowerMap& map) {
+      _has_lower = true;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _lower[_arc_id[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the upper bounds (capacities) on the arcs.
+    ///
+    /// This function sets the upper bounds (capacities) on the arcs.
+    /// If it is not used before calling \ref run(), the upper bounds
+    /// will be set to \ref INF on all arcs (i.e. the flow value will be
+    /// unbounded from above).
+    ///
+    /// \param map An arc map storing the upper bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename UpperMap>
+    NetworkSimplex& upperMap(const UpperMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _upper[_arc_id[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the costs of the arcs.
+    ///
+    /// This function sets the costs of the arcs.
+    /// If it is not used before calling \ref run(), the costs
+    /// will be set to \c 1 on all arcs.
+    ///
+    /// \param map An arc map storing the costs.
+    /// Its \c Value type must be convertible to the \c Cost type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename CostMap>
+    NetworkSimplex& costMap(const CostMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _cost[_arc_id[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the supply values of the nodes.
+    ///
+    /// This function sets the supply values of the nodes.
+    /// If neither this function nor \ref stSupply() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// \param map A node map storing the supply values.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \sa supplyType()
+    template<typename SupplyMap>
+    NetworkSimplex& supplyMap(const SupplyMap& map) {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _supply[_node_id[n]] = map[n];
+      }
+      return *this;
+    }
+
+    /// \brief Set single source and target nodes and a supply value.
+    ///
+    /// This function sets a single source node and a single target node
+    /// and the required flow value.
+    /// If neither this function nor \ref supplyMap() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// Using this function has the same effect as using \ref supplyMap()
+    /// with a map in which \c k is assigned to \c s, \c -k is
+    /// assigned to \c t and all other nodes have zero supply value.
+    ///
+    /// \param s The source node.
+    /// \param t The target node.
+    /// \param k The required amount of flow from node \c s to node \c t
+    /// (i.e. the supply of \c s and the demand of \c t).
+    ///
+    /// \return <tt>(*this)</tt>
+    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
+      for (int i = 0; i != _node_num; ++i) {
+        _supply[i] = 0;
+      }
+      _supply[_node_id[s]] =  k;
+      _supply[_node_id[t]] = -k;
+      return *this;
+    }
+
+    /// \brief Set the type of the supply constraints.
+    ///
+    /// This function sets the type of the supply/demand constraints.
+    /// If it is not used before calling \ref run(), the \ref GEQ supply
+    /// type will be used.
+    ///
+    /// For more information, see \ref SupplyType.
+    ///
+    /// \return <tt>(*this)</tt>
+    NetworkSimplex& supplyType(SupplyType supply_type) {
+      _stype = supply_type;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Execution Control
+    /// The algorithm can be executed using \ref run().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// The paramters can be specified using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
+    /// \ref supplyType().
+    /// For example,
+    /// \code
+    ///   NetworkSimplex<ListDigraph> ns(graph);
+    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// This function can be called more than once. All the given parameters
+    /// are kept for the next call, unless \ref resetParams() or \ref reset()
+    /// is used, thus only the modified parameters have to be set again.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class (or the last \ref reset() call), then the \ref reset()
+    /// function must be called.
+    ///
+    /// \param pivot_rule The pivot rule that will be used during the
+    /// algorithm. For more information, see \ref PivotRule.
+    ///
+    /// \return \c INFEASIBLE if no feasible flow exists,
+    /// \n \c OPTIMAL if the problem has optimal solution
+    /// (i.e. it is feasible and bounded), and the algorithm has found
+    /// optimal flow and node potentials (primal and dual solutions),
+    /// \n \c UNBOUNDED if the objective function of the problem is
+    /// unbounded, i.e. there is a directed cycle having negative total
+    /// cost and infinite upper bound.
+    ///
+    /// \see ProblemType, PivotRule
+    /// \see resetParams(), reset()
+    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
+      if (!init()) return INFEASIBLE;
+      return start(pivot_rule);
+    }
+
+    /// \brief Reset all the parameters that have been given before.
+    ///
+    /// This function resets all the paramaters that have been given
+    /// before using functions \ref lowerMap(), \ref upperMap(),
+    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// For example,
+    /// \code
+    ///   NetworkSimplex<ListDigraph> ns(graph);
+    ///
+    ///   // First run
+    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    ///
+    ///   // Run again with modified cost map (resetParams() is not called,
+    ///   // so only the cost map have to be set again)
+    ///   cost[e] += 100;
+    ///   ns.costMap(cost).run();
+    ///
+    ///   // Run again from scratch using resetParams()
+    ///   // (the lower bounds will be set to zero on all arcs)
+    ///   ns.resetParams();
+    ///   ns.upperMap(capacity).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see reset(), run()
+    NetworkSimplex& resetParams() {
+      for (int i = 0; i != _node_num; ++i) {
+        _supply[i] = 0;
+      }
+      for (int i = 0; i != _arc_num; ++i) {
+        _lower[i] = 0;
+        _upper[i] = INF;
+        _cost[i] = 1;
+      }
+      _has_lower = false;
+      _stype = GEQ;
+      return *this;
+    }
+
+    /// \brief Reset the internal data structures and all the parameters
+    /// that have been given before.
+    ///
+    /// This function resets the internal data structures and all the
+    /// paramaters that have been given before using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
+    /// \ref supplyType().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// See \ref resetParams() for examples.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see resetParams(), run()
+    NetworkSimplex& reset() {
+      // Resize vectors
+      _node_num = countNodes(_graph);
+      _arc_num = countArcs(_graph);
+      int all_node_num = _node_num + 1;
+      int max_arc_num = _arc_num + 2 * _node_num;
+
+      _source.resize(max_arc_num);
+      _target.resize(max_arc_num);
+
+      _lower.resize(_arc_num);
+      _upper.resize(_arc_num);
+      _cap.resize(max_arc_num);
+      _cost.resize(max_arc_num);
+      _supply.resize(all_node_num);
+      _flow.resize(max_arc_num);
+      _pi.resize(all_node_num);
+
+      _parent.resize(all_node_num);
+      _pred.resize(all_node_num);
+      _pred_dir.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 && _node_num > 1) {
+        // Store the arcs in a mixed order
+        const int skip = std::max(_arc_num / _node_num, 3);
+        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 += skip) >= _arc_num) i = ++j;
+        }
+      } else {
+        // Store the arcs in the original order
+        int i = 0;
+        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
+          _arc_id[a] = i;
+          _source[i] = _node_id[_graph.source(a)];
+          _target[i] = _node_id[_graph.target(a)];
+        }
+      }
+
+      // Reset parameters
+      resetParams();
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The \ref run() function must be called before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found flow.
+    ///
+    /// This function returns the total cost of the found flow.
+    /// Its complexity is O(m).
+    ///
+    /// \note The return type of the function can be specified as a
+    /// template parameter. For example,
+    /// \code
+    ///   ns.totalCost<double>();
+    /// \endcode
+    /// It is useful if the total cost cannot be stored in the \c Cost
+    /// type of the algorithm, which is the default return type of the
+    /// function.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename Number>
+    Number totalCost() const {
+      Number c = 0;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        int i = _arc_id[a];
+        c += Number(_flow[i]) * Number(_cost[i]);
+      }
+      return c;
+    }
+
+#ifndef DOXYGEN
+    Cost totalCost() const {
+      return totalCost<Cost>();
+    }
+#endif
+
+    /// \brief Return the flow on the given arc.
+    ///
+    /// This function returns the flow on the given arc.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Value flow(const Arc& a) const {
+      return _flow[_arc_id[a]];
+    }
+
+    /// \brief Copy the flow values (the primal solution) into the
+    /// given map.
+    ///
+    /// This function copies the flow value on each arc into the given
+    /// map. The \c Value type of the algorithm must be convertible to
+    /// the \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename FlowMap>
+    void flowMap(FlowMap &map) const {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        map.set(a, _flow[_arc_id[a]]);
+      }
+    }
+
+    /// \brief Return the potential (dual value) of the given node.
+    ///
+    /// This function returns the potential (dual value) of the
+    /// given node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const Node& n) const {
+      return _pi[_node_id[n]];
+    }
+
+    /// \brief Copy the potential values (the dual solution) into the
+    /// given map.
+    ///
+    /// This function copies the potential (dual value) of each node
+    /// into the given map.
+    /// The \c Cost type of the algorithm must be convertible to the
+    /// \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename PotentialMap>
+    void potentialMap(PotentialMap &map) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        map.set(n, _pi[_node_id[n]]);
+      }
+    }
+
+    /// @}
+
+  private:
+
+    // Initialize internal data structures
+    bool init() {
+      if (_node_num == 0) return false;
+
+      // Check the sum of supply values
+      _sum_supply = 0;
+      for (int i = 0; i != _node_num; ++i) {
+        _sum_supply += _supply[i];
+      }
+      if ( !((_stype == GEQ && _sum_supply <= 0) ||
+             (_stype == LEQ && _sum_supply >= 0)) ) return false;
+
+      // Check lower and upper bounds
+      LEMON_DEBUG(checkBoundMaps(),
+          "Upper bounds must be greater or equal to the lower bounds");
+
+      // Remove non-zero lower bounds
+      if (_has_lower) {
+        for (int i = 0; i != _arc_num; ++i) {
+          Value c = _lower[i];
+          if (c >= 0) {
+            _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
+          } else {
+            _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
+          }
+          _supply[_source[i]] -= c;
+          _supply[_target[i]] += c;
+        }
+      } else {
+        for (int i = 0; i != _arc_num; ++i) {
+          _cap[i] = _upper[i];
+        }
+      }
+
+      // Initialize artifical cost
+      Cost ART_COST;
+      if (std::numeric_limits<Cost>::is_exact) {
+        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
+      } else {
+        ART_COST = 0;
+        for (int i = 0; i != _arc_num; ++i) {
+          if (_cost[i] > ART_COST) ART_COST = _cost[i];
+        }
+        ART_COST = (ART_COST + 1) * _node_num;
+      }
+
+      // Initialize arc maps
+      for (int i = 0; i != _arc_num; ++i) {
+        _flow[i] = 0;
+        _state[i] = STATE_LOWER;
+      }
+
+      // Set data for the artificial root node
+      _root = _node_num;
+      _parent[_root] = -1;
+      _pred[_root] = -1;
+      _thread[_root] = 0;
+      _rev_thread[0] = _root;
+      _succ_num[_root] = _node_num + 1;
+      _last_succ[_root] = _root - 1;
+      _supply[_root] = -_sum_supply;
+      _pi[_root] = 0;
+
+      // Add artificial arcs and initialize the spanning tree data structure
+      if (_sum_supply == 0) {
+        // EQ supply constraints
+        _search_arc_num = _arc_num;
+        _all_arc_num = _arc_num + _node_num;
+        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
+          _parent[u] = _root;
+          _pred[u] = e;
+          _thread[u] = u + 1;
+          _rev_thread[u + 1] = u;
+          _succ_num[u] = 1;
+          _last_succ[u] = u;
+          _cap[e] = INF;
+          _state[e] = STATE_TREE;
+          if (_supply[u] >= 0) {
+            _pred_dir[u] = DIR_UP;
+            _pi[u] = 0;
+            _source[e] = u;
+            _target[e] = _root;
+            _flow[e] = _supply[u];
+            _cost[e] = 0;
+          } else {
+            _pred_dir[u] = DIR_DOWN;
+            _pi[u] = ART_COST;
+            _source[e] = _root;
+            _target[e] = u;
+            _flow[e] = -_supply[u];
+            _cost[e] = ART_COST;
+          }
+        }
+      }
+      else if (_sum_supply > 0) {
+        // LEQ supply constraints
+        _search_arc_num = _arc_num + _node_num;
+        int f = _arc_num + _node_num;
+        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
+          _parent[u] = _root;
+          _thread[u] = u + 1;
+          _rev_thread[u + 1] = u;
+          _succ_num[u] = 1;
+          _last_succ[u] = u;
+          if (_supply[u] >= 0) {
+            _pred_dir[u] = DIR_UP;
+            _pi[u] = 0;
+            _pred[u] = e;
+            _source[e] = u;
+            _target[e] = _root;
+            _cap[e] = INF;
+            _flow[e] = _supply[u];
+            _cost[e] = 0;
+            _state[e] = STATE_TREE;
+          } else {
+            _pred_dir[u] = DIR_DOWN;
+            _pi[u] = ART_COST;
+            _pred[u] = f;
+            _source[f] = _root;
+            _target[f] = u;
+            _cap[f] = INF;
+            _flow[f] = -_supply[u];
+            _cost[f] = ART_COST;
+            _state[f] = STATE_TREE;
+            _source[e] = u;
+            _target[e] = _root;
+            _cap[e] = INF;
+            _flow[e] = 0;
+            _cost[e] = 0;
+            _state[e] = STATE_LOWER;
+            ++f;
+          }
+        }
+        _all_arc_num = f;
+      }
+      else {
+        // GEQ supply constraints
+        _search_arc_num = _arc_num + _node_num;
+        int f = _arc_num + _node_num;
+        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
+          _parent[u] = _root;
+          _thread[u] = u + 1;
+          _rev_thread[u + 1] = u;
+          _succ_num[u] = 1;
+          _last_succ[u] = u;
+          if (_supply[u] <= 0) {
+            _pred_dir[u] = DIR_DOWN;
+            _pi[u] = 0;
+            _pred[u] = e;
+            _source[e] = _root;
+            _target[e] = u;
+            _cap[e] = INF;
+            _flow[e] = -_supply[u];
+            _cost[e] = 0;
+            _state[e] = STATE_TREE;
+          } else {
+            _pred_dir[u] = DIR_UP;
+            _pi[u] = -ART_COST;
+            _pred[u] = f;
+            _source[f] = u;
+            _target[f] = _root;
+            _cap[f] = INF;
+            _flow[f] = _supply[u];
+            _state[f] = STATE_TREE;
+            _cost[f] = ART_COST;
+            _source[e] = _root;
+            _target[e] = u;
+            _cap[e] = INF;
+            _flow[e] = 0;
+            _cost[e] = 0;
+            _state[e] = STATE_LOWER;
+            ++f;
+          }
+        }
+        _all_arc_num = f;
+      }
+
+      return true;
+    }
+
+    // Check if the upper bound is greater than or equal to the lower bound
+    // on each arc.
+    bool checkBoundMaps() {
+      for (int j = 0; j != _arc_num; ++j) {
+        if (_upper[j] < _lower[j]) return false;
+      }
+      return true;
+    }
+
+    // Find the join node
+    void findJoinNode() {
+      int u = _source[in_arc];
+      int v = _target[in_arc];
+      while (u != v) {
+        if (_succ_num[u] < _succ_num[v]) {
+          u = _parent[u];
+        } else {
+          v = _parent[v];
+        }
+      }
+      join = u;
+    }
+
+    // Find the leaving arc of the cycle and returns true if the
+    // leaving arc is not the same as the entering arc
+    bool findLeavingArc() {
+      // Initialize first and second nodes according to the direction
+      // of the cycle
+      int first, second;
+      if (_state[in_arc] == STATE_LOWER) {
+        first  = _source[in_arc];
+        second = _target[in_arc];
+      } else {
+        first  = _target[in_arc];
+        second = _source[in_arc];
+      }
+      delta = _cap[in_arc];
+      int result = 0;
+      Value c, d;
+      int e;
+
+      // Search the cycle form the first node to the join node
+      for (int u = first; u != join; u = _parent[u]) {
+        e = _pred[u];
+        d = _flow[e];
+        if (_pred_dir[u] == DIR_DOWN) {
+          c = _cap[e];
+          d = c >= MAX ? INF : c - d;
+        }
+        if (d < delta) {
+          delta = d;
+          u_out = u;
+          result = 1;
+        }
+      }
+
+      // Search the cycle form the second node to the join node
+      for (int u = second; u != join; u = _parent[u]) {
+        e = _pred[u];
+        d = _flow[e];
+        if (_pred_dir[u] == DIR_UP) {
+          c = _cap[e];
+          d = c >= MAX ? INF : c - d;
+        }
+        if (d <= delta) {
+          delta = d;
+          u_out = u;
+          result = 2;
+        }
+      }
+
+      if (result == 1) {
+        u_in = first;
+        v_in = second;
+      } else {
+        u_in = second;
+        v_in = first;
+      }
+      return result != 0;
+    }
+
+    // Change _flow and _state vectors
+    void changeFlow(bool change) {
+      // Augment along the cycle
+      if (delta > 0) {
+        Value val = _state[in_arc] * delta;
+        _flow[in_arc] += val;
+        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
+          _flow[_pred[u]] -= _pred_dir[u] * val;
+        }
+        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
+          _flow[_pred[u]] += _pred_dir[u] * val;
+        }
+      }
+      // Update the state of the entering and leaving arcs
+      if (change) {
+        _state[in_arc] = STATE_TREE;
+        _state[_pred[u_out]] =
+          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
+      } else {
+        _state[in_arc] = -_state[in_arc];
+      }
+    }
+
+    // Update the tree structure
+    void updateTreeStructure() {
+      int old_rev_thread = _rev_thread[u_out];
+      int old_succ_num = _succ_num[u_out];
+      int old_last_succ = _last_succ[u_out];
+      v_out = _parent[u_out];
+
+      // Check if u_in and u_out coincide
+      if (u_in == u_out) {
+        // Update _parent, _pred, _pred_dir
+        _parent[u_in] = v_in;
+        _pred[u_in] = in_arc;
+        _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
+
+        // Update _thread and _rev_thread
+        if (_thread[v_in] != u_out) {
+          int after = _thread[old_last_succ];
+          _thread[old_rev_thread] = after;
+          _rev_thread[after] = old_rev_thread;
+          after = _thread[v_in];
+          _thread[v_in] = u_out;
+          _rev_thread[u_out] = v_in;
+          _thread[old_last_succ] = after;
+          _rev_thread[after] = old_last_succ;
+        }
+      } else {
+        // Handle the case when old_rev_thread equals to v_in
+        // (it also means that join and v_out coincide)
+        int thread_continue = old_rev_thread == v_in ?
+          _thread[old_last_succ] : _thread[v_in];
+
+        // Update _thread and _parent along the stem nodes (i.e. the nodes
+        // between u_in and u_out, whose parent have to be changed)
+        int stem = u_in;              // the current stem node
+        int par_stem = v_in;          // the new parent of stem
+        int next_stem;                // the next stem node
+        int last = _last_succ[u_in];  // the last successor of stem
+        int before, after = _thread[last];
+        _thread[v_in] = u_in;
+        _dirty_revs.clear();
+        _dirty_revs.push_back(v_in);
+        while (stem != u_out) {
+          // Insert the next stem node into the thread list
+          next_stem = _parent[stem];
+          _thread[last] = next_stem;
+          _dirty_revs.push_back(last);
+
+          // Remove the subtree of stem from the thread list
+          before = _rev_thread[stem];
+          _thread[before] = after;
+          _rev_thread[after] = before;
+
+          // Change the parent node and shift stem nodes
+          _parent[stem] = par_stem;
+          par_stem = stem;
+          stem = next_stem;
+
+          // Update last and after
+          last = _last_succ[stem] == _last_succ[par_stem] ?
+            _rev_thread[par_stem] : _last_succ[stem];
+          after = _thread[last];
+        }
+        _parent[u_out] = par_stem;
+        _thread[last] = thread_continue;
+        _rev_thread[thread_continue] = last;
+        _last_succ[u_out] = last;
+
+        // Remove the subtree of u_out from the thread list except for
+        // the case when old_rev_thread equals to v_in
+        if (old_rev_thread != v_in) {
+          _thread[old_rev_thread] = after;
+          _rev_thread[after] = old_rev_thread;
+        }
+
+        // Update _rev_thread using the new _thread values
+        for (int i = 0; i != int(_dirty_revs.size()); ++i) {
+          int u = _dirty_revs[i];
+          _rev_thread[_thread[u]] = u;
+        }
+
+        // Update _pred, _pred_dir, _last_succ and _succ_num for the
+        // stem nodes from u_out to u_in
+        int tmp_sc = 0, tmp_ls = _last_succ[u_out];
+        for (int u = u_out, p = _parent[u]; u != u_in; u = p, p = _parent[u]) {
+          _pred[u] = _pred[p];
+          _pred_dir[u] = -_pred_dir[p];
+          tmp_sc += _succ_num[u] - _succ_num[p];
+          _succ_num[u] = tmp_sc;
+          _last_succ[p] = tmp_ls;
+        }
+        _pred[u_in] = in_arc;
+        _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
+        _succ_num[u_in] = old_succ_num;
+      }
+
+      // Update _last_succ from v_in towards the root
+      int up_limit_out = _last_succ[join] == v_in ? join : -1;
+      int last_succ_out = _last_succ[u_out];
+      for (int u = v_in; u != -1 && _last_succ[u] == v_in; u = _parent[u]) {
+        _last_succ[u] = last_succ_out;
+      }
+
+      // Update _last_succ from v_out towards the root
+      if (join != old_rev_thread && v_in != old_rev_thread) {
+        for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
+             u = _parent[u]) {
+          _last_succ[u] = old_rev_thread;
+        }
+      }
+      else if (last_succ_out != old_last_succ) {
+        for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
+             u = _parent[u]) {
+          _last_succ[u] = last_succ_out;
+        }
+      }
+
+      // Update _succ_num from v_in to join
+      for (int u = v_in; u != join; u = _parent[u]) {
+        _succ_num[u] += old_succ_num;
+      }
+      // Update _succ_num from v_out to join
+      for (int u = v_out; u != join; u = _parent[u]) {
+        _succ_num[u] -= old_succ_num;
+      }
+    }
+
+    // Update potentials in the subtree that has been moved
+    void updatePotential() {
+      Cost sigma = _pi[v_in] - _pi[u_in] -
+                   _pred_dir[u_in] * _cost[in_arc];
+      int end = _thread[_last_succ[u_in]];
+      for (int u = u_in; u != end; u = _thread[u]) {
+        _pi[u] += sigma;
+      }
+    }
+
+    // Heuristic initial pivots
+    bool initialPivots() {
+      Value curr, total = 0;
+      std::vector<Node> supply_nodes, demand_nodes;
+      for (NodeIt u(_graph); u != INVALID; ++u) {
+        curr = _supply[_node_id[u]];
+        if (curr > 0) {
+          total += curr;
+          supply_nodes.push_back(u);
+        }
+        else if (curr < 0) {
+          demand_nodes.push_back(u);
+        }
+      }
+      if (_sum_supply > 0) total -= _sum_supply;
+      if (total <= 0) return true;
+
+      IntVector arc_vector;
+      if (_sum_supply >= 0) {
+        if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {
+          // Perform a reverse graph search from the sink to the source
+          typename GR::template NodeMap<bool> reached(_graph, false);
+          Node s = supply_nodes[0], t = demand_nodes[0];
+          std::vector<Node> stack;
+          reached[t] = true;
+          stack.push_back(t);
+          while (!stack.empty()) {
+            Node u, v = stack.back();
+            stack.pop_back();
+            if (v == s) break;
+            for (InArcIt a(_graph, v); a != INVALID; ++a) {
+              if (reached[u = _graph.source(a)]) continue;
+              int j = _arc_id[a];
+              if (_cap[j] >= total) {
+                arc_vector.push_back(j);
+                reached[u] = true;
+                stack.push_back(u);
+              }
+            }
+          }
+        } else {
+          // Find the min. cost incoming arc for each demand node
+          for (int i = 0; i != int(demand_nodes.size()); ++i) {
+            Node v = demand_nodes[i];
+            Cost c, min_cost = std::numeric_limits<Cost>::max();
+            Arc min_arc = INVALID;
+            for (InArcIt a(_graph, v); a != INVALID; ++a) {
+              c = _cost[_arc_id[a]];
+              if (c < min_cost) {
+                min_cost = c;
+                min_arc = a;
+              }
+            }
+            if (min_arc != INVALID) {
+              arc_vector.push_back(_arc_id[min_arc]);
+            }
+          }
+        }
+      } else {
+        // Find the min. cost outgoing arc for each supply node
+        for (int i = 0; i != int(supply_nodes.size()); ++i) {
+          Node u = supply_nodes[i];
+          Cost c, min_cost = std::numeric_limits<Cost>::max();
+          Arc min_arc = INVALID;
+          for (OutArcIt a(_graph, u); a != INVALID; ++a) {
+            c = _cost[_arc_id[a]];
+            if (c < min_cost) {
+              min_cost = c;
+              min_arc = a;
+            }
+          }
+          if (min_arc != INVALID) {
+            arc_vector.push_back(_arc_id[min_arc]);
+          }
+        }
+      }
+
+      // Perform heuristic initial pivots
+      for (int i = 0; i != int(arc_vector.size()); ++i) {
+        in_arc = arc_vector[i];
+        if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -
+            _pi[_target[in_arc]]) >= 0) continue;
+        findJoinNode();
+        bool change = findLeavingArc();
+        if (delta >= MAX) return false;
+        changeFlow(change);
+        if (change) {
+          updateTreeStructure();
+          updatePotential();
+        }
+      }
+      return true;
+    }
+
+    // Execute the algorithm
+    ProblemType start(PivotRule pivot_rule) {
+      // Select the pivot rule implementation
+      switch (pivot_rule) {
+        case FIRST_ELIGIBLE:
+          return start<FirstEligiblePivotRule>();
+        case BEST_ELIGIBLE:
+          return start<BestEligiblePivotRule>();
+        case BLOCK_SEARCH:
+          return start<BlockSearchPivotRule>();
+        case CANDIDATE_LIST:
+          return start<CandidateListPivotRule>();
+        case ALTERING_LIST:
+          return start<AlteringListPivotRule>();
+      }
+      return INFEASIBLE; // avoid warning
+    }
+
+    template <typename PivotRuleImpl>
+    ProblemType start() {
+      PivotRuleImpl pivot(*this);
+
+      // Perform heuristic initial pivots
+      if (!initialPivots()) return UNBOUNDED;
+
+      // Execute the Network Simplex algorithm
+      while (pivot.findEnteringArc()) {
+        findJoinNode();
+        bool change = findLeavingArc();
+        if (delta >= MAX) return UNBOUNDED;
+        changeFlow(change);
+        if (change) {
+          updateTreeStructure();
+          updatePotential();
+        }
+      }
+
+      // Check feasibility
+      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
+        if (_flow[e] != 0) return INFEASIBLE;
+      }
+
+      // Transform the solution and the supply map to the original form
+      if (_has_lower) {
+        for (int i = 0; i != _arc_num; ++i) {
+          Value c = _lower[i];
+          if (c != 0) {
+            _flow[i] += c;
+            _supply[_source[i]] += c;
+            _supply[_target[i]] -= c;
+          }
+        }
+      }
+
+      // Shift potentials to meet the requirements of the GEQ/LEQ type
+      // optimality conditions
+      if (_sum_supply == 0) {
+        if (_stype == GEQ) {
+          Cost max_pot = -std::numeric_limits<Cost>::max();
+          for (int i = 0; i != _node_num; ++i) {
+            if (_pi[i] > max_pot) max_pot = _pi[i];
+          }
+          if (max_pot > 0) {
+            for (int i = 0; i != _node_num; ++i)
+              _pi[i] -= max_pot;
+          }
+        } else {
+          Cost min_pot = std::numeric_limits<Cost>::max();
+          for (int i = 0; i != _node_num; ++i) {
+            if (_pi[i] < min_pot) min_pot = _pi[i];
+          }
+          if (min_pot < 0) {
+            for (int i = 0; i != _node_num; ++i)
+              _pi[i] -= min_pot;
+          }
+        }
+      }
+
+      return OPTIMAL;
+    }
+
+  }; //class NetworkSimplex
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_NETWORK_SIMPLEX_H
diff --git a/lemon/opt2_tsp.h b/lemon/opt2_tsp.h
new file mode 100644
index 0000000..686cc9c
--- /dev/null
+++ b/lemon/opt2_tsp.h
@@ -0,0 +1,367 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_OPT2_TSP_H
+#define LEMON_OPT2_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief 2-opt algorithm for symmetric TSP.
+
+#include <vector>
+#include <lemon/full_graph.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief 2-opt algorithm for symmetric TSP.
+  ///
+  /// Opt2Tsp implements the 2-opt heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This algorithm starts with an initial tour and iteratively improves it.
+  /// At each step, it removes two edges and the reconnects the created two
+  /// paths in the other way if the resulting tour is shorter.
+  /// The algorithm finishes when no such 2-opt move can be applied, and so
+  /// the tour is 2-optimal.
+  ///
+  /// If no starting tour is given to the \ref run() function, then the
+  /// algorithm uses the node sequence determined by the node IDs.
+  /// Oherwise, it starts with the given tour.
+  ///
+  /// This is a rather slow but effective method.
+  /// Its typical usage is the improvement of the result of a fast tour
+  /// construction heuristic (e.g. the InsertionTsp algorithm).
+  ///
+  /// \tparam CM Type of the cost map.
+  template <typename CM>
+  class Opt2Tsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      Cost _sum;
+      std::vector<int> _plist;
+      std::vector<Node> _path;
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      Opt2Tsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm from scratch.
+      ///
+      /// This function runs the algorithm starting from the tour that is
+      /// determined by the node ID sequence.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run() {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 2) {
+          _path.push_back(_gr(0));
+          _path.push_back(_gr(1));
+          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
+        }
+
+        _plist.resize(2*_gr.nodeNum());
+        for (int i = 1; i < _gr.nodeNum()-1; ++i) {
+          _plist[2*i] = i-1;
+          _plist[2*i+1] = i+1;
+        }
+        _plist[0] = _gr.nodeNum()-1;
+        _plist[1] = 1;
+        _plist[2*_gr.nodeNum()-2] = _gr.nodeNum()-2;
+        _plist[2*_gr.nodeNum()-1] = 0;
+
+        return start();
+      }
+
+      /// \brief Runs the algorithm starting from the given tour.
+      ///
+      /// This function runs the algorithm starting from the given tour.
+      ///
+      /// \param tour The tour as a path structure. It must be a
+      /// \ref checkPath() "valid path" containing excactly n arcs.
+      ///
+      /// \return The total cost of the found tour.
+      template <typename Path>
+      Cost run(const Path& tour) {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 2) {
+          _path.push_back(_gr(0));
+          _path.push_back(_gr(1));
+          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
+        }
+
+        _plist.resize(2*_gr.nodeNum());
+        typename Path::ArcIt it(tour);
+        int first = _gr.id(_gr.source(it)),
+            prev = first,
+            curr = _gr.id(_gr.target(it)),
+            next = -1;
+        _plist[2*first+1] = curr;
+        for (++it; it != INVALID; ++it) {
+          next = _gr.id(_gr.target(it));
+          _plist[2*curr] = prev;
+          _plist[2*curr+1] = next;
+          prev = curr;
+          curr = next;
+        }
+        _plist[2*first] = prev;
+
+        return start();
+      }
+
+      /// \brief Runs the algorithm starting from the given tour.
+      ///
+      /// This function runs the algorithm starting from the given tour
+      /// (node sequence).
+      ///
+      /// \param tour A vector that stores all <tt>Node</tt>s of the graph
+      /// in the desired order.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run(const std::vector<Node>& tour) {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 2) {
+          _path.push_back(_gr(0));
+          _path.push_back(_gr(1));
+          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
+        }
+
+        _plist.resize(2*_gr.nodeNum());
+        typename std::vector<Node>::const_iterator it = tour.begin();
+        int first = _gr.id(*it),
+            prev = first,
+            curr = _gr.id(*(++it)),
+            next = -1;
+        _plist[2*first+1] = curr;
+        for (++it; it != tour.end(); ++it) {
+          next = _gr.id(*it);
+          _plist[2*curr] = prev;
+          _plist[2*curr+1] = next;
+          prev = curr;
+          curr = next;
+        }
+        _plist[2*first] = curr;
+        _plist[2*curr] = prev;
+        _plist[2*curr+1] = first;
+
+        return start();
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _path;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_path.begin(), _path.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_path.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_path[i], _path[i+1]));
+        }
+        if (int(_path.size()) >= 2) {
+          path.addBack(_gr.arc(_path.back(), _path.front()));
+        }
+      }
+
+      /// @}
+
+    private:
+
+      // Iterator class for the linked list storage of the tour
+      class PathListIt {
+        public:
+          PathListIt(const std::vector<int> &pl, int i=0)
+            : plist(&pl), act(i), last(pl[2*act]) {}
+          PathListIt(const std::vector<int> &pl, int i, int l)
+            : plist(&pl), act(i), last(l) {}
+
+          int nextIndex() const {
+            return (*plist)[2*act] == last ? 2*act+1 : 2*act;
+          }
+
+          int prevIndex() const {
+            return (*plist)[2*act] == last ? 2*act : 2*act+1;
+          }
+
+          int next() const {
+            int x = (*plist)[2*act];
+            return x == last ? (*plist)[2*act+1] : x;
+          }
+
+          int prev() const {
+            return last;
+          }
+
+          PathListIt& operator++() {
+            int tmp = act;
+            act = next();
+            last = tmp;
+            return *this;
+          }
+
+          operator int() const {
+            return act;
+          }
+
+        private:
+          const std::vector<int> *plist;
+          int act;
+          int last;
+      };
+
+      // Checks and applies 2-opt move (if it improves the tour)
+      bool checkOpt2(const PathListIt& i, const PathListIt& j) {
+        Node u  = _gr.nodeFromId(i),
+             un = _gr.nodeFromId(i.next()),
+             v  = _gr.nodeFromId(j),
+             vn = _gr.nodeFromId(j.next());
+
+        if (_cost[_gr.edge(u, un)] + _cost[_gr.edge(v, vn)] >
+            _cost[_gr.edge(u, v)] + _cost[_gr.edge(un, vn)])
+        {
+          _plist[PathListIt(_plist, i.next(), i).prevIndex()] = j.next();
+          _plist[PathListIt(_plist, j.next(), j).prevIndex()] = i.next();
+
+          _plist[i.nextIndex()] = j;
+          _plist[j.nextIndex()] = i;
+
+          return true;
+        }
+
+        return false;
+     }
+
+      // Executes the algorithm from the initial tour
+      Cost start() {
+
+      restart_search:
+        for (PathListIt i(_plist); true; ++i) {
+          PathListIt j = i;
+          if (++j == 0 || ++j == 0) break;
+          for (; j != 0 && j != i.prev(); ++j) {
+            if (checkOpt2(i, j))
+              goto restart_search;
+          }
+        }
+
+        PathListIt i(_plist);
+        _path.push_back(_gr.nodeFromId(i));
+        for (++i; i != 0; ++i)
+          _path.push_back(_gr.nodeFromId(i));
+
+        _sum = _cost[_gr.edge(_path.back(), _path.front())];
+        for (int i = 0; i < int(_path.size())-1; ++i) {
+          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
+        }
+
+        return _sum;
+      }
+
+  };
+
+}; // namespace lemon
+
+#endif
diff --git a/lemon/pairing_heap.h b/lemon/pairing_heap.h
new file mode 100644
index 0000000..da6ebcb
--- /dev/null
+++ b/lemon/pairing_heap.h
@@ -0,0 +1,474 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_PAIRING_HEAP_H
+#define LEMON_PAIRING_HEAP_H
+
+///\file
+///\ingroup heaps
+///\brief Pairing heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Pairing Heap.
+  ///
+  /// This class implements the \e pairing \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The methods \ref increase() and \ref erase() are not efficient
+  /// in a pairing heap. In case of many calls of these operations,
+  /// it is better to use other heap structure, e.g. \ref BinHeap
+  /// "binary heap".
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class PairingHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    class store;
+
+    std::vector<store> _data;
+    int _min;
+    ItemIntMap &_iim;
+    Compare _comp;
+    int _num_items;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit PairingHeap(ItemIntMap &map)
+      : _min(0), _iim(map), _num_items(0) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    PairingHeap(ItemIntMap &map, const Compare &comp)
+      : _min(0), _iim(map), _comp(comp), _num_items(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num_items; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num_items==0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear();
+      _min = 0;
+      _num_items = 0;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param item The item.
+    /// \param value The priority.
+    void set (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if ( i>=0 && _data[i].in ) {
+        if ( _comp(value, _data[i].prio) ) decrease(item, value);
+        if ( _comp(_data[i].prio, value) ) increase(item, value);
+      } else push(item, value);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param item The item to insert.
+    /// \param value The priority of the item.
+    /// \pre \e item must not be stored in the heap.
+    void push (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if( i<0 ) {
+        int s=_data.size();
+        _iim.set(item, s);
+        store st;
+        st.name=item;
+        _data.push_back(st);
+        i=s;
+      } else {
+        _data[i].parent=_data[i].child=-1;
+        _data[i].left_child=false;
+        _data[i].degree=0;
+        _data[i].in=true;
+      }
+
+      _data[i].prio=value;
+
+      if ( _num_items!=0 ) {
+        if ( _comp( value, _data[_min].prio) ) {
+          fuse(i,_min);
+          _min=i;
+        }
+        else fuse(_min,i);
+      }
+      else _min=i;
+
+      ++_num_items;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[_min].name; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    const Prio& prio() const { return _data[_min].prio; }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param item The item.
+    /// \pre \e item must be in the heap.
+    const Prio& operator[](const Item& item) const {
+      return _data[_iim[item]].prio;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      std::vector<int> trees;
+      int i=0, child_right = 0;
+      _data[_min].in=false;
+
+      if( -1!=_data[_min].child ) {
+        i=_data[_min].child;
+        trees.push_back(i);
+        _data[i].parent = -1;
+        _data[_min].child = -1;
+
+        int ch=-1;
+        while( _data[i].child!=-1 ) {
+          ch=_data[i].child;
+          if( _data[ch].left_child && i==_data[ch].parent ) {
+            break;
+          } else {
+            if( _data[ch].left_child ) {
+              child_right=_data[ch].parent;
+              _data[ch].parent = i;
+              --_data[i].degree;
+            }
+            else {
+              child_right=ch;
+              _data[i].child=-1;
+              _data[i].degree=0;
+            }
+            _data[child_right].parent = -1;
+            trees.push_back(child_right);
+            i = child_right;
+          }
+        }
+
+        int num_child = trees.size();
+        int other;
+        for( i=0; i<num_child-1; i+=2 ) {
+          if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
+            other=trees[i];
+            trees[i]=trees[i+1];
+            trees[i+1]=other;
+          }
+          fuse( trees[i], trees[i+1] );
+        }
+
+        i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
+        while(i>=2) {
+          if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
+            other=trees[i];
+            trees[i]=trees[i-2];
+            trees[i-2]=other;
+          }
+          fuse( trees[i-2], trees[i] );
+          i-=2;
+        }
+        _min = trees[0];
+      }
+      else {
+        _min = _data[_min].child;
+      }
+
+      if (_min >= 0) _data[_min].left_child = false;
+      --_num_items;
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param item The item to delete.
+    /// \pre \e item must be in the heap.
+    void erase (const Item& item) {
+      int i=_iim[item];
+      if ( i>=0 && _data[i].in ) {
+        decrease( item, _data[_min].prio-1 );
+        pop();
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at least \e value.
+    void decrease (Item item, const Prio& value) {
+      int i=_iim[item];
+      _data[i].prio=value;
+      int p=_data[i].parent;
+
+      if( _data[i].left_child && i!=_data[p].child ) {
+        p=_data[p].parent;
+      }
+
+      if ( p!=-1 && _comp(value,_data[p].prio) ) {
+        cut(i,p);
+        if ( _comp(_data[_min].prio,value) ) {
+          fuse(_min,i);
+        } else {
+          fuse(i,_min);
+          _min=i;
+        }
+      }
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at most \e value.
+    void increase (Item item, const Prio& value) {
+      erase(item);
+      push(item,value);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param item The item.
+    State state(const Item &item) const {
+      int i=_iim[item];
+      if( i>=0 ) {
+        if( _data[i].in ) i=0;
+        else i=-2;
+      }
+      return State(i);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) erase(i);
+        _iim[i]=st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    void cut(int a, int b) {
+      int child_a;
+      switch (_data[a].degree) {
+        case 2:
+          child_a = _data[_data[a].child].parent;
+          if( _data[a].left_child ) {
+            _data[child_a].left_child=true;
+            _data[b].child=child_a;
+            _data[child_a].parent=_data[a].parent;
+          }
+          else {
+            _data[child_a].left_child=false;
+            _data[child_a].parent=b;
+            if( a!=_data[b].child )
+              _data[_data[b].child].parent=child_a;
+            else
+              _data[b].child=child_a;
+          }
+          --_data[a].degree;
+          _data[_data[a].child].parent=a;
+          break;
+
+        case 1:
+          child_a = _data[a].child;
+          if( !_data[child_a].left_child ) {
+            --_data[a].degree;
+            if( _data[a].left_child ) {
+              _data[child_a].left_child=true;
+              _data[child_a].parent=_data[a].parent;
+              _data[b].child=child_a;
+            }
+            else {
+              _data[child_a].left_child=false;
+              _data[child_a].parent=b;
+              if( a!=_data[b].child )
+                _data[_data[b].child].parent=child_a;
+              else
+                _data[b].child=child_a;
+            }
+            _data[a].child=-1;
+          }
+          else {
+            --_data[b].degree;
+            if( _data[a].left_child ) {
+              _data[b].child =
+                (1==_data[b].degree) ? _data[a].parent : -1;
+            } else {
+              if (1==_data[b].degree)
+                _data[_data[b].child].parent=b;
+              else
+                _data[b].child=-1;
+            }
+          }
+          break;
+
+        case 0:
+          --_data[b].degree;
+          if( _data[a].left_child ) {
+            _data[b].child =
+              (0!=_data[b].degree) ? _data[a].parent : -1;
+          } else {
+            if( 0!=_data[b].degree )
+              _data[_data[b].child].parent=b;
+            else
+              _data[b].child=-1;
+          }
+          break;
+      }
+      _data[a].parent=-1;
+      _data[a].left_child=false;
+    }
+
+    void fuse(int a, int b) {
+      int child_a = _data[a].child;
+      int child_b = _data[b].child;
+      _data[a].child=b;
+      _data[b].parent=a;
+      _data[b].left_child=true;
+
+      if( -1!=child_a ) {
+        _data[b].child=child_a;
+        _data[child_a].parent=b;
+        _data[child_a].left_child=false;
+        ++_data[b].degree;
+
+        if( -1!=child_b ) {
+           _data[b].child=child_b;
+           _data[child_b].parent=child_a;
+        }
+      }
+      else { ++_data[a].degree; }
+    }
+
+    class store {
+      friend class PairingHeap;
+
+      Item name;
+      int parent;
+      int child;
+      bool left_child;
+      int degree;
+      bool in;
+      Prio prio;
+
+      store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_PAIRING_HEAP_H
+
diff --git a/lemon/path.h b/lemon/path.h
new file mode 100644
index 0000000..baa92c4
--- /dev/null
+++ b/lemon/path.h
@@ -0,0 +1,1164 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup paths
+///\file
+///\brief Classes for representing paths in digraphs.
+///
+
+#ifndef LEMON_PATH_H
+#define LEMON_PATH_H
+
+#include <vector>
+#include <algorithm>
+
+#include <lemon/error.h>
+#include <lemon/core.h>
+#include <lemon/concepts/path.h>
+
+namespace lemon {
+
+  /// \addtogroup paths
+  /// @{
+
+
+  /// \brief A structure for representing directed paths in a digraph.
+  ///
+  /// A structure for representing directed path in a digraph.
+  /// \tparam GR The digraph type in which the path is.
+  ///
+  /// In a sense, the path can be treated as a list of arcs. The
+  /// LEMON path type stores just this list. As a consequence, it
+  /// cannot enumerate the nodes of the path and the source node of
+  /// a zero length path is undefined.
+  ///
+  /// This implementation is a back and front insertable and erasable
+  /// path type. It can be indexed in O(1) time. The front and back
+  /// insertion and erase is done in O(1) (amortized) time. The
+  /// implementation uses two vectors for storing the front and back
+  /// insertions.
+  template <typename GR>
+  class Path {
+  public:
+
+    typedef GR Digraph;
+    typedef typename Digraph::Arc Arc;
+
+    /// \brief Default constructor
+    ///
+    /// Default constructor
+    Path() {}
+
+    /// \brief Copy constructor
+    ///
+    Path(const Path& cpath) {
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Template copy constructor
+    ///
+    /// This constuctor initializes the path from any other path type.
+    /// It simply makes a copy of the given path.
+    template <typename CPath>
+    Path(const CPath& cpath) {
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Copy assignment
+    ///
+    Path& operator=(const Path& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
+    /// \brief Template copy assignment
+    ///
+    /// This operator makes a copy of a path of any other type.
+    template <typename CPath>
+    Path& operator=(const CPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
+    /// \brief LEMON style iterator for path arcs
+    ///
+    /// This class is used to iterate on the arcs of the paths.
+    class ArcIt {
+      friend class Path;
+    public:
+      /// \brief Default constructor
+      ArcIt() {}
+      /// \brief Invalid constructor
+      ArcIt(Invalid) : path(0), idx(-1) {}
+      /// \brief Initializate the iterator to the first arc of path
+      ArcIt(const Path &_path)
+        : path(&_path), idx(_path.empty() ? -1 : 0) {}
+
+    private:
+
+      ArcIt(const Path &_path, int _idx)
+        : path(&_path), idx(_idx) {}
+
+    public:
+
+      /// \brief Conversion to Arc
+      operator const Arc&() const {
+        return path->nth(idx);
+      }
+
+      /// \brief Next arc
+      ArcIt& operator++() {
+        ++idx;
+        if (idx >= path->length()) idx = -1;
+        return *this;
+      }
+
+      /// \brief Comparison operator
+      bool operator==(const ArcIt& e) const { return idx==e.idx; }
+      /// \brief Comparison operator
+      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
+      /// \brief Comparison operator
+      bool operator<(const ArcIt& e) const { return idx<e.idx; }
+
+    private:
+      const Path *path;
+      int idx;
+    };
+
+    /// \brief Length of the path.
+    int length() const { return head.size() + tail.size(); }
+    /// \brief Return whether the path is empty.
+    bool empty() const { return head.empty() && tail.empty(); }
+
+    /// \brief Reset the path to an empty one.
+    void clear() { head.clear(); tail.clear(); }
+
+    /// \brief The n-th arc.
+    ///
+    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    const Arc& nth(int n) const {
+      return n < int(head.size()) ? *(head.rbegin() + n) :
+        *(tail.begin() + (n - head.size()));
+    }
+
+    /// \brief Initialize arc iterator to point to the n-th arc
+    ///
+    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    ArcIt nthIt(int n) const {
+      return ArcIt(*this, n);
+    }
+
+    /// \brief The first arc of the path
+    const Arc& front() const {
+      return head.empty() ? tail.front() : head.back();
+    }
+
+    /// \brief Add a new arc before the current path
+    void addFront(const Arc& arc) {
+      head.push_back(arc);
+    }
+
+    /// \brief Erase the first arc of the path
+    void eraseFront() {
+      if (!head.empty()) {
+        head.pop_back();
+      } else {
+        head.clear();
+        int halfsize = tail.size() / 2;
+        head.resize(halfsize);
+        std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
+                  head.rbegin());
+        std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
+        tail.resize(tail.size() - halfsize - 1);
+      }
+    }
+
+    /// \brief The last arc of the path
+    const Arc& back() const {
+      return tail.empty() ? head.front() : tail.back();
+    }
+
+    /// \brief Add a new arc behind the current path
+    void addBack(const Arc& arc) {
+      tail.push_back(arc);
+    }
+
+    /// \brief Erase the last arc of the path
+    void eraseBack() {
+      if (!tail.empty()) {
+        tail.pop_back();
+      } else {
+        int halfsize = head.size() / 2;
+        tail.resize(halfsize);
+        std::copy(head.begin() + 1, head.begin() + halfsize + 1,
+                  tail.rbegin());
+        std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
+        head.resize(head.size() - halfsize - 1);
+      }
+    }
+
+    typedef True BuildTag;
+
+    template <typename CPath>
+    void build(const CPath& path) {
+      int len = path.length();
+      tail.reserve(len);
+      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
+        tail.push_back(it);
+      }
+    }
+
+    template <typename CPath>
+    void buildRev(const CPath& path) {
+      int len = path.length();
+      head.reserve(len);
+      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
+        head.push_back(it);
+      }
+    }
+
+  protected:
+    typedef std::vector<Arc> Container;
+    Container head, tail;
+
+  };
+
+  /// \brief A structure for representing directed paths in a digraph.
+  ///
+  /// A structure for representing directed path in a digraph.
+  /// \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.
+  ///
+  /// This implementation is a just back insertable and erasable path
+  /// type. It can be indexed in O(1) time. The back insertion and
+  /// erasure is amortized O(1) time. This implementation is faster
+  /// then the \c Path type because it use just one vector for the
+  /// arcs.
+  template <typename GR>
+  class SimplePath {
+  public:
+
+    typedef GR Digraph;
+    typedef typename Digraph::Arc Arc;
+
+    /// \brief Default constructor
+    ///
+    /// Default constructor
+    SimplePath() {}
+
+    /// \brief Copy constructor
+    ///
+    SimplePath(const SimplePath& cpath) {
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Template copy constructor
+    ///
+    /// This path can be initialized with any other path type. It just
+    /// makes a copy of the given path.
+    template <typename CPath>
+    SimplePath(const CPath& cpath) {
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Copy assignment
+    ///
+    SimplePath& operator=(const SimplePath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
+    /// \brief Template copy assignment
+    ///
+    /// This path can be initialized with any other path type. It just
+    /// makes a copy of the given path.
+    template <typename CPath>
+    SimplePath& operator=(const CPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
+    /// \brief Iterator class to iterate on the arcs of the paths
+    ///
+    /// This class is used to iterate on the arcs of the paths
+    ///
+    /// Of course it converts to Digraph::Arc
+    class ArcIt {
+      friend class SimplePath;
+    public:
+      /// Default constructor
+      ArcIt() {}
+      /// Invalid constructor
+      ArcIt(Invalid) : path(0), idx(-1) {}
+      /// \brief Initializate the constructor to the first arc of path
+      ArcIt(const SimplePath &_path)
+        : path(&_path), idx(_path.empty() ? -1 : 0) {}
+
+    private:
+
+      /// Constructor with starting point
+      ArcIt(const SimplePath &_path, int _idx)
+        : path(&_path), idx(_idx) {}
+
+    public:
+
+      ///Conversion to Digraph::Arc
+      operator const Arc&() const {
+        return path->nth(idx);
+      }
+
+      /// Next arc
+      ArcIt& operator++() {
+        ++idx;
+        if (idx >= path->length()) idx = -1;
+        return *this;
+      }
+
+      /// Comparison operator
+      bool operator==(const ArcIt& e) const { return idx==e.idx; }
+      /// Comparison operator
+      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
+      /// Comparison operator
+      bool operator<(const ArcIt& e) const { return idx<e.idx; }
+
+    private:
+      const SimplePath *path;
+      int idx;
+    };
+
+    /// \brief Length of the path.
+    int length() const { return data.size(); }
+    /// \brief Return true if the path is empty.
+    bool empty() const { return data.empty(); }
+
+    /// \brief Reset the path to an empty one.
+    void clear() { data.clear(); }
+
+    /// \brief The n-th arc.
+    ///
+    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    const Arc& nth(int n) const {
+      return data[n];
+    }
+
+    /// \brief  Initializes arc iterator to point to the n-th arc.
+    ArcIt nthIt(int n) const {
+      return ArcIt(*this, n);
+    }
+
+    /// \brief The first arc of the path.
+    const Arc& front() const {
+      return data.front();
+    }
+
+    /// \brief The last arc of the path.
+    const Arc& back() const {
+      return data.back();
+    }
+
+    /// \brief Add a new arc behind the current path.
+    void addBack(const Arc& arc) {
+      data.push_back(arc);
+    }
+
+    /// \brief Erase the last arc of the path
+    void eraseBack() {
+      data.pop_back();
+    }
+
+    typedef True BuildTag;
+
+    template <typename CPath>
+    void build(const CPath& path) {
+      int len = path.length();
+      data.resize(len);
+      int index = 0;
+      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
+        data[index] = it;;
+        ++index;
+      }
+    }
+
+    template <typename CPath>
+    void buildRev(const CPath& path) {
+      int len = path.length();
+      data.resize(len);
+      int index = len;
+      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
+        --index;
+        data[index] = it;;
+      }
+    }
+
+  protected:
+    typedef std::vector<Arc> Container;
+    Container data;
+
+  };
+
+  /// \brief A structure for representing directed paths in a digraph.
+  ///
+  /// A structure for representing directed path in a digraph.
+  /// \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.
+  ///
+  /// This implementation is a back and front insertable and erasable
+  /// path type. It can be indexed in O(k) time, where k is the rank
+  /// of the arc in the path. The length can be computed in O(n)
+  /// time. The front and back insertion and erasure is O(1) time
+  /// and it can be splited and spliced in O(1) time.
+  template <typename GR>
+  class ListPath {
+  public:
+
+    typedef GR Digraph;
+    typedef typename Digraph::Arc Arc;
+
+  protected:
+
+    // the std::list<> is incompatible
+    // hard to create invalid iterator
+    struct Node {
+      Arc arc;
+      Node *next, *prev;
+    };
+
+    Node *first, *last;
+
+    std::allocator<Node> alloc;
+
+  public:
+
+    /// \brief Default constructor
+    ///
+    /// Default constructor
+    ListPath() : first(0), last(0) {}
+
+    /// \brief Copy constructor
+    ///
+    ListPath(const ListPath& cpath) : first(0), last(0) {
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Template copy constructor
+    ///
+    /// This path can be initialized with any other path type. It just
+    /// makes a copy of the given path.
+    template <typename CPath>
+    ListPath(const CPath& cpath) : first(0), last(0) {
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Destructor of the path
+    ///
+    /// Destructor of the path
+    ~ListPath() {
+      clear();
+    }
+
+    /// \brief Copy assignment
+    ///
+    ListPath& operator=(const ListPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
+    /// \brief Template copy assignment
+    ///
+    /// This path can be initialized with any other path type. It just
+    /// makes a copy of the given path.
+    template <typename CPath>
+    ListPath& operator=(const CPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
+    /// \brief Iterator class to iterate on the arcs of the paths
+    ///
+    /// This class is used to iterate on the arcs of the paths
+    ///
+    /// Of course it converts to Digraph::Arc
+    class ArcIt {
+      friend class ListPath;
+    public:
+      /// Default constructor
+      ArcIt() {}
+      /// Invalid constructor
+      ArcIt(Invalid) : path(0), node(0) {}
+      /// \brief Initializate the constructor to the first arc of path
+      ArcIt(const ListPath &_path)
+        : path(&_path), node(_path.first) {}
+
+    protected:
+
+      ArcIt(const ListPath &_path, Node *_node)
+        : path(&_path), node(_node) {}
+
+
+    public:
+
+      ///Conversion to Digraph::Arc
+      operator const Arc&() const {
+        return node->arc;
+      }
+
+      /// Next arc
+      ArcIt& operator++() {
+        node = node->next;
+        return *this;
+      }
+
+      /// Comparison operator
+      bool operator==(const ArcIt& e) const { return node==e.node; }
+      /// Comparison operator
+      bool operator!=(const ArcIt& e) const { return node!=e.node; }
+      /// Comparison operator
+      bool operator<(const ArcIt& e) const { return node<e.node; }
+
+    private:
+      const ListPath *path;
+      Node *node;
+    };
+
+    /// \brief The n-th arc.
+    ///
+    /// This function looks for the n-th arc in O(n) time.
+    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    const Arc& nth(int n) const {
+      Node *node = first;
+      for (int i = 0; i < n; ++i) {
+        node = node->next;
+      }
+      return node->arc;
+    }
+
+    /// \brief Initializes arc iterator to point to the n-th arc.
+    ArcIt nthIt(int n) const {
+      Node *node = first;
+      for (int i = 0; i < n; ++i) {
+        node = node->next;
+      }
+      return ArcIt(*this, node);
+    }
+
+    /// \brief Length of the path.
+    int length() const {
+      int len = 0;
+      Node *node = first;
+      while (node != 0) {
+        node = node->next;
+        ++len;
+      }
+      return len;
+    }
+
+    /// \brief Return true if the path is empty.
+    bool empty() const { return first == 0; }
+
+    /// \brief Reset the path to an empty one.
+    void clear() {
+      while (first != 0) {
+        last = first->next;
+        alloc.destroy(first);
+        alloc.deallocate(first, 1);
+        first = last;
+      }
+    }
+
+    /// \brief The first arc of the path
+    const Arc& front() const {
+      return first->arc;
+    }
+
+    /// \brief Add a new arc before the current path
+    void addFront(const Arc& arc) {
+      Node *node = alloc.allocate(1);
+      alloc.construct(node, Node());
+      node->prev = 0;
+      node->next = first;
+      node->arc = arc;
+      if (first) {
+        first->prev = node;
+        first = node;
+      } else {
+        first = last = node;
+      }
+    }
+
+    /// \brief Erase the first arc of the path
+    void eraseFront() {
+      Node *node = first;
+      first = first->next;
+      if (first) {
+        first->prev = 0;
+      } else {
+        last = 0;
+      }
+      alloc.destroy(node);
+      alloc.deallocate(node, 1);
+    }
+
+    /// \brief The last arc of the path.
+    const Arc& back() const {
+      return last->arc;
+    }
+
+    /// \brief Add a new arc behind the current path.
+    void addBack(const Arc& arc) {
+      Node *node = alloc.allocate(1);
+      alloc.construct(node, Node());
+      node->next = 0;
+      node->prev = last;
+      node->arc = arc;
+      if (last) {
+        last->next = node;
+        last = node;
+      } else {
+        last = first = node;
+      }
+    }
+
+    /// \brief Erase the last arc of the path
+    void eraseBack() {
+      Node *node = last;
+      last = last->prev;
+      if (last) {
+        last->next = 0;
+      } else {
+        first = 0;
+      }
+      alloc.destroy(node);
+      alloc.deallocate(node, 1);
+    }
+
+    /// \brief Splice a path to the back of the current path.
+    ///
+    /// It splices \c tpath to the back of the current path and \c
+    /// tpath becomes empty. The time complexity of this function is
+    /// O(1).
+    void spliceBack(ListPath& tpath) {
+      if (first) {
+        if (tpath.first) {
+          last->next = tpath.first;
+          tpath.first->prev = last;
+          last = tpath.last;
+        }
+      } else {
+        first = tpath.first;
+        last = tpath.last;
+      }
+      tpath.first = tpath.last = 0;
+    }
+
+    /// \brief Splice a path to the front of the current path.
+    ///
+    /// It splices \c tpath before the current path and \c tpath
+    /// becomes empty. The time complexity of this function
+    /// is O(1).
+    void spliceFront(ListPath& tpath) {
+      if (first) {
+        if (tpath.first) {
+          first->prev = tpath.last;
+          tpath.last->next = first;
+          first = tpath.first;
+        }
+      } else {
+        first = tpath.first;
+        last = tpath.last;
+      }
+      tpath.first = tpath.last = 0;
+    }
+
+    /// \brief Splice a path into the current path.
+    ///
+    /// It splices the \c tpath into the current path before the
+    /// position of \c it iterator and \c tpath becomes empty. The
+    /// time complexity of this function is O(1). If the \c it is
+    /// \c INVALID then it will splice behind the current path.
+    void splice(ArcIt it, ListPath& tpath) {
+      if (it.node) {
+        if (tpath.first) {
+          tpath.first->prev = it.node->prev;
+          if (it.node->prev) {
+            it.node->prev->next = tpath.first;
+          } else {
+            first = tpath.first;
+          }
+          it.node->prev = tpath.last;
+          tpath.last->next = it.node;
+        }
+      } else {
+        if (first) {
+          if (tpath.first) {
+            last->next = tpath.first;
+            tpath.first->prev = last;
+            last = tpath.last;
+          }
+        } else {
+          first = tpath.first;
+          last = tpath.last;
+        }
+      }
+      tpath.first = tpath.last = 0;
+    }
+
+    /// \brief Split the current path.
+    ///
+    /// It splits the current path into two parts. The part before
+    /// the iterator \c it will remain in the current path and the part
+    /// starting with
+    /// \c it will put into \c tpath. If \c tpath have arcs
+    /// before the operation they are removed first.  The time
+    /// complexity of this function is O(1) plus the the time of emtying
+    /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
+    void split(ArcIt it, ListPath& tpath) {
+      tpath.clear();
+      if (it.node) {
+        tpath.first = it.node;
+        tpath.last = last;
+        if (it.node->prev) {
+          last = it.node->prev;
+          last->next = 0;
+        } else {
+          first = last = 0;
+        }
+        it.node->prev = 0;
+      }
+    }
+
+
+    typedef True BuildTag;
+
+    template <typename CPath>
+    void build(const CPath& path) {
+      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
+        addBack(it);
+      }
+    }
+
+    template <typename CPath>
+    void buildRev(const CPath& path) {
+      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
+        addFront(it);
+      }
+    }
+
+  };
+
+  /// \brief A structure for representing directed paths in a digraph.
+  ///
+  /// A structure for representing directed path in a digraph.
+  /// \tparam GR The digraph type in which the path is.
+  ///
+  /// In a sense, the path can be treated as a list of arcs. The
+  /// LEMON path type stores just this list. As a consequence it
+  /// cannot enumerate the nodes in the path and the source node of
+  /// a zero length path is undefined.
+  ///
+  /// This implementation is completly static, i.e. it can be copy constucted
+  /// or copy assigned from another path, but otherwise it cannot be
+  /// modified.
+  ///
+  /// Being the the most memory efficient path type in LEMON,
+  /// it is intented to be
+  /// used when you want to store a large number of paths.
+  template <typename GR>
+  class StaticPath {
+  public:
+
+    typedef GR Digraph;
+    typedef typename Digraph::Arc Arc;
+
+    /// \brief Default constructor
+    ///
+    /// Default constructor
+    StaticPath() : len(0), arcs(0) {}
+
+    /// \brief Copy constructor
+    ///
+    StaticPath(const StaticPath& cpath) : arcs(0) {
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Template copy constructor
+    ///
+    /// This path can be initialized from any other path type.
+    template <typename CPath>
+    StaticPath(const CPath& cpath) : arcs(0) {
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Destructor of the path
+    ///
+    /// Destructor of the path
+    ~StaticPath() {
+      if (arcs) delete[] arcs;
+    }
+
+    /// \brief Copy assignment
+    ///
+    StaticPath& operator=(const StaticPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
+    /// \brief Template copy assignment
+    ///
+    /// This path can be made equal to any other path type. It simply
+    /// makes a copy of the given path.
+    template <typename CPath>
+    StaticPath& operator=(const CPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
+    /// \brief Iterator class to iterate on the arcs of the paths
+    ///
+    /// This class is used to iterate on the arcs of the paths
+    ///
+    /// Of course it converts to Digraph::Arc
+    class ArcIt {
+      friend class StaticPath;
+    public:
+      /// Default constructor
+      ArcIt() {}
+      /// Invalid constructor
+      ArcIt(Invalid) : path(0), idx(-1) {}
+      /// Initializate the constructor to the first arc of path
+      ArcIt(const StaticPath &_path)
+        : path(&_path), idx(_path.empty() ? -1 : 0) {}
+
+    private:
+
+      /// Constructor with starting point
+      ArcIt(const StaticPath &_path, int _idx)
+        : idx(_idx), path(&_path) {}
+
+    public:
+
+      ///Conversion to Digraph::Arc
+      operator const Arc&() const {
+        return path->nth(idx);
+      }
+
+      /// Next arc
+      ArcIt& operator++() {
+        ++idx;
+        if (idx >= path->length()) idx = -1;
+        return *this;
+      }
+
+      /// Comparison operator
+      bool operator==(const ArcIt& e) const { return idx==e.idx; }
+      /// Comparison operator
+      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
+      /// Comparison operator
+      bool operator<(const ArcIt& e) const { return idx<e.idx; }
+
+    private:
+      const StaticPath *path;
+      int idx;
+    };
+
+    /// \brief The n-th arc.
+    ///
+    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    const Arc& nth(int n) const {
+      return arcs[n];
+    }
+
+    /// \brief The arc iterator pointing to the n-th arc.
+    ArcIt nthIt(int n) const {
+      return ArcIt(*this, n);
+    }
+
+    /// \brief The length of the path.
+    int length() const { return len; }
+
+    /// \brief Return true when the path is empty.
+    int empty() const { return len == 0; }
+
+    /// \brief Erase all arcs in the digraph.
+    void clear() {
+      len = 0;
+      if (arcs) delete[] arcs;
+      arcs = 0;
+    }
+
+    /// \brief The first arc of the path.
+    const Arc& front() const {
+      return arcs[0];
+    }
+
+    /// \brief The last arc of the path.
+    const Arc& back() const {
+      return arcs[len - 1];
+    }
+
+
+    typedef True BuildTag;
+
+    template <typename CPath>
+    void build(const CPath& path) {
+      len = path.length();
+      arcs = new Arc[len];
+      int index = 0;
+      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
+        arcs[index] = it;
+        ++index;
+      }
+    }
+
+    template <typename CPath>
+    void buildRev(const CPath& path) {
+      len = path.length();
+      arcs = new Arc[len];
+      int index = len;
+      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
+        --index;
+        arcs[index] = it;
+      }
+    }
+
+  private:
+    int len;
+    Arc* arcs;
+  };
+
+  ///////////////////////////////////////////////////////////////////////
+  // Additional utilities
+  ///////////////////////////////////////////////////////////////////////
+
+  namespace _path_bits {
+
+    template <typename Path, typename Enable = void>
+    struct RevPathTagIndicator {
+      static const bool value = false;
+    };
+
+    template <typename Path>
+    struct RevPathTagIndicator<
+      Path,
+      typename enable_if<typename Path::RevPathTag, void>::type
+      > {
+      static const bool value = true;
+    };
+
+    template <typename Path, typename Enable = void>
+    struct BuildTagIndicator {
+      static const bool value = false;
+    };
+
+    template <typename Path>
+    struct BuildTagIndicator<
+      Path,
+      typename enable_if<typename Path::BuildTag, void>::type
+    > {
+      static const bool value = true;
+    };
+
+    template <typename From, typename To,
+              bool buildEnable = BuildTagIndicator<To>::value>
+    struct PathCopySelectorForward {
+      static void copy(const From& from, To& to) {
+        to.clear();
+        for (typename From::ArcIt it(from); it != INVALID; ++it) {
+          to.addBack(it);
+        }
+      }
+    };
+
+    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(const From& from, To& to) {
+        to.clear();
+        for (typename From::RevArcIt it(from); it != INVALID; ++it) {
+          to.addFront(it);
+        }
+      }
+    };
+
+    template <typename From, typename To>
+    struct PathCopySelectorBackward<From, To, true> {
+      static void copy(const From& from, To& to) {
+        to.clear();
+        to.buildRev(from);
+      }
+    };
+
+
+    template <typename From, typename To,
+              bool revEnable = RevPathTagIndicator<From>::value>
+    struct PathCopySelector {
+      static void copy(const From& from, To& to) {
+        PathCopySelectorForward<From, To>::copy(from, to);
+      }
+    };
+
+    template <typename From, typename To>
+    struct PathCopySelector<From, To, true> {
+      static void copy(const From& from, To& to) {
+        PathCopySelectorBackward<From, To>::copy(from, to);
+      }
+    };
+
+  }
+
+
+  /// \brief Make a copy of a path.
+  ///
+  /// 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);
+  }
+
+  /// \brief Check the consistency of a path.
+  ///
+  /// This function checks that the target of each arc is the same
+  /// as the source of the next one.
+  ///
+  template <typename Digraph, typename Path>
+  bool checkPath(const Digraph& digraph, const Path& path) {
+    typename Path::ArcIt it(path);
+    if (it == INVALID) return true;
+    typename Digraph::Node node = digraph.target(it);
+    ++it;
+    while (it != INVALID) {
+      if (digraph.source(it) != node) return false;
+      node = digraph.target(it);
+      ++it;
+    }
+    return true;
+  }
+
+  /// \brief The source of a 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 path.empty() ? INVALID : digraph.source(path.front());
+  }
+
+  /// \brief The target of a 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 path.empty() ? INVALID : digraph.target(path.back());
+  }
+
+  /// \brief Class which helps to iterate through the nodes of a path
+  ///
+  /// In a sense, the path can be treated as a list of arcs. The
+  /// LEMON path type stores only this list. As a consequence, it
+  /// cannot enumerate the nodes in the path and the zero length paths
+  /// cannot have a source node.
+  ///
+  /// This class implements the node iterator of a path structure. To
+  /// provide this feature, the underlying digraph should be passed to
+  /// the constructor of the iterator.
+  template <typename Path>
+  class PathNodeIt {
+  private:
+    const typename Path::Digraph *_digraph;
+    typename Path::ArcIt _it;
+    typename Path::Digraph::Node _nd;
+
+  public:
+
+    typedef typename Path::Digraph Digraph;
+    typedef typename Digraph::Node Node;
+
+    /// Default constructor
+    PathNodeIt() {}
+    /// Invalid constructor
+    PathNodeIt(Invalid)
+      : _digraph(0), _it(INVALID), _nd(INVALID) {}
+    /// Constructor
+    PathNodeIt(const Digraph& digraph, const Path& path)
+      : _digraph(&digraph), _it(path) {
+      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
+    }
+    /// Constructor
+    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
+      : _digraph(&digraph), _it(path), _nd(src) {}
+
+    ///Conversion to Digraph::Node
+    operator Node() const {
+      return _nd;
+    }
+
+    /// Next node
+    PathNodeIt& operator++() {
+      if (_it == INVALID) _nd = INVALID;
+      else {
+        _nd = _digraph->target(_it);
+        ++_it;
+      }
+      return *this;
+    }
+
+    /// Comparison operator
+    bool operator==(const PathNodeIt& n) const {
+      return _it == n._it && _nd == n._nd;
+    }
+    /// Comparison operator
+    bool operator!=(const PathNodeIt& n) const {
+      return _it != n._it || _nd != n._nd;
+    }
+    /// Comparison operator
+    bool operator<(const PathNodeIt& n) const {
+      return (_it < n._it && _nd != INVALID);
+    }
+
+  };
+
+  ///@}
+
+} // namespace lemon
+
+#endif // LEMON_PATH_H
diff --git a/lemon/planarity.h b/lemon/planarity.h
new file mode 100644
index 0000000..bfe8e85
--- /dev/null
+++ b/lemon/planarity.h
@@ -0,0 +1,2754 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_PLANARITY_H
+#define LEMON_PLANARITY_H
+
+/// \ingroup planar
+/// \file
+/// \brief Planarity checking, embedding, drawing and coloring
+
+#include <vector>
+#include <list>
+
+#include <lemon/dfs.h>
+#include <lemon/bfs.h>
+#include <lemon/radix_sort.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+#include <lemon/bucket_heap.h>
+#include <lemon/adaptors.h>
+#include <lemon/edge_set.h>
+#include <lemon/color.h>
+#include <lemon/dim2.h>
+
+namespace lemon {
+
+  namespace _planarity_bits {
+
+    template <typename Graph>
+    struct PlanarityVisitor : DfsVisitor<Graph> {
+
+      TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+      typedef typename Graph::template NodeMap<Arc> PredMap;
+
+      typedef typename Graph::template EdgeMap<bool> TreeMap;
+
+      typedef typename Graph::template NodeMap<int> OrderMap;
+      typedef std::vector<Node> OrderList;
+
+      typedef typename Graph::template NodeMap<int> LowMap;
+      typedef typename Graph::template NodeMap<int> AncestorMap;
+
+      PlanarityVisitor(const Graph& graph,
+                       PredMap& pred_map, TreeMap& tree_map,
+                       OrderMap& order_map, OrderList& order_list,
+                       AncestorMap& ancestor_map, LowMap& low_map)
+        : _graph(graph), _pred_map(pred_map), _tree_map(tree_map),
+          _order_map(order_map), _order_list(order_list),
+          _ancestor_map(ancestor_map), _low_map(low_map) {}
+
+      void reach(const Node& node) {
+        _order_map[node] = _order_list.size();
+        _low_map[node] = _order_list.size();
+        _ancestor_map[node] = _order_list.size();
+        _order_list.push_back(node);
+      }
+
+      void discover(const Arc& arc) {
+        Node target = _graph.target(arc);
+
+        _tree_map[arc] = true;
+        _pred_map[target] = arc;
+      }
+
+      void examine(const Arc& arc) {
+        Node source = _graph.source(arc);
+        Node target = _graph.target(arc);
+
+        if (_order_map[target] < _order_map[source] && !_tree_map[arc]) {
+          if (_low_map[source] > _order_map[target]) {
+            _low_map[source] = _order_map[target];
+          }
+          if (_ancestor_map[source] > _order_map[target]) {
+            _ancestor_map[source] = _order_map[target];
+          }
+        }
+      }
+
+      void backtrack(const Arc& arc) {
+        Node source = _graph.source(arc);
+        Node target = _graph.target(arc);
+
+        if (_low_map[source] > _low_map[target]) {
+          _low_map[source] = _low_map[target];
+        }
+      }
+
+      const Graph& _graph;
+      PredMap& _pred_map;
+      TreeMap& _tree_map;
+      OrderMap& _order_map;
+      OrderList& _order_list;
+      AncestorMap& _ancestor_map;
+      LowMap& _low_map;
+    };
+
+    template <typename Graph, bool embedding = true>
+    struct NodeDataNode {
+      int prev, next;
+      int visited;
+      typename Graph::Arc first;
+      bool inverted;
+    };
+
+    template <typename Graph>
+    struct NodeDataNode<Graph, false> {
+      int prev, next;
+      int visited;
+    };
+
+    template <typename Graph>
+    struct ChildListNode {
+      typedef typename Graph::Node Node;
+      Node first;
+      Node prev, next;
+    };
+
+    template <typename Graph>
+    struct ArcListNode {
+      typename Graph::Arc prev, next;
+    };
+
+    template <typename Graph>
+    class PlanarityChecking {
+    private:
+
+      TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+      const Graph& _graph;
+
+    private:
+
+      typedef typename Graph::template NodeMap<Arc> PredMap;
+
+      typedef typename Graph::template EdgeMap<bool> TreeMap;
+
+      typedef typename Graph::template NodeMap<int> OrderMap;
+      typedef std::vector<Node> OrderList;
+
+      typedef typename Graph::template NodeMap<int> LowMap;
+      typedef typename Graph::template NodeMap<int> AncestorMap;
+
+      typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
+      typedef std::vector<NodeDataNode> NodeData;
+
+      typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
+      typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
+
+      typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
+
+      typedef typename Graph::template NodeMap<bool> EmbedArc;
+
+    public:
+
+      PlanarityChecking(const Graph& graph) : _graph(graph) {}
+
+      bool run() {
+        typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
+
+        PredMap pred_map(_graph, INVALID);
+        TreeMap tree_map(_graph, false);
+
+        OrderMap order_map(_graph, -1);
+        OrderList order_list;
+
+        AncestorMap ancestor_map(_graph, -1);
+        LowMap low_map(_graph, -1);
+
+        Visitor visitor(_graph, pred_map, tree_map,
+                        order_map, order_list, ancestor_map, low_map);
+        DfsVisit<Graph, Visitor> visit(_graph, visitor);
+        visit.run();
+
+        ChildLists child_lists(_graph);
+        createChildLists(tree_map, order_map, low_map, child_lists);
+
+        NodeData node_data(2 * order_list.size());
+
+        EmbedArc embed_arc(_graph, false);
+
+        MergeRoots merge_roots(_graph);
+
+        for (int i = order_list.size() - 1; i >= 0; --i) {
+
+          Node node = order_list[i];
+
+          Node source = node;
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && tree_map[e]) {
+              initFace(target, node_data, order_map, order_list);
+            }
+          }
+
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && !tree_map[e]) {
+              embed_arc[target] = true;
+              walkUp(target, source, i, pred_map, low_map,
+                     order_map, order_list, node_data, merge_roots);
+            }
+          }
+
+          for (typename MergeRoots::Value::iterator it =
+                 merge_roots[node].begin();
+               it != merge_roots[node].end(); ++it) {
+            int rn = *it;
+            walkDown(rn, i, node_data, order_list, child_lists,
+                     ancestor_map, low_map, embed_arc, merge_roots);
+          }
+          merge_roots[node].clear();
+
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && !tree_map[e]) {
+              if (embed_arc[target]) {
+                return false;
+              }
+            }
+          }
+        }
+
+        return true;
+      }
+
+    private:
+
+      void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
+                            const LowMap& low_map, ChildLists& child_lists) {
+
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          Node source = n;
+
+          std::vector<Node> targets;
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && tree_map[e]) {
+              targets.push_back(target);
+            }
+          }
+
+          if (targets.size() == 0) {
+            child_lists[source].first = INVALID;
+          } else if (targets.size() == 1) {
+            child_lists[source].first = targets[0];
+            child_lists[targets[0]].prev = INVALID;
+            child_lists[targets[0]].next = INVALID;
+          } else {
+            radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
+            for (int i = 1; i < int(targets.size()); ++i) {
+              child_lists[targets[i]].prev = targets[i - 1];
+              child_lists[targets[i - 1]].next = targets[i];
+            }
+            child_lists[targets.back()].next = INVALID;
+            child_lists[targets.front()].prev = INVALID;
+            child_lists[source].first = targets.front();
+          }
+        }
+      }
+
+      void walkUp(const Node& node, Node root, int rorder,
+                  const PredMap& pred_map, const LowMap& low_map,
+                  const OrderMap& order_map, const OrderList& order_list,
+                  NodeData& node_data, MergeRoots& merge_roots) {
+
+        int na, nb;
+        bool da, db;
+
+        na = nb = order_map[node];
+        da = true; db = false;
+
+        while (true) {
+
+          if (node_data[na].visited == rorder) break;
+          if (node_data[nb].visited == rorder) break;
+
+          node_data[na].visited = rorder;
+          node_data[nb].visited = rorder;
+
+          int rn = -1;
+
+          if (na >= int(order_list.size())) {
+            rn = na;
+          } else if (nb >= int(order_list.size())) {
+            rn = nb;
+          }
+
+          if (rn == -1) {
+            int nn;
+
+            nn = da ? node_data[na].prev : node_data[na].next;
+            da = node_data[nn].prev != na;
+            na = nn;
+
+            nn = db ? node_data[nb].prev : node_data[nb].next;
+            db = node_data[nn].prev != nb;
+            nb = nn;
+
+          } else {
+
+            Node rep = order_list[rn - order_list.size()];
+            Node parent = _graph.source(pred_map[rep]);
+
+            if (low_map[rep] < rorder) {
+              merge_roots[parent].push_back(rn);
+            } else {
+              merge_roots[parent].push_front(rn);
+            }
+
+            if (parent != root) {
+              na = nb = order_map[parent];
+              da = true; db = false;
+            } else {
+              break;
+            }
+          }
+        }
+      }
+
+      void walkDown(int rn, int rorder, NodeData& node_data,
+                    OrderList& order_list, ChildLists& child_lists,
+                    AncestorMap& ancestor_map, LowMap& low_map,
+                    EmbedArc& embed_arc, MergeRoots& merge_roots) {
+
+        std::vector<std::pair<int, bool> > merge_stack;
+
+        for (int di = 0; di < 2; ++di) {
+          bool rd = di == 0;
+          int pn = rn;
+          int n = rd ? node_data[rn].next : node_data[rn].prev;
+
+          while (n != rn) {
+
+            Node node = order_list[n];
+
+            if (embed_arc[node]) {
+
+              // Merging components on the critical path
+              while (!merge_stack.empty()) {
+
+                // Component root
+                int cn = merge_stack.back().first;
+                bool cd = merge_stack.back().second;
+                merge_stack.pop_back();
+
+                // Parent of component
+                int dn = merge_stack.back().first;
+                bool dd = merge_stack.back().second;
+                merge_stack.pop_back();
+
+                Node parent = order_list[dn];
+
+                // Erasing from merge_roots
+                merge_roots[parent].pop_front();
+
+                Node child = order_list[cn - order_list.size()];
+
+                // Erasing from child_lists
+                if (child_lists[child].prev != INVALID) {
+                  child_lists[child_lists[child].prev].next =
+                    child_lists[child].next;
+                } else {
+                  child_lists[parent].first = child_lists[child].next;
+                }
+
+                if (child_lists[child].next != INVALID) {
+                  child_lists[child_lists[child].next].prev =
+                    child_lists[child].prev;
+                }
+
+                // Merging external faces
+                {
+                  int en = cn;
+                  cn = cd ? node_data[cn].prev : node_data[cn].next;
+                  cd = node_data[cn].next == en;
+
+                }
+
+                if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
+                if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
+
+              }
+
+              bool d = pn == node_data[n].prev;
+
+              if (node_data[n].prev == node_data[n].next &&
+                  node_data[n].inverted) {
+                d = !d;
+              }
+
+              // Embedding arc into external face
+              if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
+              if (d) node_data[n].prev = rn; else node_data[n].next = rn;
+              pn = rn;
+
+              embed_arc[order_list[n]] = false;
+            }
+
+            if (!merge_roots[node].empty()) {
+
+              bool d = pn == node_data[n].prev;
+
+              merge_stack.push_back(std::make_pair(n, d));
+
+              int rn = merge_roots[node].front();
+
+              int xn = node_data[rn].next;
+              Node xnode = order_list[xn];
+
+              int yn = node_data[rn].prev;
+              Node ynode = order_list[yn];
+
+              bool rd;
+              if (!external(xnode, rorder, child_lists,
+                            ancestor_map, low_map)) {
+                rd = true;
+              } else if (!external(ynode, rorder, child_lists,
+                                   ancestor_map, low_map)) {
+                rd = false;
+              } else if (pertinent(xnode, embed_arc, merge_roots)) {
+                rd = true;
+              } else {
+                rd = false;
+              }
+
+              merge_stack.push_back(std::make_pair(rn, rd));
+
+              pn = rn;
+              n = rd ? xn : yn;
+
+            } else if (!external(node, rorder, child_lists,
+                                 ancestor_map, low_map)) {
+              int nn = (node_data[n].next != pn ?
+                        node_data[n].next : node_data[n].prev);
+
+              bool nd = n == node_data[nn].prev;
+
+              if (nd) node_data[nn].prev = pn;
+              else node_data[nn].next = pn;
+
+              if (n == node_data[pn].prev) node_data[pn].prev = nn;
+              else node_data[pn].next = nn;
+
+              node_data[nn].inverted =
+                (node_data[nn].prev == node_data[nn].next && nd != rd);
+
+              n = nn;
+            }
+            else break;
+
+          }
+
+          if (!merge_stack.empty() || n == rn) {
+            break;
+          }
+        }
+      }
+
+      void initFace(const Node& node, NodeData& node_data,
+                    const OrderMap& order_map, const OrderList& order_list) {
+        int n = order_map[node];
+        int rn = n + order_list.size();
+
+        node_data[n].next = node_data[n].prev = rn;
+        node_data[rn].next = node_data[rn].prev = n;
+
+        node_data[n].visited = order_list.size();
+        node_data[rn].visited = order_list.size();
+
+      }
+
+      bool external(const Node& node, int rorder,
+                    ChildLists& child_lists, AncestorMap& ancestor_map,
+                    LowMap& low_map) {
+        Node child = child_lists[node].first;
+
+        if (child != INVALID) {
+          if (low_map[child] < rorder) return true;
+        }
+
+        if (ancestor_map[node] < rorder) return true;
+
+        return false;
+      }
+
+      bool pertinent(const Node& node, const EmbedArc& embed_arc,
+                     const MergeRoots& merge_roots) {
+        return !merge_roots[node].empty() || embed_arc[node];
+      }
+
+    };
+
+  }
+
+  /// \ingroup planar
+  ///
+  /// \brief Planarity checking of an undirected simple graph
+  ///
+  /// This function implements the Boyer-Myrvold algorithm for
+  /// planarity checking of an undirected simple graph. It is a simplified
+  /// version of the PlanarEmbedding algorithm class because neither
+  /// the embedding nor the Kuratowski subdivisons are computed.
+  template <typename GR>
+  bool checkPlanarity(const GR& graph) {
+    _planarity_bits::PlanarityChecking<GR> pc(graph);
+    return pc.run();
+  }
+
+  /// \ingroup planar
+  ///
+  /// \brief Planar embedding of an undirected simple graph
+  ///
+  /// This class implements the Boyer-Myrvold algorithm for planar
+  /// embedding of an undirected simple graph. The planar embedding is an
+  /// ordering of the outgoing edges of the nodes, which is a possible
+  /// configuration to draw the graph in the plane. If there is not
+  /// such ordering then the graph contains a K<sub>5</sub> (full graph
+  /// with 5 nodes) or a K<sub>3,3</sub> (complete bipartite graph on
+  /// 3 Red and 3 Blue nodes) subdivision.
+  ///
+  /// The current implementation calculates either an embedding or a
+  /// Kuratowski subdivision. The running time of the algorithm is O(n).
+  ///
+  /// \see PlanarDrawing, checkPlanarity()
+  template <typename Graph>
+  class PlanarEmbedding {
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    const Graph& _graph;
+    typename Graph::template ArcMap<Arc> _embedding;
+
+    typename Graph::template EdgeMap<bool> _kuratowski;
+
+  private:
+
+    typedef typename Graph::template NodeMap<Arc> PredMap;
+
+    typedef typename Graph::template EdgeMap<bool> TreeMap;
+
+    typedef typename Graph::template NodeMap<int> OrderMap;
+    typedef std::vector<Node> OrderList;
+
+    typedef typename Graph::template NodeMap<int> LowMap;
+    typedef typename Graph::template NodeMap<int> AncestorMap;
+
+    typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
+    typedef std::vector<NodeDataNode> NodeData;
+
+    typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
+    typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
+
+    typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
+
+    typedef typename Graph::template NodeMap<Arc> EmbedArc;
+
+    typedef _planarity_bits::ArcListNode<Graph> ArcListNode;
+    typedef typename Graph::template ArcMap<ArcListNode> ArcLists;
+
+    typedef typename Graph::template NodeMap<bool> FlipMap;
+
+    typedef typename Graph::template NodeMap<int> TypeMap;
+
+    enum IsolatorNodeType {
+      HIGHX = 6, LOWX = 7,
+      HIGHY = 8, LOWY = 9,
+      ROOT = 10, PERTINENT = 11,
+      INTERNAL = 12
+    };
+
+  public:
+
+    /// \brief The map type for storing the embedding
+    ///
+    /// The map type for storing the embedding.
+    /// \see embeddingMap()
+    typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \pre The graph must be simple, i.e. it should not
+    /// contain parallel or loop arcs.
+    PlanarEmbedding(const Graph& graph)
+      : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// \param kuratowski If this parameter is set to \c false, then the
+    /// algorithm does not compute a Kuratowski subdivision.
+    /// \return \c true if the graph is planar.
+    bool run(bool kuratowski = true) {
+      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
+
+      PredMap pred_map(_graph, INVALID);
+      TreeMap tree_map(_graph, false);
+
+      OrderMap order_map(_graph, -1);
+      OrderList order_list;
+
+      AncestorMap ancestor_map(_graph, -1);
+      LowMap low_map(_graph, -1);
+
+      Visitor visitor(_graph, pred_map, tree_map,
+                      order_map, order_list, ancestor_map, low_map);
+      DfsVisit<Graph, Visitor> visit(_graph, visitor);
+      visit.run();
+
+      ChildLists child_lists(_graph);
+      createChildLists(tree_map, order_map, low_map, child_lists);
+
+      NodeData node_data(2 * order_list.size());
+
+      EmbedArc embed_arc(_graph, INVALID);
+
+      MergeRoots merge_roots(_graph);
+
+      ArcLists arc_lists(_graph);
+
+      FlipMap flip_map(_graph, false);
+
+      for (int i = order_list.size() - 1; i >= 0; --i) {
+
+        Node node = order_list[i];
+
+        node_data[i].first = INVALID;
+
+        Node source = node;
+        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+          Node target = _graph.target(e);
+
+          if (order_map[source] < order_map[target] && tree_map[e]) {
+            initFace(target, arc_lists, node_data,
+                     pred_map, order_map, order_list);
+          }
+        }
+
+        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+          Node target = _graph.target(e);
+
+          if (order_map[source] < order_map[target] && !tree_map[e]) {
+            embed_arc[target] = e;
+            walkUp(target, source, i, pred_map, low_map,
+                   order_map, order_list, node_data, merge_roots);
+          }
+        }
+
+        for (typename MergeRoots::Value::iterator it =
+               merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
+          int rn = *it;
+          walkDown(rn, i, node_data, arc_lists, flip_map, order_list,
+                   child_lists, ancestor_map, low_map, embed_arc, merge_roots);
+        }
+        merge_roots[node].clear();
+
+        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+          Node target = _graph.target(e);
+
+          if (order_map[source] < order_map[target] && !tree_map[e]) {
+            if (embed_arc[target] != INVALID) {
+              if (kuratowski) {
+                isolateKuratowski(e, node_data, arc_lists, flip_map,
+                                  order_map, order_list, pred_map, child_lists,
+                                  ancestor_map, low_map,
+                                  embed_arc, merge_roots);
+              }
+              return false;
+            }
+          }
+        }
+      }
+
+      for (int i = 0; i < int(order_list.size()); ++i) {
+
+        mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
+                            child_lists, arc_lists);
+        storeEmbedding(order_list[i], node_data, order_map, pred_map,
+                       arc_lists, flip_map);
+      }
+
+      return true;
+    }
+
+    /// \brief Give back the successor of an arc
+    ///
+    /// This function gives back the successor of an arc. It makes
+    /// possible to query the cyclic order of the outgoing arcs from
+    /// a node.
+    Arc next(const Arc& arc) const {
+      return _embedding[arc];
+    }
+
+    /// \brief Give back the calculated embedding map
+    ///
+    /// This function gives back the calculated embedding map, which
+    /// contains the successor of each arc in the cyclic order of the
+    /// outgoing arcs of its source node.
+    const EmbeddingMap& embeddingMap() const {
+      return _embedding;
+    }
+
+    /// \brief Give back \c true if the given edge is in the Kuratowski
+    /// subdivision
+    ///
+    /// This function gives back \c true if the given edge is in the found
+    /// Kuratowski subdivision.
+    /// \pre The \c run() function must be called with \c true parameter
+    /// before using this function.
+    bool kuratowski(const Edge& edge) const {
+      return _kuratowski[edge];
+    }
+
+  private:
+
+    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
+                          const LowMap& low_map, ChildLists& child_lists) {
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Node source = n;
+
+        std::vector<Node> targets;
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node target = _graph.target(e);
+
+          if (order_map[source] < order_map[target] && tree_map[e]) {
+            targets.push_back(target);
+          }
+        }
+
+        if (targets.size() == 0) {
+          child_lists[source].first = INVALID;
+        } else if (targets.size() == 1) {
+          child_lists[source].first = targets[0];
+          child_lists[targets[0]].prev = INVALID;
+          child_lists[targets[0]].next = INVALID;
+        } else {
+          radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
+          for (int i = 1; i < int(targets.size()); ++i) {
+            child_lists[targets[i]].prev = targets[i - 1];
+            child_lists[targets[i - 1]].next = targets[i];
+          }
+          child_lists[targets.back()].next = INVALID;
+          child_lists[targets.front()].prev = INVALID;
+          child_lists[source].first = targets.front();
+        }
+      }
+    }
+
+    void walkUp(const Node& node, Node root, int rorder,
+                const PredMap& pred_map, const LowMap& low_map,
+                const OrderMap& order_map, const OrderList& order_list,
+                NodeData& node_data, MergeRoots& merge_roots) {
+
+      int na, nb;
+      bool da, db;
+
+      na = nb = order_map[node];
+      da = true; db = false;
+
+      while (true) {
+
+        if (node_data[na].visited == rorder) break;
+        if (node_data[nb].visited == rorder) break;
+
+        node_data[na].visited = rorder;
+        node_data[nb].visited = rorder;
+
+        int rn = -1;
+
+        if (na >= int(order_list.size())) {
+          rn = na;
+        } else if (nb >= int(order_list.size())) {
+          rn = nb;
+        }
+
+        if (rn == -1) {
+          int nn;
+
+          nn = da ? node_data[na].prev : node_data[na].next;
+          da = node_data[nn].prev != na;
+          na = nn;
+
+          nn = db ? node_data[nb].prev : node_data[nb].next;
+          db = node_data[nn].prev != nb;
+          nb = nn;
+
+        } else {
+
+          Node rep = order_list[rn - order_list.size()];
+          Node parent = _graph.source(pred_map[rep]);
+
+          if (low_map[rep] < rorder) {
+            merge_roots[parent].push_back(rn);
+          } else {
+            merge_roots[parent].push_front(rn);
+          }
+
+          if (parent != root) {
+            na = nb = order_map[parent];
+            da = true; db = false;
+          } else {
+            break;
+          }
+        }
+      }
+    }
+
+    void walkDown(int rn, int rorder, NodeData& node_data,
+                  ArcLists& arc_lists, FlipMap& flip_map,
+                  OrderList& order_list, ChildLists& child_lists,
+                  AncestorMap& ancestor_map, LowMap& low_map,
+                  EmbedArc& embed_arc, MergeRoots& merge_roots) {
+
+      std::vector<std::pair<int, bool> > merge_stack;
+
+      for (int di = 0; di < 2; ++di) {
+        bool rd = di == 0;
+        int pn = rn;
+        int n = rd ? node_data[rn].next : node_data[rn].prev;
+
+        while (n != rn) {
+
+          Node node = order_list[n];
+
+          if (embed_arc[node] != INVALID) {
+
+            // Merging components on the critical path
+            while (!merge_stack.empty()) {
+
+              // Component root
+              int cn = merge_stack.back().first;
+              bool cd = merge_stack.back().second;
+              merge_stack.pop_back();
+
+              // Parent of component
+              int dn = merge_stack.back().first;
+              bool dd = merge_stack.back().second;
+              merge_stack.pop_back();
+
+              Node parent = order_list[dn];
+
+              // Erasing from merge_roots
+              merge_roots[parent].pop_front();
+
+              Node child = order_list[cn - order_list.size()];
+
+              // Erasing from child_lists
+              if (child_lists[child].prev != INVALID) {
+                child_lists[child_lists[child].prev].next =
+                  child_lists[child].next;
+              } else {
+                child_lists[parent].first = child_lists[child].next;
+              }
+
+              if (child_lists[child].next != INVALID) {
+                child_lists[child_lists[child].next].prev =
+                  child_lists[child].prev;
+              }
+
+              // Merging arcs + flipping
+              Arc de = node_data[dn].first;
+              Arc ce = node_data[cn].first;
+
+              flip_map[order_list[cn - order_list.size()]] = cd != dd;
+              if (cd != dd) {
+                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
+                ce = arc_lists[ce].prev;
+                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
+              }
+
+              {
+                Arc dne = arc_lists[de].next;
+                Arc cne = arc_lists[ce].next;
+
+                arc_lists[de].next = cne;
+                arc_lists[ce].next = dne;
+
+                arc_lists[dne].prev = ce;
+                arc_lists[cne].prev = de;
+              }
+
+              if (dd) {
+                node_data[dn].first = ce;
+              }
+
+              // Merging external faces
+              {
+                int en = cn;
+                cn = cd ? node_data[cn].prev : node_data[cn].next;
+                cd = node_data[cn].next == en;
+
+                 if (node_data[cn].prev == node_data[cn].next &&
+                    node_data[cn].inverted) {
+                   cd = !cd;
+                 }
+              }
+
+              if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
+              if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
+
+            }
+
+            bool d = pn == node_data[n].prev;
+
+            if (node_data[n].prev == node_data[n].next &&
+                node_data[n].inverted) {
+              d = !d;
+            }
+
+            // Add new arc
+            {
+              Arc arc = embed_arc[node];
+              Arc re = node_data[rn].first;
+
+              arc_lists[arc_lists[re].next].prev = arc;
+              arc_lists[arc].next = arc_lists[re].next;
+              arc_lists[arc].prev = re;
+              arc_lists[re].next = arc;
+
+              if (!rd) {
+                node_data[rn].first = arc;
+              }
+
+              Arc rev = _graph.oppositeArc(arc);
+              Arc e = node_data[n].first;
+
+              arc_lists[arc_lists[e].next].prev = rev;
+              arc_lists[rev].next = arc_lists[e].next;
+              arc_lists[rev].prev = e;
+              arc_lists[e].next = rev;
+
+              if (d) {
+                node_data[n].first = rev;
+              }
+
+            }
+
+            // Embedding arc into external face
+            if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
+            if (d) node_data[n].prev = rn; else node_data[n].next = rn;
+            pn = rn;
+
+            embed_arc[order_list[n]] = INVALID;
+          }
+
+          if (!merge_roots[node].empty()) {
+
+            bool d = pn == node_data[n].prev;
+            if (node_data[n].prev == node_data[n].next &&
+                node_data[n].inverted) {
+              d = !d;
+            }
+
+            merge_stack.push_back(std::make_pair(n, d));
+
+            int rn = merge_roots[node].front();
+
+            int xn = node_data[rn].next;
+            Node xnode = order_list[xn];
+
+            int yn = node_data[rn].prev;
+            Node ynode = order_list[yn];
+
+            bool rd;
+            if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
+              rd = true;
+            } else if (!external(ynode, rorder, child_lists,
+                                 ancestor_map, low_map)) {
+              rd = false;
+            } else if (pertinent(xnode, embed_arc, merge_roots)) {
+              rd = true;
+            } else {
+              rd = false;
+            }
+
+            merge_stack.push_back(std::make_pair(rn, rd));
+
+            pn = rn;
+            n = rd ? xn : yn;
+
+          } else if (!external(node, rorder, child_lists,
+                               ancestor_map, low_map)) {
+            int nn = (node_data[n].next != pn ?
+                      node_data[n].next : node_data[n].prev);
+
+            bool nd = n == node_data[nn].prev;
+
+            if (nd) node_data[nn].prev = pn;
+            else node_data[nn].next = pn;
+
+            if (n == node_data[pn].prev) node_data[pn].prev = nn;
+            else node_data[pn].next = nn;
+
+            node_data[nn].inverted =
+              (node_data[nn].prev == node_data[nn].next && nd != rd);
+
+            n = nn;
+          }
+          else break;
+
+        }
+
+        if (!merge_stack.empty() || n == rn) {
+          break;
+        }
+      }
+    }
+
+    void initFace(const Node& node, ArcLists& arc_lists,
+                  NodeData& node_data, const PredMap& pred_map,
+                  const OrderMap& order_map, const OrderList& order_list) {
+      int n = order_map[node];
+      int rn = n + order_list.size();
+
+      node_data[n].next = node_data[n].prev = rn;
+      node_data[rn].next = node_data[rn].prev = n;
+
+      node_data[n].visited = order_list.size();
+      node_data[rn].visited = order_list.size();
+
+      node_data[n].inverted = false;
+      node_data[rn].inverted = false;
+
+      Arc arc = pred_map[node];
+      Arc rev = _graph.oppositeArc(arc);
+
+      node_data[rn].first = arc;
+      node_data[n].first = rev;
+
+      arc_lists[arc].prev = arc;
+      arc_lists[arc].next = arc;
+
+      arc_lists[rev].prev = rev;
+      arc_lists[rev].next = rev;
+
+    }
+
+    void mergeRemainingFaces(const Node& node, NodeData& node_data,
+                             OrderList& order_list, OrderMap& order_map,
+                             ChildLists& child_lists, ArcLists& arc_lists) {
+      while (child_lists[node].first != INVALID) {
+        int dd = order_map[node];
+        Node child = child_lists[node].first;
+        int cd = order_map[child] + order_list.size();
+        child_lists[node].first = child_lists[child].next;
+
+        Arc de = node_data[dd].first;
+        Arc ce = node_data[cd].first;
+
+        if (de != INVALID) {
+          Arc dne = arc_lists[de].next;
+          Arc cne = arc_lists[ce].next;
+
+          arc_lists[de].next = cne;
+          arc_lists[ce].next = dne;
+
+          arc_lists[dne].prev = ce;
+          arc_lists[cne].prev = de;
+        }
+
+        node_data[dd].first = ce;
+
+      }
+    }
+
+    void storeEmbedding(const Node& node, NodeData& node_data,
+                        OrderMap& order_map, PredMap& pred_map,
+                        ArcLists& arc_lists, FlipMap& flip_map) {
+
+      if (node_data[order_map[node]].first == INVALID) return;
+
+      if (pred_map[node] != INVALID) {
+        Node source = _graph.source(pred_map[node]);
+        flip_map[node] = flip_map[node] != flip_map[source];
+      }
+
+      Arc first = node_data[order_map[node]].first;
+      Arc prev = first;
+
+      Arc arc = flip_map[node] ?
+        arc_lists[prev].prev : arc_lists[prev].next;
+
+      _embedding[prev] = arc;
+
+      while (arc != first) {
+        Arc next = arc_lists[arc].prev == prev ?
+          arc_lists[arc].next : arc_lists[arc].prev;
+        prev = arc; arc = next;
+        _embedding[prev] = arc;
+      }
+    }
+
+
+    bool external(const Node& node, int rorder,
+                  ChildLists& child_lists, AncestorMap& ancestor_map,
+                  LowMap& low_map) {
+      Node child = child_lists[node].first;
+
+      if (child != INVALID) {
+        if (low_map[child] < rorder) return true;
+      }
+
+      if (ancestor_map[node] < rorder) return true;
+
+      return false;
+    }
+
+    bool pertinent(const Node& node, const EmbedArc& embed_arc,
+                   const MergeRoots& merge_roots) {
+      return !merge_roots[node].empty() || embed_arc[node] != INVALID;
+    }
+
+    int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
+                 AncestorMap& ancestor_map, LowMap& low_map) {
+      int low_point;
+
+      Node child = child_lists[node].first;
+
+      if (child != INVALID) {
+        low_point = low_map[child];
+      } else {
+        low_point = order_map[node];
+      }
+
+      if (low_point > ancestor_map[node]) {
+        low_point = ancestor_map[node];
+      }
+
+      return low_point;
+    }
+
+    int findComponentRoot(Node root, Node node, ChildLists& child_lists,
+                          OrderMap& order_map, OrderList& order_list) {
+
+      int order = order_map[root];
+      int norder = order_map[node];
+
+      Node child = child_lists[root].first;
+      while (child != INVALID) {
+        int corder = order_map[child];
+        if (corder > order && corder < norder) {
+          order = corder;
+        }
+        child = child_lists[child].next;
+      }
+      return order + order_list.size();
+    }
+
+    Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
+                       EmbedArc& embed_arc, MergeRoots& merge_roots) {
+      Node wnode =_graph.target(node_data[order_map[node]].first);
+      while (!pertinent(wnode, embed_arc, merge_roots)) {
+        wnode = _graph.target(node_data[order_map[wnode]].first);
+      }
+      return wnode;
+    }
+
+
+    Node findExternal(Node node, int rorder, OrderMap& order_map,
+                      ChildLists& child_lists, AncestorMap& ancestor_map,
+                      LowMap& low_map, NodeData& node_data) {
+      Node wnode =_graph.target(node_data[order_map[node]].first);
+      while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
+        wnode = _graph.target(node_data[order_map[wnode]].first);
+      }
+      return wnode;
+    }
+
+    void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
+                        OrderList& order_list, OrderMap& order_map,
+                        NodeData& node_data, ArcLists& arc_lists,
+                        EmbedArc& embed_arc, MergeRoots& merge_roots,
+                        ChildLists& child_lists, AncestorMap& ancestor_map,
+                        LowMap& low_map) {
+
+      Node cnode = node;
+      Node pred = INVALID;
+
+      while (true) {
+
+        bool pert = pertinent(cnode, embed_arc, merge_roots);
+        bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
+
+        if (pert && ext) {
+          if (!merge_roots[cnode].empty()) {
+            int cn = merge_roots[cnode].back();
+
+            if (low_map[order_list[cn - order_list.size()]] < rorder) {
+              Arc arc = node_data[cn].first;
+              _kuratowski.set(arc, true);
+
+              pred = cnode;
+              cnode = _graph.target(arc);
+
+              continue;
+            }
+          }
+          wnode = znode = cnode;
+          return;
+
+        } else if (pert) {
+          wnode = cnode;
+
+          while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
+            Arc arc = node_data[order_map[cnode]].first;
+
+            if (_graph.target(arc) == pred) {
+              arc = arc_lists[arc].next;
+            }
+            _kuratowski.set(arc, true);
+
+            Node next = _graph.target(arc);
+            pred = cnode; cnode = next;
+          }
+
+          znode = cnode;
+          return;
+
+        } else if (ext) {
+          znode = cnode;
+
+          while (!pertinent(cnode, embed_arc, merge_roots)) {
+            Arc arc = node_data[order_map[cnode]].first;
+
+            if (_graph.target(arc) == pred) {
+              arc = arc_lists[arc].next;
+            }
+            _kuratowski.set(arc, true);
+
+            Node next = _graph.target(arc);
+            pred = cnode; cnode = next;
+          }
+
+          wnode = cnode;
+          return;
+
+        } else {
+          Arc arc = node_data[order_map[cnode]].first;
+
+          if (_graph.target(arc) == pred) {
+            arc = arc_lists[arc].next;
+          }
+          _kuratowski.set(arc, true);
+
+          Node next = _graph.target(arc);
+          pred = cnode; cnode = next;
+        }
+
+      }
+
+    }
+
+    void orientComponent(Node root, int rn, OrderMap& order_map,
+                         PredMap& pred_map, NodeData& node_data,
+                         ArcLists& arc_lists, FlipMap& flip_map,
+                         TypeMap& type_map) {
+      node_data[order_map[root]].first = node_data[rn].first;
+      type_map[root] = 1;
+
+      std::vector<Node> st, qu;
+
+      st.push_back(root);
+      while (!st.empty()) {
+        Node node = st.back();
+        st.pop_back();
+        qu.push_back(node);
+
+        Arc arc = node_data[order_map[node]].first;
+
+        if (type_map[_graph.target(arc)] == 0) {
+          st.push_back(_graph.target(arc));
+          type_map[_graph.target(arc)] = 1;
+        }
+
+        Arc last = arc, pred = arc;
+        arc = arc_lists[arc].next;
+        while (arc != last) {
+
+          if (type_map[_graph.target(arc)] == 0) {
+            st.push_back(_graph.target(arc));
+            type_map[_graph.target(arc)] = 1;
+          }
+
+          Arc next = arc_lists[arc].next != pred ?
+            arc_lists[arc].next : arc_lists[arc].prev;
+          pred = arc; arc = next;
+        }
+
+      }
+
+      type_map[root] = 2;
+      flip_map[root] = false;
+
+      for (int i = 1; i < int(qu.size()); ++i) {
+
+        Node node = qu[i];
+
+        while (type_map[node] != 2) {
+          st.push_back(node);
+          type_map[node] = 2;
+          node = _graph.source(pred_map[node]);
+        }
+
+        bool flip = flip_map[node];
+
+        while (!st.empty()) {
+          node = st.back();
+          st.pop_back();
+
+          flip_map[node] = flip != flip_map[node];
+          flip = flip_map[node];
+
+          if (flip) {
+            Arc arc = node_data[order_map[node]].first;
+            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
+            arc = arc_lists[arc].prev;
+            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
+            node_data[order_map[node]].first = arc;
+          }
+        }
+      }
+
+      for (int i = 0; i < int(qu.size()); ++i) {
+
+        Arc arc = node_data[order_map[qu[i]]].first;
+        Arc last = arc, pred = arc;
+
+        arc = arc_lists[arc].next;
+        while (arc != last) {
+
+          if (arc_lists[arc].next == pred) {
+            std::swap(arc_lists[arc].next, arc_lists[arc].prev);
+          }
+          pred = arc; arc = arc_lists[arc].next;
+        }
+
+      }
+    }
+
+    void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
+                      OrderMap& order_map, NodeData& node_data,
+                      TypeMap& type_map) {
+      Node node = _graph.target(node_data[order_map[root]].first);
+
+      while (node != ynode) {
+        type_map[node] = HIGHY;
+        node = _graph.target(node_data[order_map[node]].first);
+      }
+
+      while (node != wnode) {
+        type_map[node] = LOWY;
+        node = _graph.target(node_data[order_map[node]].first);
+      }
+
+      node = _graph.target(node_data[order_map[wnode]].first);
+
+      while (node != xnode) {
+        type_map[node] = LOWX;
+        node = _graph.target(node_data[order_map[node]].first);
+      }
+      type_map[node] = LOWX;
+
+      node = _graph.target(node_data[order_map[xnode]].first);
+      while (node != root) {
+        type_map[node] = HIGHX;
+        node = _graph.target(node_data[order_map[node]].first);
+      }
+
+      type_map[wnode] = PERTINENT;
+      type_map[root] = ROOT;
+    }
+
+    void findInternalPath(std::vector<Arc>& ipath,
+                          Node wnode, Node root, TypeMap& type_map,
+                          OrderMap& order_map, NodeData& node_data,
+                          ArcLists& arc_lists) {
+      std::vector<Arc> st;
+
+      Node node = wnode;
+
+      while (node != root) {
+        Arc arc = arc_lists[node_data[order_map[node]].first].next;
+        st.push_back(arc);
+        node = _graph.target(arc);
+      }
+
+      while (true) {
+        Arc arc = st.back();
+        if (type_map[_graph.target(arc)] == LOWX ||
+            type_map[_graph.target(arc)] == HIGHX) {
+          break;
+        }
+        if (type_map[_graph.target(arc)] == 2) {
+          type_map[_graph.target(arc)] = 3;
+
+          arc = arc_lists[_graph.oppositeArc(arc)].next;
+          st.push_back(arc);
+        } else {
+          st.pop_back();
+          arc = arc_lists[arc].next;
+
+          while (_graph.oppositeArc(arc) == st.back()) {
+            arc = st.back();
+            st.pop_back();
+            arc = arc_lists[arc].next;
+          }
+          st.push_back(arc);
+        }
+      }
+
+      for (int i = 0; i < int(st.size()); ++i) {
+        if (type_map[_graph.target(st[i])] != LOWY &&
+            type_map[_graph.target(st[i])] != HIGHY) {
+          for (; i < int(st.size()); ++i) {
+            ipath.push_back(st[i]);
+          }
+        }
+      }
+    }
+
+    void setInternalFlags(std::vector<Arc>& ipath, TypeMap& type_map) {
+      for (int i = 1; i < int(ipath.size()); ++i) {
+        type_map[_graph.source(ipath[i])] = INTERNAL;
+      }
+    }
+
+    void findPilePath(std::vector<Arc>& ppath,
+                      Node root, TypeMap& type_map, OrderMap& order_map,
+                      NodeData& node_data, ArcLists& arc_lists) {
+      std::vector<Arc> st;
+
+      st.push_back(_graph.oppositeArc(node_data[order_map[root]].first));
+      st.push_back(node_data[order_map[root]].first);
+
+      while (st.size() > 1) {
+        Arc arc = st.back();
+        if (type_map[_graph.target(arc)] == INTERNAL) {
+          break;
+        }
+        if (type_map[_graph.target(arc)] == 3) {
+          type_map[_graph.target(arc)] = 4;
+
+          arc = arc_lists[_graph.oppositeArc(arc)].next;
+          st.push_back(arc);
+        } else {
+          st.pop_back();
+          arc = arc_lists[arc].next;
+
+          while (!st.empty() && _graph.oppositeArc(arc) == st.back()) {
+            arc = st.back();
+            st.pop_back();
+            arc = arc_lists[arc].next;
+          }
+          st.push_back(arc);
+        }
+      }
+
+      for (int i = 1; i < int(st.size()); ++i) {
+        ppath.push_back(st[i]);
+      }
+    }
+
+
+    int markExternalPath(Node node, OrderMap& order_map,
+                         ChildLists& child_lists, PredMap& pred_map,
+                         AncestorMap& ancestor_map, LowMap& low_map) {
+      int lp = lowPoint(node, order_map, child_lists,
+                        ancestor_map, low_map);
+
+      if (ancestor_map[node] != lp) {
+        node = child_lists[node].first;
+        _kuratowski[pred_map[node]] = true;
+
+        while (ancestor_map[node] != lp) {
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node tnode = _graph.target(e);
+            if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
+              node = tnode;
+              _kuratowski[e] = true;
+              break;
+            }
+          }
+        }
+      }
+
+      for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+        if (order_map[_graph.target(e)] == lp) {
+          _kuratowski[e] = true;
+          break;
+        }
+      }
+
+      return lp;
+    }
+
+    void markPertinentPath(Node node, OrderMap& order_map,
+                           NodeData& node_data, ArcLists& arc_lists,
+                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
+      while (embed_arc[node] == INVALID) {
+        int n = merge_roots[node].front();
+        Arc arc = node_data[n].first;
+
+        _kuratowski.set(arc, true);
+
+        Node pred = node;
+        node = _graph.target(arc);
+        while (!pertinent(node, embed_arc, merge_roots)) {
+          arc = node_data[order_map[node]].first;
+          if (_graph.target(arc) == pred) {
+            arc = arc_lists[arc].next;
+          }
+          _kuratowski.set(arc, true);
+          pred = node;
+          node = _graph.target(arc);
+        }
+      }
+      _kuratowski.set(embed_arc[node], true);
+    }
+
+    void markPredPath(Node node, Node snode, PredMap& pred_map) {
+      while (node != snode) {
+        _kuratowski.set(pred_map[node], true);
+        node = _graph.source(pred_map[node]);
+      }
+    }
+
+    void markFacePath(Node ynode, Node xnode,
+                      OrderMap& order_map, NodeData& node_data) {
+      Arc arc = node_data[order_map[ynode]].first;
+      Node node = _graph.target(arc);
+      _kuratowski.set(arc, true);
+
+      while (node != xnode) {
+        arc = node_data[order_map[node]].first;
+        _kuratowski.set(arc, true);
+        node = _graph.target(arc);
+      }
+    }
+
+    void markInternalPath(std::vector<Arc>& path) {
+      for (int i = 0; i < int(path.size()); ++i) {
+        _kuratowski.set(path[i], true);
+      }
+    }
+
+    void markPilePath(std::vector<Arc>& path) {
+      for (int i = 0; i < int(path.size()); ++i) {
+        _kuratowski.set(path[i], true);
+      }
+    }
+
+    void isolateKuratowski(Arc arc, NodeData& node_data,
+                           ArcLists& arc_lists, FlipMap& flip_map,
+                           OrderMap& order_map, OrderList& order_list,
+                           PredMap& pred_map, ChildLists& child_lists,
+                           AncestorMap& ancestor_map, LowMap& low_map,
+                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
+
+      Node root = _graph.source(arc);
+      Node enode = _graph.target(arc);
+
+      int rorder = order_map[root];
+
+      TypeMap type_map(_graph, 0);
+
+      int rn = findComponentRoot(root, enode, child_lists,
+                                 order_map, order_list);
+
+      Node xnode = order_list[node_data[rn].next];
+      Node ynode = order_list[node_data[rn].prev];
+
+      // Minor-A
+      {
+        while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
+
+          if (!merge_roots[xnode].empty()) {
+            root = xnode;
+            rn = merge_roots[xnode].front();
+          } else {
+            root = ynode;
+            rn = merge_roots[ynode].front();
+          }
+
+          xnode = order_list[node_data[rn].next];
+          ynode = order_list[node_data[rn].prev];
+        }
+
+        if (root != _graph.source(arc)) {
+          orientComponent(root, rn, order_map, pred_map,
+                          node_data, arc_lists, flip_map, type_map);
+          markFacePath(root, root, order_map, node_data);
+          int xlp = markExternalPath(xnode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          int ylp = markExternalPath(ynode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+          Node lwnode = findPertinent(ynode, order_map, node_data,
+                                      embed_arc, merge_roots);
+
+          markPertinentPath(lwnode, order_map, node_data, arc_lists,
+                            embed_arc, merge_roots);
+
+          return;
+        }
+      }
+
+      orientComponent(root, rn, order_map, pred_map,
+                      node_data, arc_lists, flip_map, type_map);
+
+      Node wnode = findPertinent(ynode, order_map, node_data,
+                                 embed_arc, merge_roots);
+      setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
+
+
+      //Minor-B
+      if (!merge_roots[wnode].empty()) {
+        int cn = merge_roots[wnode].back();
+        Node rep = order_list[cn - order_list.size()];
+        if (low_map[rep] < rorder) {
+          markFacePath(root, root, order_map, node_data);
+          int xlp = markExternalPath(xnode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          int ylp = markExternalPath(ynode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+
+          Node lwnode, lznode;
+          markCommonPath(wnode, rorder, lwnode, lznode, order_list,
+                         order_map, node_data, arc_lists, embed_arc,
+                         merge_roots, child_lists, ancestor_map, low_map);
+
+          markPertinentPath(lwnode, order_map, node_data, arc_lists,
+                            embed_arc, merge_roots);
+          int zlp = markExternalPath(lznode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+
+          int minlp = xlp < ylp ? xlp : ylp;
+          if (zlp < minlp) minlp = zlp;
+
+          int maxlp = xlp > ylp ? xlp : ylp;
+          if (zlp > maxlp) maxlp = zlp;
+
+          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
+
+          return;
+        }
+      }
+
+      Node pxnode, pynode;
+      std::vector<Arc> ipath;
+      findInternalPath(ipath, wnode, root, type_map, order_map,
+                       node_data, arc_lists);
+      setInternalFlags(ipath, type_map);
+      pynode = _graph.source(ipath.front());
+      pxnode = _graph.target(ipath.back());
+
+      wnode = findPertinent(pynode, order_map, node_data,
+                            embed_arc, merge_roots);
+
+      // Minor-C
+      {
+        if (type_map[_graph.source(ipath.front())] == HIGHY) {
+          if (type_map[_graph.target(ipath.back())] == HIGHX) {
+            markFacePath(xnode, pxnode, order_map, node_data);
+          }
+          markFacePath(root, xnode, order_map, node_data);
+          markPertinentPath(wnode, order_map, node_data, arc_lists,
+                            embed_arc, merge_roots);
+          markInternalPath(ipath);
+          int xlp = markExternalPath(xnode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          int ylp = markExternalPath(ynode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+          return;
+        }
+
+        if (type_map[_graph.target(ipath.back())] == HIGHX) {
+          markFacePath(ynode, root, order_map, node_data);
+          markPertinentPath(wnode, order_map, node_data, arc_lists,
+                            embed_arc, merge_roots);
+          markInternalPath(ipath);
+          int xlp = markExternalPath(xnode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          int ylp = markExternalPath(ynode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+          return;
+        }
+      }
+
+      std::vector<Arc> ppath;
+      findPilePath(ppath, root, type_map, order_map, node_data, arc_lists);
+
+      // Minor-D
+      if (!ppath.empty()) {
+        markFacePath(ynode, xnode, order_map, node_data);
+        markPertinentPath(wnode, order_map, node_data, arc_lists,
+                          embed_arc, merge_roots);
+        markPilePath(ppath);
+        markInternalPath(ipath);
+        int xlp = markExternalPath(xnode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+        int ylp = markExternalPath(ynode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+        markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+        return;
+      }
+
+      // Minor-E*
+      {
+
+        if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
+          Node znode = findExternal(pynode, rorder, order_map,
+                                    child_lists, ancestor_map,
+                                    low_map, node_data);
+
+          if (type_map[znode] == LOWY) {
+            markFacePath(root, xnode, order_map, node_data);
+            markPertinentPath(wnode, order_map, node_data, arc_lists,
+                              embed_arc, merge_roots);
+            markInternalPath(ipath);
+            int xlp = markExternalPath(xnode, order_map, child_lists,
+                                       pred_map, ancestor_map, low_map);
+            int zlp = markExternalPath(znode, order_map, child_lists,
+                                       pred_map, ancestor_map, low_map);
+            markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
+          } else {
+            markFacePath(ynode, root, order_map, node_data);
+            markPertinentPath(wnode, order_map, node_data, arc_lists,
+                              embed_arc, merge_roots);
+            markInternalPath(ipath);
+            int ylp = markExternalPath(ynode, order_map, child_lists,
+                                       pred_map, ancestor_map, low_map);
+            int zlp = markExternalPath(znode, order_map, child_lists,
+                                       pred_map, ancestor_map, low_map);
+            markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
+          }
+          return;
+        }
+
+        int xlp = markExternalPath(xnode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+        int ylp = markExternalPath(ynode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+        int wlp = markExternalPath(wnode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+
+        if (wlp > xlp && wlp > ylp) {
+          markFacePath(root, root, order_map, node_data);
+          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+          return;
+        }
+
+        markInternalPath(ipath);
+        markPertinentPath(wnode, order_map, node_data, arc_lists,
+                          embed_arc, merge_roots);
+
+        if (xlp > ylp && xlp > wlp) {
+          markFacePath(root, pynode, order_map, node_data);
+          markFacePath(wnode, xnode, order_map, node_data);
+          markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
+          return;
+        }
+
+        if (ylp > xlp && ylp > wlp) {
+          markFacePath(pxnode, root, order_map, node_data);
+          markFacePath(ynode, wnode, order_map, node_data);
+          markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
+          return;
+        }
+
+        if (pynode != ynode) {
+          markFacePath(pxnode, wnode, order_map, node_data);
+
+          int minlp = xlp < ylp ? xlp : ylp;
+          if (wlp < minlp) minlp = wlp;
+
+          int maxlp = xlp > ylp ? xlp : ylp;
+          if (wlp > maxlp) maxlp = wlp;
+
+          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
+          return;
+        }
+
+        if (pxnode != xnode) {
+          markFacePath(wnode, pynode, order_map, node_data);
+
+          int minlp = xlp < ylp ? xlp : ylp;
+          if (wlp < minlp) minlp = wlp;
+
+          int maxlp = xlp > ylp ? xlp : ylp;
+          if (wlp > maxlp) maxlp = wlp;
+
+          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
+          return;
+        }
+
+        markFacePath(root, root, order_map, node_data);
+        int minlp = xlp < ylp ? xlp : ylp;
+        if (wlp < minlp) minlp = wlp;
+        markPredPath(root, order_list[minlp], pred_map);
+        return;
+      }
+
+    }
+
+  };
+
+  namespace _planarity_bits {
+
+    template <typename Graph, typename EmbeddingMap>
+    void makeConnected(Graph& graph, EmbeddingMap& embedding) {
+      DfsVisitor<Graph> null_visitor;
+      DfsVisit<Graph, DfsVisitor<Graph> > dfs(graph, null_visitor);
+      dfs.init();
+
+      typename Graph::Node u = INVALID;
+      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+        if (!dfs.reached(n)) {
+          dfs.addSource(n);
+          dfs.start();
+          if (u == INVALID) {
+            u = n;
+          } else {
+            typename Graph::Node v = n;
+
+            typename Graph::Arc ue = typename Graph::OutArcIt(graph, u);
+            typename Graph::Arc ve = typename Graph::OutArcIt(graph, v);
+
+            typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true);
+
+            if (ue != INVALID) {
+              embedding[e] = embedding[ue];
+              embedding[ue] = e;
+            } else {
+              embedding[e] = e;
+            }
+
+            if (ve != INVALID) {
+              embedding[graph.oppositeArc(e)] = embedding[ve];
+              embedding[ve] = graph.oppositeArc(e);
+            } else {
+              embedding[graph.oppositeArc(e)] = graph.oppositeArc(e);
+            }
+          }
+        }
+      }
+    }
+
+    template <typename Graph, typename EmbeddingMap>
+    void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) {
+      typename Graph::template ArcMap<bool> processed(graph);
+
+      std::vector<typename Graph::Arc> arcs;
+      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
+        arcs.push_back(e);
+      }
+
+      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
+
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        typename Graph::Arc pp = arcs[i];
+        if (processed[pp]) continue;
+
+        typename Graph::Arc e = embedding[graph.oppositeArc(pp)];
+        processed[e] = true;
+        visited.set(graph.source(e), true);
+
+        typename Graph::Arc p = e, l = e;
+        e = embedding[graph.oppositeArc(e)];
+
+        while (e != l) {
+          processed[e] = true;
+
+          if (visited[graph.source(e)]) {
+
+            typename Graph::Arc n =
+              graph.direct(graph.addEdge(graph.source(p),
+                                           graph.target(e)), true);
+            embedding[n] = p;
+            embedding[graph.oppositeArc(pp)] = n;
+
+            embedding[graph.oppositeArc(n)] =
+              embedding[graph.oppositeArc(e)];
+            embedding[graph.oppositeArc(e)] =
+              graph.oppositeArc(n);
+
+            p = n;
+            e = embedding[graph.oppositeArc(n)];
+          } else {
+            visited.set(graph.source(e), true);
+            pp = p;
+            p = e;
+            e = embedding[graph.oppositeArc(e)];
+          }
+        }
+        visited.setAll(false);
+      }
+    }
+
+
+    template <typename Graph, typename EmbeddingMap>
+    void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) {
+
+      typename Graph::template NodeMap<int> degree(graph);
+
+      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+        degree[n] = countIncEdges(graph, n);
+      }
+
+      typename Graph::template ArcMap<bool> processed(graph);
+      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
+
+      std::vector<typename Graph::Arc> arcs;
+      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
+        arcs.push_back(e);
+      }
+
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        typename Graph::Arc e = arcs[i];
+
+        if (processed[e]) continue;
+        processed[e] = true;
+
+        typename Graph::Arc mine = e;
+        int mind = degree[graph.source(e)];
+
+        int face_size = 1;
+
+        typename Graph::Arc l = e;
+        e = embedding[graph.oppositeArc(e)];
+        while (l != e) {
+          processed[e] = true;
+
+          ++face_size;
+
+          if (degree[graph.source(e)] < mind) {
+            mine = e;
+            mind = degree[graph.source(e)];
+          }
+
+          e = embedding[graph.oppositeArc(e)];
+        }
+
+        if (face_size < 4) {
+          continue;
+        }
+
+        typename Graph::Node s = graph.source(mine);
+        for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) {
+          visited.set(graph.target(e), true);
+        }
+
+        typename Graph::Arc oppe = INVALID;
+
+        e = embedding[graph.oppositeArc(mine)];
+        e = embedding[graph.oppositeArc(e)];
+        while (graph.target(e) != s) {
+          if (visited[graph.source(e)]) {
+            oppe = e;
+            break;
+          }
+          e = embedding[graph.oppositeArc(e)];
+        }
+        visited.setAll(false);
+
+        if (oppe == INVALID) {
+
+          e = embedding[graph.oppositeArc(mine)];
+          typename Graph::Arc pn = mine, p = e;
+
+          e = embedding[graph.oppositeArc(e)];
+          while (graph.target(e) != s) {
+            typename Graph::Arc n =
+              graph.direct(graph.addEdge(s, graph.source(e)), true);
+
+            embedding[n] = pn;
+            embedding[graph.oppositeArc(n)] = e;
+            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
+
+            pn = n;
+
+            p = e;
+            e = embedding[graph.oppositeArc(e)];
+          }
+
+          embedding[graph.oppositeArc(e)] = pn;
+
+        } else {
+
+          mine = embedding[graph.oppositeArc(mine)];
+          s = graph.source(mine);
+          oppe = embedding[graph.oppositeArc(oppe)];
+          typename Graph::Node t = graph.source(oppe);
+
+          typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true);
+          embedding[ce] = mine;
+          embedding[graph.oppositeArc(ce)] = oppe;
+
+          typename Graph::Arc pn = ce, p = oppe;
+          e = embedding[graph.oppositeArc(oppe)];
+          while (graph.target(e) != s) {
+            typename Graph::Arc n =
+              graph.direct(graph.addEdge(s, graph.source(e)), true);
+
+            embedding[n] = pn;
+            embedding[graph.oppositeArc(n)] = e;
+            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
+
+            pn = n;
+
+            p = e;
+            e = embedding[graph.oppositeArc(e)];
+
+          }
+          embedding[graph.oppositeArc(e)] = pn;
+
+          pn = graph.oppositeArc(ce), p = mine;
+          e = embedding[graph.oppositeArc(mine)];
+          while (graph.target(e) != t) {
+            typename Graph::Arc n =
+              graph.direct(graph.addEdge(t, graph.source(e)), true);
+
+            embedding[n] = pn;
+            embedding[graph.oppositeArc(n)] = e;
+            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
+
+            pn = n;
+
+            p = e;
+            e = embedding[graph.oppositeArc(e)];
+
+          }
+          embedding[graph.oppositeArc(e)] = pn;
+        }
+      }
+    }
+
+  }
+
+  /// \ingroup planar
+  ///
+  /// \brief Schnyder's planar drawing algorithm
+  ///
+  /// The planar drawing algorithm calculates positions for the nodes
+  /// in the plane. These coordinates satisfy that if the edges are
+  /// represented with straight lines, then they will not intersect
+  /// each other.
+  ///
+  /// Scnyder's algorithm embeds the graph on an \c (n-2)x(n-2) size grid,
+  /// i.e. each node will be located in the \c [0..n-2]x[0..n-2] square.
+  /// The time complexity of the algorithm is O(n).
+  ///
+  /// \see PlanarEmbedding
+  template <typename Graph>
+  class PlanarDrawing {
+  public:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    /// \brief The point type for storing coordinates
+    typedef dim2::Point<int> Point;
+    /// \brief The map type for storing the coordinates of the nodes
+    typedef typename Graph::template NodeMap<Point> PointMap;
+
+
+    /// \brief Constructor
+    ///
+    /// Constructor
+    /// \pre The graph must be simple, i.e. it should not
+    /// contain parallel or loop arcs.
+    PlanarDrawing(const Graph& graph)
+      : _graph(graph), _point_map(graph) {}
+
+  private:
+
+    template <typename AuxGraph, typename AuxEmbeddingMap>
+    void drawing(const AuxGraph& graph,
+                 const AuxEmbeddingMap& next,
+                 PointMap& point_map) {
+      TEMPLATE_GRAPH_TYPEDEFS(AuxGraph);
+
+      typename AuxGraph::template ArcMap<Arc> prev(graph);
+
+      for (NodeIt n(graph); n != INVALID; ++n) {
+        Arc e = OutArcIt(graph, n);
+
+        Arc p = e, l = e;
+
+        e = next[e];
+        while (e != l) {
+          prev[e] = p;
+          p = e;
+          e = next[e];
+        }
+        prev[e] = p;
+      }
+
+      Node anode, bnode, cnode;
+
+      {
+        Arc e = ArcIt(graph);
+        anode = graph.source(e);
+        bnode = graph.target(e);
+        cnode = graph.target(next[graph.oppositeArc(e)]);
+      }
+
+      IterableBoolMap<AuxGraph, Node> proper(graph, false);
+      typename AuxGraph::template NodeMap<int> conn(graph, -1);
+
+      conn[anode] = conn[bnode] = -2;
+      {
+        for (OutArcIt e(graph, anode); e != INVALID; ++e) {
+          Node m = graph.target(e);
+          if (conn[m] == -1) {
+            conn[m] = 1;
+          }
+        }
+        conn[cnode] = 2;
+
+        for (OutArcIt e(graph, bnode); e != INVALID; ++e) {
+          Node m = graph.target(e);
+          if (conn[m] == -1) {
+            conn[m] = 1;
+          } else if (conn[m] != -2) {
+            conn[m] += 1;
+            Arc pe = graph.oppositeArc(e);
+            if (conn[graph.target(next[pe])] == -2) {
+              conn[m] -= 1;
+            }
+            if (conn[graph.target(prev[pe])] == -2) {
+              conn[m] -= 1;
+            }
+
+            proper.set(m, conn[m] == 1);
+          }
+        }
+      }
+
+
+      typename AuxGraph::template ArcMap<int> angle(graph, -1);
+
+      while (proper.trueNum() != 0) {
+        Node n = typename IterableBoolMap<AuxGraph, Node>::TrueIt(proper);
+        proper.set(n, false);
+        conn[n] = -2;
+
+        for (OutArcIt e(graph, n); e != INVALID; ++e) {
+          Node m = graph.target(e);
+          if (conn[m] == -1) {
+            conn[m] = 1;
+          } else if (conn[m] != -2) {
+            conn[m] += 1;
+            Arc pe = graph.oppositeArc(e);
+            if (conn[graph.target(next[pe])] == -2) {
+              conn[m] -= 1;
+            }
+            if (conn[graph.target(prev[pe])] == -2) {
+              conn[m] -= 1;
+            }
+
+            proper.set(m, conn[m] == 1);
+          }
+        }
+
+        {
+          Arc e = OutArcIt(graph, n);
+          Arc p = e, l = e;
+
+          e = next[e];
+          while (e != l) {
+
+            if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
+              Arc f = e;
+              angle[f] = 0;
+              f = next[graph.oppositeArc(f)];
+              angle[f] = 1;
+              f = next[graph.oppositeArc(f)];
+              angle[f] = 2;
+            }
+
+            p = e;
+            e = next[e];
+          }
+
+          if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
+            Arc f = e;
+            angle[f] = 0;
+            f = next[graph.oppositeArc(f)];
+            angle[f] = 1;
+            f = next[graph.oppositeArc(f)];
+            angle[f] = 2;
+          }
+        }
+      }
+
+      typename AuxGraph::template NodeMap<Node> apred(graph, INVALID);
+      typename AuxGraph::template NodeMap<Node> bpred(graph, INVALID);
+      typename AuxGraph::template NodeMap<Node> cpred(graph, INVALID);
+
+      typename AuxGraph::template NodeMap<int> apredid(graph, -1);
+      typename AuxGraph::template NodeMap<int> bpredid(graph, -1);
+      typename AuxGraph::template NodeMap<int> cpredid(graph, -1);
+
+      for (ArcIt e(graph); e != INVALID; ++e) {
+        if (angle[e] == angle[next[e]]) {
+          switch (angle[e]) {
+          case 2:
+            apred[graph.target(e)] = graph.source(e);
+            apredid[graph.target(e)] = graph.id(graph.source(e));
+            break;
+          case 1:
+            bpred[graph.target(e)] = graph.source(e);
+            bpredid[graph.target(e)] = graph.id(graph.source(e));
+            break;
+          case 0:
+            cpred[graph.target(e)] = graph.source(e);
+            cpredid[graph.target(e)] = graph.id(graph.source(e));
+            break;
+          }
+        }
+      }
+
+      cpred[anode] = INVALID;
+      cpred[bnode] = INVALID;
+
+      std::vector<Node> aorder, border, corder;
+
+      {
+        typename AuxGraph::template NodeMap<bool> processed(graph, false);
+        std::vector<Node> st;
+        for (NodeIt n(graph); n != INVALID; ++n) {
+          if (!processed[n] && n != bnode && n != cnode) {
+            st.push_back(n);
+            processed[n] = true;
+            Node m = apred[n];
+            while (m != INVALID && !processed[m]) {
+              st.push_back(m);
+              processed[m] = true;
+              m = apred[m];
+            }
+            while (!st.empty()) {
+              aorder.push_back(st.back());
+              st.pop_back();
+            }
+          }
+        }
+      }
+
+      {
+        typename AuxGraph::template NodeMap<bool> processed(graph, false);
+        std::vector<Node> st;
+        for (NodeIt n(graph); n != INVALID; ++n) {
+          if (!processed[n] && n != cnode && n != anode) {
+            st.push_back(n);
+            processed[n] = true;
+            Node m = bpred[n];
+            while (m != INVALID && !processed[m]) {
+              st.push_back(m);
+              processed[m] = true;
+              m = bpred[m];
+            }
+            while (!st.empty()) {
+              border.push_back(st.back());
+              st.pop_back();
+            }
+          }
+        }
+      }
+
+      {
+        typename AuxGraph::template NodeMap<bool> processed(graph, false);
+        std::vector<Node> st;
+        for (NodeIt n(graph); n != INVALID; ++n) {
+          if (!processed[n] && n != anode && n != bnode) {
+            st.push_back(n);
+            processed[n] = true;
+            Node m = cpred[n];
+            while (m != INVALID && !processed[m]) {
+              st.push_back(m);
+              processed[m] = true;
+              m = cpred[m];
+            }
+            while (!st.empty()) {
+              corder.push_back(st.back());
+              st.pop_back();
+            }
+          }
+        }
+      }
+
+      typename AuxGraph::template NodeMap<int> atree(graph, 0);
+      for (int i = aorder.size() - 1; i >= 0; --i) {
+        Node n = aorder[i];
+        atree[n] = 1;
+        for (OutArcIt e(graph, n); e != INVALID; ++e) {
+          if (apred[graph.target(e)] == n) {
+            atree[n] += atree[graph.target(e)];
+          }
+        }
+      }
+
+      typename AuxGraph::template NodeMap<int> btree(graph, 0);
+      for (int i = border.size() - 1; i >= 0; --i) {
+        Node n = border[i];
+        btree[n] = 1;
+        for (OutArcIt e(graph, n); e != INVALID; ++e) {
+          if (bpred[graph.target(e)] == n) {
+            btree[n] += btree[graph.target(e)];
+          }
+        }
+      }
+
+      typename AuxGraph::template NodeMap<int> apath(graph, 0);
+      apath[bnode] = apath[cnode] = 1;
+      typename AuxGraph::template NodeMap<int> apath_btree(graph, 0);
+      apath_btree[bnode] = btree[bnode];
+      for (int i = 1; i < int(aorder.size()); ++i) {
+        Node n = aorder[i];
+        apath[n] = apath[apred[n]] + 1;
+        apath_btree[n] = btree[n] + apath_btree[apred[n]];
+      }
+
+      typename AuxGraph::template NodeMap<int> bpath_atree(graph, 0);
+      bpath_atree[anode] = atree[anode];
+      for (int i = 1; i < int(border.size()); ++i) {
+        Node n = border[i];
+        bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
+      }
+
+      typename AuxGraph::template NodeMap<int> cpath(graph, 0);
+      cpath[anode] = cpath[bnode] = 1;
+      typename AuxGraph::template NodeMap<int> cpath_atree(graph, 0);
+      cpath_atree[anode] = atree[anode];
+      typename AuxGraph::template NodeMap<int> cpath_btree(graph, 0);
+      cpath_btree[bnode] = btree[bnode];
+      for (int i = 1; i < int(corder.size()); ++i) {
+        Node n = corder[i];
+        cpath[n] = cpath[cpred[n]] + 1;
+        cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
+        cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
+      }
+
+      typename AuxGraph::template NodeMap<int> third(graph);
+      for (NodeIt n(graph); n != INVALID; ++n) {
+        point_map[n].x =
+          bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
+        point_map[n].y =
+          cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
+      }
+
+    }
+
+  public:
+
+    /// \brief Calculate the node positions
+    ///
+    /// This function calculates the node positions on the plane.
+    /// \return \c true if the graph is planar.
+    bool run() {
+      PlanarEmbedding<Graph> pe(_graph);
+      if (!pe.run()) return false;
+
+      run(pe);
+      return true;
+    }
+
+    /// \brief Calculate the node positions according to a
+    /// combinatorical embedding
+    ///
+    /// This function calculates the node positions on the plane.
+    /// The given \c embedding map should contain a valid combinatorical
+    /// embedding, i.e. a valid cyclic order of the arcs.
+    /// It can be computed using PlanarEmbedding.
+    template <typename EmbeddingMap>
+    void run(const EmbeddingMap& embedding) {
+      typedef SmartEdgeSet<Graph> AuxGraph;
+
+      if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
+        drawing(_graph, embedding, _point_map);
+        return;
+      }
+
+      AuxGraph aux_graph(_graph);
+      typename AuxGraph::template ArcMap<typename AuxGraph::Arc>
+        aux_embedding(aux_graph);
+
+      {
+
+        typename Graph::template EdgeMap<typename AuxGraph::Edge>
+          ref(_graph);
+
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e));
+        }
+
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          Arc ee = embedding[_graph.direct(e, true)];
+          aux_embedding[aux_graph.direct(ref[e], true)] =
+            aux_graph.direct(ref[ee], _graph.direction(ee));
+          ee = embedding[_graph.direct(e, false)];
+          aux_embedding[aux_graph.direct(ref[e], false)] =
+            aux_graph.direct(ref[ee], _graph.direction(ee));
+        }
+      }
+      _planarity_bits::makeConnected(aux_graph, aux_embedding);
+      _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding);
+      _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding);
+      drawing(aux_graph, aux_embedding, _point_map);
+    }
+
+    /// \brief The coordinate of the given node
+    ///
+    /// This function returns the coordinate of the given node.
+    Point operator[](const Node& node) const {
+      return _point_map[node];
+    }
+
+    /// \brief Return the grid embedding in a node map
+    ///
+    /// This function returns the grid embedding in a node map of
+    /// \c dim2::Point<int> coordinates.
+    const PointMap& coords() const {
+      return _point_map;
+    }
+
+  private:
+
+    const Graph& _graph;
+    PointMap _point_map;
+
+  };
+
+  namespace _planarity_bits {
+
+    template <typename ColorMap>
+    class KempeFilter {
+    public:
+      typedef typename ColorMap::Key Key;
+      typedef bool Value;
+
+      KempeFilter(const ColorMap& color_map,
+                  const typename ColorMap::Value& first,
+                  const typename ColorMap::Value& second)
+        : _color_map(color_map), _first(first), _second(second) {}
+
+      Value operator[](const Key& key) const {
+        return _color_map[key] == _first || _color_map[key] == _second;
+      }
+
+    private:
+      const ColorMap& _color_map;
+      typename ColorMap::Value _first, _second;
+    };
+  }
+
+  /// \ingroup planar
+  ///
+  /// \brief Coloring planar graphs
+  ///
+  /// The graph coloring problem is the coloring of the graph nodes
+  /// so that there are no adjacent nodes with the same color. The
+  /// planar graphs can always be colored with four colors, which is
+  /// proved by Appel and Haken. Their proofs provide a quadratic
+  /// time algorithm for four coloring, but it could not be used to
+  /// implement an efficient algorithm. The five and six coloring can be
+  /// made in linear time, but in this class, the five coloring has
+  /// quadratic worst case time complexity. The two coloring (if
+  /// possible) is solvable with a graph search algorithm and it is
+  /// implemented in \ref bipartitePartitions() function in LEMON. To
+  /// decide whether a planar graph is three colorable is NP-complete.
+  ///
+  /// This class contains member functions for calculate colorings
+  /// with five and six colors. The six coloring algorithm is a simple
+  /// greedy coloring on the backward minimum outgoing order of nodes.
+  /// This order can be computed by selecting the node with least
+  /// outgoing arcs to unprocessed nodes in each phase. This order
+  /// guarantees that when a node is chosen for coloring it has at
+  /// most five already colored adjacents. The five coloring algorithm
+  /// use the same method, but if the greedy approach fails to color
+  /// with five colors, i.e. the node has five already different
+  /// colored neighbours, it swaps the colors in one of the connected
+  /// two colored sets with the Kempe recoloring method.
+  template <typename Graph>
+  class PlanarColoring {
+  public:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    /// \brief The map type for storing color indices
+    typedef typename Graph::template NodeMap<int> IndexMap;
+    /// \brief The map type for storing colors
+    ///
+    /// The map type for storing colors.
+    /// \see Palette, Color
+    typedef ComposeMap<Palette, IndexMap> ColorMap;
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \pre The graph must be simple, i.e. it should not
+    /// contain parallel or loop arcs.
+    PlanarColoring(const Graph& graph)
+      : _graph(graph), _color_map(graph), _palette(0) {
+      _palette.add(Color(1,0,0));
+      _palette.add(Color(0,1,0));
+      _palette.add(Color(0,0,1));
+      _palette.add(Color(1,1,0));
+      _palette.add(Color(1,0,1));
+      _palette.add(Color(0,1,1));
+    }
+
+    /// \brief Return the node map of color indices
+    ///
+    /// This function returns the node map of color indices. The values are
+    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
+    IndexMap colorIndexMap() const {
+      return _color_map;
+    }
+
+    /// \brief Return the node map of colors
+    ///
+    /// This function returns the node map of colors. The values are among
+    /// five or six distinct \ref lemon::Color "colors".
+    ColorMap colorMap() const {
+      return composeMap(_palette, _color_map);
+    }
+
+    /// \brief Return the color index of the node
+    ///
+    /// This function returns the color index of the given node. The value is
+    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
+    int colorIndex(const Node& node) const {
+      return _color_map[node];
+    }
+
+    /// \brief Return the color of the node
+    ///
+    /// This function returns the color of the given node. The value is among
+    /// five or six distinct \ref lemon::Color "colors".
+    Color color(const Node& node) const {
+      return _palette[_color_map[node]];
+    }
+
+
+    /// \brief Calculate a coloring with at most six colors
+    ///
+    /// This function calculates a coloring with at most six colors. The time
+    /// complexity of this variant is linear in the size of the graph.
+    /// \return \c true if the algorithm could color the graph with six colors.
+    /// If the algorithm fails, then the graph is not planar.
+    /// \note This function can return \c true if the graph is not
+    /// planar, but it can be colored with at most six colors.
+    bool runSixColoring() {
+
+      typename Graph::template NodeMap<int> heap_index(_graph, -1);
+      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _color_map[n] = -2;
+        heap.push(n, countOutArcs(_graph, n));
+      }
+
+      std::vector<Node> order;
+
+      while (!heap.empty()) {
+        Node n = heap.top();
+        heap.pop();
+        _color_map[n] = -1;
+        order.push_back(n);
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node t = _graph.runningNode(e);
+          if (_color_map[t] == -2) {
+            heap.decrease(t, heap[t] - 1);
+          }
+        }
+      }
+
+      for (int i = order.size() - 1; i >= 0; --i) {
+        std::vector<bool> forbidden(6, false);
+        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
+          Node t = _graph.runningNode(e);
+          if (_color_map[t] != -1) {
+            forbidden[_color_map[t]] = true;
+          }
+        }
+               for (int k = 0; k < 6; ++k) {
+          if (!forbidden[k]) {
+            _color_map[order[i]] = k;
+            break;
+          }
+        }
+        if (_color_map[order[i]] == -1) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+  private:
+
+    bool recolor(const Node& u, const Node& v) {
+      int ucolor = _color_map[u];
+      int vcolor = _color_map[v];
+      typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
+      KempeFilter filter(_color_map, ucolor, vcolor);
+
+      typedef FilterNodes<const Graph, const KempeFilter> KempeGraph;
+      KempeGraph kempe_graph(_graph, filter);
+
+      std::vector<Node> comp;
+      Bfs<KempeGraph> bfs(kempe_graph);
+      bfs.init();
+      bfs.addSource(u);
+      while (!bfs.emptyQueue()) {
+        Node n = bfs.nextNode();
+        if (n == v) return false;
+        comp.push_back(n);
+        bfs.processNextNode();
+      }
+
+      int scolor = ucolor + vcolor;
+      for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
+        _color_map[comp[i]] = scolor - _color_map[comp[i]];
+      }
+
+      return true;
+    }
+
+    template <typename EmbeddingMap>
+    void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
+      std::vector<Node> nodes;
+      nodes.reserve(4);
+
+      for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) {
+        Node t = _graph.target(e);
+        if (_color_map[t] != -1) {
+          nodes.push_back(t);
+          if (nodes.size() == 4) break;
+        }
+      }
+
+      int color = _color_map[nodes[0]];
+      if (recolor(nodes[0], nodes[2])) {
+        _color_map[node] = color;
+      } else {
+        color = _color_map[nodes[1]];
+        recolor(nodes[1], nodes[3]);
+        _color_map[node] = color;
+      }
+    }
+
+  public:
+
+    /// \brief Calculate a coloring with at most five colors
+    ///
+    /// This function calculates a coloring with at most five
+    /// colors. The worst case time complexity of this variant is
+    /// quadratic in the size of the graph.
+    /// \param embedding This map should contain a valid combinatorical
+    /// embedding, i.e. a valid cyclic order of the arcs.
+    /// It can be computed using PlanarEmbedding.
+    template <typename EmbeddingMap>
+    void runFiveColoring(const EmbeddingMap& embedding) {
+
+      typename Graph::template NodeMap<int> heap_index(_graph, -1);
+      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _color_map[n] = -2;
+        heap.push(n, countOutArcs(_graph, n));
+      }
+
+      std::vector<Node> order;
+
+      while (!heap.empty()) {
+        Node n = heap.top();
+        heap.pop();
+        _color_map[n] = -1;
+        order.push_back(n);
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node t = _graph.runningNode(e);
+          if (_color_map[t] == -2) {
+            heap.decrease(t, heap[t] - 1);
+          }
+        }
+      }
+
+      for (int i = order.size() - 1; i >= 0; --i) {
+        std::vector<bool> forbidden(5, false);
+        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
+          Node t = _graph.runningNode(e);
+          if (_color_map[t] != -1) {
+            forbidden[_color_map[t]] = true;
+          }
+        }
+        for (int k = 0; k < 5; ++k) {
+          if (!forbidden[k]) {
+            _color_map[order[i]] = k;
+            break;
+          }
+        }
+        if (_color_map[order[i]] == -1) {
+          kempeRecoloring(order[i], embedding);
+        }
+      }
+    }
+
+    /// \brief Calculate a coloring with at most five colors
+    ///
+    /// This function calculates a coloring with at most five
+    /// colors. The worst case time complexity of this variant is
+    /// quadratic in the size of the graph.
+    /// \return \c true if the graph is planar.
+    bool runFiveColoring() {
+      PlanarEmbedding<Graph> pe(_graph);
+      if (!pe.run()) return false;
+
+      runFiveColoring(pe.embeddingMap());
+      return true;
+    }
+
+  private:
+
+    const Graph& _graph;
+    IndexMap _color_map;
+    Palette _palette;
+  };
+
+}
+
+#endif
diff --git a/lemon/preflow.h b/lemon/preflow.h
new file mode 100644
index 0000000..28ccd67
--- /dev/null
+++ b/lemon/preflow.h
@@ -0,0 +1,985 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_PREFLOW_H
+#define LEMON_PREFLOW_H
+
+#include <lemon/tolerance.h>
+#include <lemon/elevator.h>
+
+/// \file
+/// \ingroup max_flow
+/// \brief Implementation of the preflow algorithm.
+
+namespace lemon {
+
+  /// \brief Default traits class of Preflow class.
+  ///
+  /// Default traits class of Preflow class.
+  /// \tparam GR Digraph type.
+  /// \tparam CAP Capacity map type.
+  template <typename GR, typename CAP>
+  struct PreflowDefaultTraits {
+
+    /// \brief The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc capacities.
+    ///
+    /// The type of the map that stores the arc capacities.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef CAP CapacityMap;
+
+    /// \brief The type of the flow values.
+    typedef typename CapacityMap::Value Value;
+
+    /// \brief The type of the map that stores the flow values.
+    ///
+    /// The type of the map that stores the flow values.
+    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+#ifdef DOXYGEN
+    typedef GR::ArcMap<Value> FlowMap;
+#else
+    typedef typename Digraph::template ArcMap<Value> FlowMap;
+#endif
+
+    /// \brief Instantiates a FlowMap.
+    ///
+    /// This function instantiates a \ref FlowMap.
+    /// \param digraph The digraph for which we would like to define
+    /// the flow map.
+    static FlowMap* createFlowMap(const Digraph& digraph) {
+      return new FlowMap(digraph);
+    }
+
+    /// \brief The elevator type used by Preflow algorithm.
+    ///
+    /// The elevator type used by Preflow algorithm.
+    ///
+    /// \sa Elevator, LinkedElevator
+#ifdef DOXYGEN
+    typedef lemon::Elevator<GR, GR::Node> Elevator;
+#else
+    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
+#endif
+
+    /// \brief Instantiates an Elevator.
+    ///
+    /// This function instantiates an \ref Elevator.
+    /// \param digraph The digraph for which we would like to define
+    /// the elevator.
+    /// \param max_level The maximum level of the elevator.
+    static Elevator* createElevator(const Digraph& digraph, int max_level) {
+      return new Elevator(digraph, max_level);
+    }
+
+    /// \brief The tolerance used by the algorithm
+    ///
+    /// The tolerance used by the algorithm to handle inexact computation.
+    typedef lemon::Tolerance<Value> Tolerance;
+
+  };
+
+
+  /// \ingroup max_flow
+  ///
+  /// \brief %Preflow algorithm class.
+  ///
+  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
+  /// \e push-relabel algorithm producing a \ref max_flow
+  /// "flow of maximum value" in a digraph \cite clrs01algorithms,
+  /// \cite amo93networkflows, \cite goldberg88newapproach.
+  /// The preflow algorithms are the fastest known maximum
+  /// flow algorithms. The current implementation uses a mixture of the
+  /// \e "highest label" and the \e "bound decrease" heuristics.
+  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{m})\f$.
+  ///
+  /// The algorithm consists of two phases. After the first phase
+  /// the maximum flow value and the minimum cut is obtained. The
+  /// second phase constructs a feasible maximum flow on each arc.
+  ///
+  /// \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>
+#else
+  template <typename GR,
+            typename CAP = typename GR::template ArcMap<int>,
+            typename TR = PreflowDefaultTraits<GR, CAP> >
+#endif
+  class Preflow {
+  public:
+
+    ///The \ref lemon::PreflowDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
+    ///The type of the digraph the algorithm runs on.
+    typedef typename Traits::Digraph Digraph;
+    ///The type of the capacity map.
+    typedef typename Traits::CapacityMap CapacityMap;
+    ///The type of the flow values.
+    typedef typename Traits::Value Value;
+
+    ///The type of the flow map.
+    typedef typename Traits::FlowMap FlowMap;
+    ///The type of the elevator.
+    typedef typename Traits::Elevator Elevator;
+    ///The type of the tolerance.
+    typedef typename Traits::Tolerance Tolerance;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    const Digraph& _graph;
+    const CapacityMap* _capacity;
+
+    int _node_num;
+
+    Node _source, _target;
+
+    FlowMap* _flow;
+    bool _local_flow;
+
+    Elevator* _level;
+    bool _local_level;
+
+    typedef typename Digraph::template NodeMap<Value> ExcessMap;
+    ExcessMap* _excess;
+
+    Tolerance _tolerance;
+
+    bool _phase;
+
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_flow) {
+        _flow = Traits::createFlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_level) {
+        _level = Traits::createElevator(_graph, _node_num);
+        _local_level = true;
+      }
+      if (!_excess) {
+        _excess = new ExcessMap(_graph);
+      }
+    }
+
+    void destroyStructures() {
+      if (_local_flow) {
+        delete _flow;
+      }
+      if (_local_level) {
+        delete _level;
+      }
+      if (_excess) {
+        delete _excess;
+      }
+    }
+
+  public:
+
+    typedef Preflow Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <typename T>
+    struct SetFlowMapTraits : public Traits {
+      typedef T FlowMap;
+      static FlowMap *createFlowMap(const Digraph&) {
+        LEMON_ASSERT(false, "FlowMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// FlowMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting FlowMap
+    /// type.
+    template <typename T>
+    struct SetFlowMap
+      : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
+      typedef Preflow<Digraph, CapacityMap,
+                      SetFlowMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Digraph&, int) {
+        LEMON_ASSERT(false, "Elevator is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type. If this named parameter is used, then an external
+    /// elevator object must be passed to the algorithm using the
+    /// \ref elevator(Elevator&) "elevator()" function before calling
+    /// \ref run() or \ref init().
+    /// \sa SetStandardElevator
+    template <typename T>
+    struct SetElevator
+      : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
+      typedef Preflow<Digraph, CapacityMap,
+                      SetElevatorTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetStandardElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Digraph& digraph, int max_level) {
+        return new Elevator(digraph, max_level);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type with automatic allocation.
+    /// The Elevator should have standard constructor interface to be
+    /// able to automatically created by the algorithm (i.e. the
+    /// digraph and the maximum level should be passed to it).
+    /// However, an external elevator object could also be passed to the
+    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
+    /// before calling \ref run() or \ref init().
+    /// \sa SetElevator
+    template <typename T>
+    struct SetStandardElevator
+      : public Preflow<Digraph, CapacityMap,
+                       SetStandardElevatorTraits<T> > {
+      typedef Preflow<Digraph, CapacityMap,
+                      SetStandardElevatorTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    Preflow() {}
+
+  public:
+
+
+    /// \brief The constructor of the class.
+    ///
+    /// The constructor of the class.
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param capacity The capacity of the arcs.
+    /// \param source The source node.
+    /// \param target The target node.
+    Preflow(const Digraph& digraph, const CapacityMap& capacity,
+            Node source, Node target)
+      : _graph(digraph), _capacity(&capacity),
+        _node_num(0), _source(source), _target(target),
+        _flow(0), _local_flow(false),
+        _level(0), _local_level(false),
+        _excess(0), _tolerance(), _phase() {}
+
+    /// \brief Destructor.
+    ///
+    /// Destructor.
+    ~Preflow() {
+      destroyStructures();
+    }
+
+    /// \brief Sets the capacity map.
+    ///
+    /// Sets the capacity map.
+    /// \return <tt>(*this)</tt>
+    Preflow& capacityMap(const CapacityMap& map) {
+      _capacity = ↦
+      return *this;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    Preflow& flowMap(FlowMap& map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = ↦
+      return *this;
+    }
+
+    /// \brief Sets the source node.
+    ///
+    /// Sets the source node.
+    /// \return <tt>(*this)</tt>
+    Preflow& source(const Node& node) {
+      _source = node;
+      return *this;
+    }
+
+    /// \brief Sets the target node.
+    ///
+    /// Sets the target node.
+    /// \return <tt>(*this)</tt>
+    Preflow& target(const Node& node) {
+      _target = node;
+      return *this;
+    }
+
+    /// \brief Sets the elevator used by algorithm.
+    ///
+    /// Sets the elevator used by algorithm.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated elevator,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    Preflow& elevator(Elevator& elevator) {
+      if (_local_level) {
+        delete _level;
+        _local_level = false;
+      }
+      _level = &elevator;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the elevator.
+    ///
+    /// Returns a const reference to the elevator.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const Elevator& elevator() const {
+      return *_level;
+    }
+
+    /// \brief Sets the tolerance used by the algorithm.
+    ///
+    /// Sets the tolerance object used by the algorithm.
+    /// \return <tt>(*this)</tt>
+    Preflow& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// Returns a const reference to the tolerance object used by
+    /// the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the preflow algorithm is to use
+    /// \ref run() or \ref runMinCut().\n
+    /// If you need better control on the initial solution or the execution,
+    /// you have to call one of the \ref init() functions first, then
+    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to zero on each arc.
+    void init() {
+      createStructures();
+
+      _phase = true;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_excess)[n] = 0;
+      }
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _flow->set(e, 0);
+      }
+
+      typename Digraph::template NodeMap<bool> reached(_graph, false);
+
+      _level->initStart();
+      _level->initAddItem(_target);
+
+      std::vector<Node> queue;
+      reached[_source] = true;
+
+      queue.push_back(_target);
+      reached[_target] = true;
+      while (!queue.empty()) {
+        _level->initNewLevel();
+        std::vector<Node> nqueue;
+        for (int i = 0; i < int(queue.size()); ++i) {
+          Node n = queue[i];
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Node u = _graph.source(e);
+            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
+              reached[u] = true;
+              _level->initAddItem(u);
+              nqueue.push_back(u);
+            }
+          }
+        }
+        queue.swap(nqueue);
+      }
+      _level->initFinish();
+
+      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
+        if (_tolerance.positive((*_capacity)[e])) {
+          Node u = _graph.target(e);
+          if ((*_level)[u] == _level->maxLevel()) continue;
+          _flow->set(e, (*_capacity)[e]);
+          (*_excess)[u] += (*_capacity)[e];
+          if (u != _target && !_level->active(u)) {
+            _level->activate(u);
+          }
+        }
+      }
+    }
+
+    /// \brief Initializes the internal data structures using the
+    /// given flow map.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to the given \c flowMap. The \c flowMap should contain a
+    /// flow or at least a preflow, i.e. at each node excluding the
+    /// source node the incoming flow should greater or equal to the
+    /// outgoing flow.
+    /// \return \c false if the given \c flowMap is not a preflow.
+    template <typename FlowMap>
+    bool init(const FlowMap& flowMap) {
+      createStructures();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _flow->set(e, flowMap[e]);
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value excess = 0;
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          excess += (*_flow)[e];
+        }
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          excess -= (*_flow)[e];
+        }
+        if (excess < 0 && n != _source) return false;
+        (*_excess)[n] = excess;
+      }
+
+      typename Digraph::template NodeMap<bool> reached(_graph, false);
+
+      _level->initStart();
+      _level->initAddItem(_target);
+
+      std::vector<Node> queue;
+      reached[_source] = true;
+
+      queue.push_back(_target);
+      reached[_target] = true;
+      while (!queue.empty()) {
+        _level->initNewLevel();
+        std::vector<Node> nqueue;
+        for (int i = 0; i < int(queue.size()); ++i) {
+          Node n = queue[i];
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Node u = _graph.source(e);
+            if (!reached[u] &&
+                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
+              reached[u] = true;
+              _level->initAddItem(u);
+              nqueue.push_back(u);
+            }
+          }
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Node v = _graph.target(e);
+            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
+              reached[v] = true;
+              _level->initAddItem(v);
+              nqueue.push_back(v);
+            }
+          }
+        }
+        queue.swap(nqueue);
+      }
+      _level->initFinish();
+
+      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
+        Value rem = (*_capacity)[e] - (*_flow)[e];
+        if (_tolerance.positive(rem)) {
+          Node u = _graph.target(e);
+          if ((*_level)[u] == _level->maxLevel()) continue;
+          _flow->set(e, (*_capacity)[e]);
+          (*_excess)[u] += rem;
+        }
+      }
+      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
+        Value rem = (*_flow)[e];
+        if (_tolerance.positive(rem)) {
+          Node v = _graph.source(e);
+          if ((*_level)[v] == _level->maxLevel()) continue;
+          _flow->set(e, 0);
+          (*_excess)[v] += rem;
+        }
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n)
+        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
+          _level->activate(n);
+
+      return true;
+    }
+
+    /// \brief Starts the first phase of the preflow algorithm.
+    ///
+    /// The preflow algorithm consists of two phases, this method runs
+    /// the first phase. After the first phase the maximum flow value
+    /// and a minimum value cut can already be computed, although a
+    /// maximum flow is not yet obtained. So after calling this method
+    /// \ref flowValue() returns the value of a maximum flow and \ref
+    /// minCut() returns a minimum cut.
+    /// \pre One of the \ref init() functions must be called before
+    /// using this function.
+    void startFirstPhase() {
+      _phase = true;
+
+      while (true) {
+        int num = _node_num;
+
+        Node n = INVALID;
+        int level = -1;
+
+        while (num > 0) {
+          n = _level->highestActive();
+          if (n == INVALID) goto first_phase_done;
+          level = _level->highestActiveLevel();
+          --num;
+
+          Value excess = (*_excess)[n];
+          int new_level = _level->maxLevel();
+
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Value rem = (*_capacity)[e] - (*_flow)[e];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.target(e);
+            if ((*_level)[v] < level) {
+              if (!_level->active(v) && v != _target) {
+                _level->activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(e, (*_flow)[e] + excess);
+                (*_excess)[v] += excess;
+                excess = 0;
+                goto no_more_push_1;
+              } else {
+                excess -= rem;
+                (*_excess)[v] += rem;
+                _flow->set(e, (*_capacity)[e]);
+              }
+            } else if (new_level > (*_level)[v]) {
+              new_level = (*_level)[v];
+            }
+          }
+
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Value rem = (*_flow)[e];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.source(e);
+            if ((*_level)[v] < level) {
+              if (!_level->active(v) && v != _target) {
+                _level->activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(e, (*_flow)[e] - excess);
+                (*_excess)[v] += excess;
+                excess = 0;
+                goto no_more_push_1;
+              } else {
+                excess -= rem;
+                (*_excess)[v] += rem;
+                _flow->set(e, 0);
+              }
+            } else if (new_level > (*_level)[v]) {
+              new_level = (*_level)[v];
+            }
+          }
+
+        no_more_push_1:
+
+          (*_excess)[n] = excess;
+
+          if (excess != 0) {
+            if (new_level + 1 < _level->maxLevel()) {
+              _level->liftHighestActive(new_level + 1);
+            } else {
+              _level->liftHighestActiveToTop();
+            }
+            if (_level->emptyLevel(level)) {
+              _level->liftToTop(level);
+            }
+          } else {
+            _level->deactivate(n);
+          }
+        }
+
+        num = _node_num * 20;
+        while (num > 0) {
+          while (level >= 0 && _level->activeFree(level)) {
+            --level;
+          }
+          if (level == -1) {
+            n = _level->highestActive();
+            level = _level->highestActiveLevel();
+            if (n == INVALID) goto first_phase_done;
+          } else {
+            n = _level->activeOn(level);
+          }
+          --num;
+
+          Value excess = (*_excess)[n];
+          int new_level = _level->maxLevel();
+
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Value rem = (*_capacity)[e] - (*_flow)[e];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.target(e);
+            if ((*_level)[v] < level) {
+              if (!_level->active(v) && v != _target) {
+                _level->activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(e, (*_flow)[e] + excess);
+                (*_excess)[v] += excess;
+                excess = 0;
+                goto no_more_push_2;
+              } else {
+                excess -= rem;
+                (*_excess)[v] += rem;
+                _flow->set(e, (*_capacity)[e]);
+              }
+            } else if (new_level > (*_level)[v]) {
+              new_level = (*_level)[v];
+            }
+          }
+
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Value rem = (*_flow)[e];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.source(e);
+            if ((*_level)[v] < level) {
+              if (!_level->active(v) && v != _target) {
+                _level->activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(e, (*_flow)[e] - excess);
+                (*_excess)[v] += excess;
+                excess = 0;
+                goto no_more_push_2;
+              } else {
+                excess -= rem;
+                (*_excess)[v] += rem;
+                _flow->set(e, 0);
+              }
+            } else if (new_level > (*_level)[v]) {
+              new_level = (*_level)[v];
+            }
+          }
+
+        no_more_push_2:
+
+          (*_excess)[n] = excess;
+
+          if (excess != 0) {
+            if (new_level + 1 < _level->maxLevel()) {
+              _level->liftActiveOn(level, new_level + 1);
+            } else {
+              _level->liftActiveToTop(level);
+            }
+            if (_level->emptyLevel(level)) {
+              _level->liftToTop(level);
+            }
+          } else {
+            _level->deactivate(n);
+          }
+        }
+      }
+    first_phase_done:;
+    }
+
+    /// \brief Starts the second phase of the preflow algorithm.
+    ///
+    /// The preflow algorithm consists of two phases, this method runs
+    /// the second phase. After calling one of the \ref init() functions
+    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
+    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
+    /// value of a maximum flow, \ref minCut() returns a minimum cut
+    /// \pre One of the \ref init() functions and \ref startFirstPhase()
+    /// must be called before using this function.
+    void startSecondPhase() {
+      _phase = false;
+
+      typename Digraph::template NodeMap<bool> reached(_graph);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        reached[n] = (*_level)[n] < _level->maxLevel();
+      }
+
+      _level->initStart();
+      _level->initAddItem(_source);
+
+      std::vector<Node> queue;
+      queue.push_back(_source);
+      reached[_source] = true;
+
+      while (!queue.empty()) {
+        _level->initNewLevel();
+        std::vector<Node> nqueue;
+        for (int i = 0; i < int(queue.size()); ++i) {
+          Node n = queue[i];
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Node v = _graph.target(e);
+            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
+              reached[v] = true;
+              _level->initAddItem(v);
+              nqueue.push_back(v);
+            }
+          }
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Node u = _graph.source(e);
+            if (!reached[u] &&
+                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
+              reached[u] = true;
+              _level->initAddItem(u);
+              nqueue.push_back(u);
+            }
+          }
+        }
+        queue.swap(nqueue);
+      }
+      _level->initFinish();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (!reached[n]) {
+          _level->dirtyTopButOne(n);
+        } else if ((*_excess)[n] > 0 && _target != n) {
+          _level->activate(n);
+        }
+      }
+
+      Node n;
+      while ((n = _level->highestActive()) != INVALID) {
+        Value excess = (*_excess)[n];
+        int level = _level->highestActiveLevel();
+        int new_level = _level->maxLevel();
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Value rem = (*_capacity)[e] - (*_flow)[e];
+          if (!_tolerance.positive(rem)) continue;
+          Node v = _graph.target(e);
+          if ((*_level)[v] < level) {
+            if (!_level->active(v) && v != _source) {
+              _level->activate(v);
+            }
+            if (!_tolerance.less(rem, excess)) {
+              _flow->set(e, (*_flow)[e] + excess);
+              (*_excess)[v] += excess;
+              excess = 0;
+              goto no_more_push;
+            } else {
+              excess -= rem;
+              (*_excess)[v] += rem;
+              _flow->set(e, (*_capacity)[e]);
+            }
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Value rem = (*_flow)[e];
+          if (!_tolerance.positive(rem)) continue;
+          Node v = _graph.source(e);
+          if ((*_level)[v] < level) {
+            if (!_level->active(v) && v != _source) {
+              _level->activate(v);
+            }
+            if (!_tolerance.less(rem, excess)) {
+              _flow->set(e, (*_flow)[e] - excess);
+              (*_excess)[v] += excess;
+              excess = 0;
+              goto no_more_push;
+            } else {
+              excess -= rem;
+              (*_excess)[v] += rem;
+              _flow->set(e, 0);
+            }
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+      no_more_push:
+
+        (*_excess)[n] = excess;
+
+        if (excess != 0) {
+          if (new_level + 1 < _level->maxLevel()) {
+            _level->liftHighestActive(new_level + 1);
+          } else {
+            // Calculation error
+            _level->liftHighestActiveToTop();
+          }
+          if (_level->emptyLevel(level)) {
+            // Calculation error
+            _level->liftToTop(level);
+          }
+        } else {
+          _level->deactivate(n);
+        }
+
+      }
+    }
+
+    /// \brief Runs the preflow algorithm.
+    ///
+    /// Runs the preflow algorithm.
+    /// \note pf.run() is just a shortcut of the following code.
+    /// \code
+    ///   pf.init();
+    ///   pf.startFirstPhase();
+    ///   pf.startSecondPhase();
+    /// \endcode
+    void run() {
+      init();
+      startFirstPhase();
+      startSecondPhase();
+    }
+
+    /// \brief Runs the preflow algorithm to compute the minimum cut.
+    ///
+    /// Runs the preflow algorithm to compute the minimum cut.
+    /// \note pf.runMinCut() is just a shortcut of the following code.
+    /// \code
+    ///   pf.init();
+    ///   pf.startFirstPhase();
+    /// \endcode
+    void runMinCut() {
+      init();
+      startFirstPhase();
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the preflow algorithm can be obtained using these
+    /// functions.\n
+    /// Either one of the \ref run() "run*()" functions or one of the
+    /// \ref startFirstPhase() "start*()" functions should be called
+    /// before using them.
+
+    ///@{
+
+    /// \brief Returns the value of the maximum flow.
+    ///
+    /// Returns the value of the maximum flow by returning the excess
+    /// of the target node. This value equals to the value of
+    /// the maximum flow already after the first phase of the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flowValue() const {
+      return (*_excess)[_target];
+    }
+
+    /// \brief Returns the flow value on the given arc.
+    ///
+    /// Returns the flow value on the given arc. This method can
+    /// be called after the second phase of the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flow(const Arc& arc) const {
+      return (*_flow)[arc];
+    }
+
+    /// \brief Returns a const reference to the flow map.
+    ///
+    /// Returns a const reference to the arc map storing the found flow.
+    /// This method can be called after the second phase of the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const FlowMap& flowMap() const {
+      return *_flow;
+    }
+
+    /// \brief Returns \c true when the node is on the source side of the
+    /// minimum cut.
+    ///
+    /// Returns true when the node is on the source side of the found
+    /// minimum cut. This method can be called both after running \ref
+    /// startFirstPhase() and \ref startSecondPhase().
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    bool minCut(const Node& node) const {
+      return ((*_level)[node] == _level->maxLevel()) == _phase;
+    }
+
+    /// \brief Gives back a minimum value cut.
+    ///
+    /// Sets \c cutMap to the characteristic vector of a minimum value
+    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
+    /// node map with \c bool (or convertible) value type.
+    ///
+    /// This method can be called both after running \ref startFirstPhase()
+    /// and \ref startSecondPhase(). The result after the second phase
+    /// could be slightly different if inexact computation is used.
+    ///
+    /// \note This function calls \ref minCut() for each node, so it runs in
+    /// O(n) time.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    template <typename CutMap>
+    void minCutMap(CutMap& cutMap) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        cutMap.set(n, minCut(n));
+      }
+    }
+
+    /// @}
+  };
+}
+
+#endif
diff --git a/lemon/quad_heap.h b/lemon/quad_heap.h
new file mode 100644
index 0000000..27c50fd
--- /dev/null
+++ b/lemon/quad_heap.h
@@ -0,0 +1,343 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_QUAD_HEAP_H
+#define LEMON_QUAD_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Fourary (quaternary) heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Fourary (quaternary) heap data structure.
+  ///
+  /// This class implements the \e Fourary (\e quaternary) \e heap
+  /// data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The fourary heap is a specialization of the \ref DHeap "D-ary heap"
+  /// for <tt>D=4</tt>. It is similar to the \ref BinHeap "binary heap",
+  /// but its nodes have at most four children, instead of two.
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+  ///
+  ///\sa BinHeap
+  ///\sa DHeap
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class QuadHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    std::vector<Pair> _data;
+    Compare _comp;
+    ItemIntMap &_iim;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit QuadHeap(ItemIntMap &map) : _iim(map) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    QuadHeap(ItemIntMap &map, const Compare &comp)
+      : _iim(map), _comp(comp) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() { _data.clear(); }
+
+  private:
+    static int parent(int i) { return (i-1)/4; }
+    static int firstChild(int i) { return 4*i+1; }
+
+    bool less(const Pair &p1, const Pair &p2) const {
+      return _comp(p1.second, p2.second);
+    }
+
+    void bubbleUp(int hole, Pair p) {
+      int par = parent(hole);
+      while( hole>0 && less(p,_data[par]) ) {
+        move(_data[par],hole);
+        hole = par;
+        par = parent(hole);
+      }
+      move(p, hole);
+    }
+
+    void bubbleDown(int hole, Pair p, int length) {
+      if( length>1 ) {
+        int child = firstChild(hole);
+        while( child+3<length ) {
+          int min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( !less(_data[min], p) )
+            goto ok;
+          move(_data[min], hole);
+          hole = min;
+          child = firstChild(hole);
+        }
+        if ( child<length ) {
+          int min = child;
+          if( ++child<length && less(_data[child], _data[min]) ) min=child;
+          if( ++child<length && less(_data[child], _data[min]) ) min=child;
+          if( less(_data[min], p) ) {
+            move(_data[min], hole);
+            hole = min;
+          }
+        }
+      }
+    ok:
+      move(p, hole);
+    }
+
+    void move(const Pair &p, int i) {
+      _data[i] = p;
+      _iim.set(p.first, i);
+    }
+
+  public:
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair &p) {
+      int n = _data.size();
+      _data.resize(n+1);
+      bubbleUp(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[0].first; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[0].second; }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      int n = _data.size()-1;
+      _iim.set(_data[0].first, POST_HEAP);
+      if (n>0) bubbleDown(0, _data[n], n);
+      _data.pop_back();
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int h = _iim[i];
+      int n = _data.size()-1;
+      _iim.set(_data[h].first, POST_HEAP);
+      if( h<n ) {
+        if( less(_data[parent(h)], _data[n]) )
+          bubbleDown(h, _data[n], n);
+        else
+          bubbleUp(h, _data[n]);
+      }
+      _data.pop_back();
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].second;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if( idx < 0 )
+        push(i,p);
+      else if( _comp(p, _data[idx].second) )
+        bubbleUp(idx, Pair(i,p));
+      else
+        bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleUp(idx, Pair(i,p));
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int s = _iim[i];
+      if (s>=0) s=0;
+      return State(s);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+        case POST_HEAP:
+        case PRE_HEAP:
+          if (state(i) == IN_HEAP) erase(i);
+          _iim[i] = st;
+          break;
+        case IN_HEAP:
+          break;
+      }
+    }
+
+    /// \brief Replace an item in the heap.
+    ///
+    /// This function replaces item \c i with item \c j.
+    /// Item \c i must be in the heap, while \c j must be out of the heap.
+    /// After calling this method, item \c i will be out of the
+    /// heap and \c j will be in the heap with the same prioriority
+    /// as item \c i had before.
+    void replace(const Item& i, const Item& j) {
+      int idx = _iim[i];
+      _iim.set(i, _iim[j]);
+      _iim.set(j, idx);
+      _data[idx].first = j;
+    }
+
+  }; // class QuadHeap
+
+} // namespace lemon
+
+#endif // LEMON_FOURARY_HEAP_H
diff --git a/lemon/radix_heap.h b/lemon/radix_heap.h
new file mode 100644
index 0000000..8701ce7
--- /dev/null
+++ b/lemon/radix_heap.h
@@ -0,0 +1,438 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_RADIX_HEAP_H
+#define LEMON_RADIX_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Radix heap implementation.
+
+#include <vector>
+#include <lemon/error.h>
+
+namespace lemon {
+
+
+  /// \ingroup heaps
+  ///
+  /// \brief Radix heap data structure.
+  ///
+  /// This class implements the \e radix \e heap data structure.
+  /// It practically conforms to the \ref concepts::Heap "heap concept",
+  /// but it has some limitations due its special implementation.
+  /// The type of the priorities must be \c int and the priority of an
+  /// item cannot be decreased under the priority of the last removed item.
+  ///
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  template <typename IM>
+  class RadixHeap {
+
+  public:
+
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef int Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+
+    /// \brief Exception thrown by RadixHeap.
+    ///
+    /// This exception is thrown when an item is inserted into a
+    /// RadixHeap with a priority smaller than the last erased one.
+    /// \see RadixHeap
+    class PriorityUnderflowError : public Exception {
+    public:
+      virtual const char* what() const throw() {
+        return "lemon::RadixHeap::PriorityUnderflowError";
+      }
+    };
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+
+    struct RadixItem {
+      int prev, next, box;
+      Item item;
+      int prio;
+      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
+    };
+
+    struct RadixBox {
+      int first;
+      int min, size;
+      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
+    };
+
+    std::vector<RadixItem> _data;
+    std::vector<RadixBox> _boxes;
+
+    ItemIntMap &_iim;
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param minimum The initial minimum value of the heap.
+    /// \param capacity The initial capacity of the heap.
+    RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
+      : _iim(map)
+    {
+      _boxes.push_back(RadixBox(minimum, 1));
+      _boxes.push_back(RadixBox(minimum + 1, 1));
+      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
+        extend();
+      }
+    }
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    /// \param minimum The minimum value of the heap.
+    /// \param capacity The capacity of the heap.
+    void clear(int minimum = 0, int capacity = 0) {
+      _data.clear(); _boxes.clear();
+      _boxes.push_back(RadixBox(minimum, 1));
+      _boxes.push_back(RadixBox(minimum + 1, 1));
+      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
+        extend();
+      }
+    }
+
+  private:
+
+    bool upper(int box, Prio pr) {
+      return pr < _boxes[box].min;
+    }
+
+    bool lower(int box, Prio pr) {
+      return pr >= _boxes[box].min + _boxes[box].size;
+    }
+
+    // Remove item from the box list
+    void remove(int index) {
+      if (_data[index].prev >= 0) {
+        _data[_data[index].prev].next = _data[index].next;
+      } else {
+        _boxes[_data[index].box].first = _data[index].next;
+      }
+      if (_data[index].next >= 0) {
+        _data[_data[index].next].prev = _data[index].prev;
+      }
+    }
+
+    // Insert item into the box list
+    void insert(int box, int index) {
+      if (_boxes[box].first == -1) {
+        _boxes[box].first = index;
+        _data[index].next = _data[index].prev = -1;
+      } else {
+        _data[index].next = _boxes[box].first;
+        _data[_boxes[box].first].prev = index;
+        _data[index].prev = -1;
+        _boxes[box].first = index;
+      }
+      _data[index].box = box;
+    }
+
+    // Add a new box to the box list
+    void extend() {
+      int min = _boxes.back().min + _boxes.back().size;
+      int bs = 2 * _boxes.back().size;
+      _boxes.push_back(RadixBox(min, bs));
+    }
+
+    // Move an item up into the proper box.
+    void bubbleUp(int index) {
+      if (!lower(_data[index].box, _data[index].prio)) return;
+      remove(index);
+      int box = findUp(_data[index].box, _data[index].prio);
+      insert(box, index);
+    }
+
+    // Find up the proper box for the item with the given priority
+    int findUp(int start, int pr) {
+      while (lower(start, pr)) {
+        if (++start == int(_boxes.size())) {
+          extend();
+        }
+      }
+      return start;
+    }
+
+    // Move an item down into the proper box
+    void bubbleDown(int index) {
+      if (!upper(_data[index].box, _data[index].prio)) return;
+      remove(index);
+      int box = findDown(_data[index].box, _data[index].prio);
+      insert(box, index);
+    }
+
+    // Find down the proper box for the item with the given priority
+    int findDown(int start, int pr) {
+      while (upper(start, pr)) {
+        if (--start < 0) throw PriorityUnderflowError();
+      }
+      return start;
+    }
+
+    // Find the first non-empty box
+    int findFirst() {
+      int first = 0;
+      while (_boxes[first].first == -1) ++first;
+      return first;
+    }
+
+    // Gives back the minimum priority of the given box
+    int minValue(int box) {
+      int min = _data[_boxes[box].first].prio;
+      for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
+        if (_data[k].prio < min) min = _data[k].prio;
+      }
+      return min;
+    }
+
+    // Rearrange the items of the heap and make the first box non-empty
+    void moveDown() {
+      int box = findFirst();
+      if (box == 0) return;
+      int min = minValue(box);
+      for (int i = 0; i <= box; ++i) {
+        _boxes[i].min = min;
+        min += _boxes[i].size;
+      }
+      int curr = _boxes[box].first, next;
+      while (curr != -1) {
+        next = _data[curr].next;
+        bubbleDown(curr);
+        curr = next;
+      }
+    }
+
+    void relocateLast(int index) {
+      if (index != int(_data.size()) - 1) {
+        _data[index] = _data.back();
+        if (_data[index].prev != -1) {
+          _data[_data[index].prev].next = index;
+        } else {
+          _boxes[_data[index].box].first = index;
+        }
+        if (_data[index].next != -1) {
+          _data[_data[index].next].prev = index;
+        }
+        _iim[_data[index].item] = index;
+      }
+      _data.pop_back();
+    }
+
+  public:
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    /// \warning This method may throw an \c UnderFlowPriorityException.
+    void push(const Item &i, const Prio &p) {
+      int n = _data.size();
+      _iim.set(i, n);
+      _data.push_back(RadixItem(i, p));
+      while (lower(_boxes.size() - 1, p)) {
+        extend();
+      }
+      int box = findDown(_boxes.size() - 1, p);
+      insert(box, n);
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const {
+      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
+      return _data[_boxes[0].first].item;
+    }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const {
+      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
+      return _data[_boxes[0].first].prio;
+     }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      moveDown();
+      int index = _boxes[0].first;
+      _iim[_data[index].item] = POST_HEAP;
+      remove(index);
+      relocateLast(index);
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int index = _iim[i];
+      _iim[i] = POST_HEAP;
+      remove(index);
+      relocateLast(index);
+   }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].prio;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be in the heap.
+    /// \warning This method may throw an \c UnderFlowPriorityException.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if( idx < 0 ) {
+        push(i, p);
+      }
+      else if( p >= _data[idx].prio ) {
+        _data[idx].prio = p;
+        bubbleUp(idx);
+      } else {
+        _data[idx].prio = p;
+        bubbleDown(idx);
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    /// \warning This method may throw an \c UnderFlowPriorityException.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      _data[idx].prio = p;
+      bubbleDown(idx);
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      _data[idx].prio = p;
+      bubbleUp(idx);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int s = _iim[i];
+      if( s >= 0 ) s = 0;
+      return State(s);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  }; // class RadixHeap
+
+} // namespace lemon
+
+#endif // LEMON_RADIX_HEAP_H
diff --git a/lemon/radix_sort.h b/lemon/radix_sort.h
new file mode 100644
index 0000000..d808756
--- /dev/null
+++ b/lemon/radix_sort.h
@@ -0,0 +1,487 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef RADIX_SORT_H
+#define RADIX_SORT_H
+
+/// \ingroup auxalg
+/// \file
+/// \brief Radix sort
+///
+/// Linear time sorting algorithms
+
+#include <vector>
+#include <limits>
+#include <iterator>
+#include <algorithm>
+
+namespace lemon {
+
+  namespace _radix_sort_bits {
+
+    template <typename Iterator>
+    bool unitRange(Iterator first, Iterator last) {
+      ++first;
+      return first == last;
+    }
+
+    template <typename Value>
+    struct Identity {
+      const Value& operator()(const Value& val) {
+        return val;
+      }
+    };
+
+
+    template <typename Value, typename Iterator, typename Functor>
+    Iterator radixSortPartition(Iterator first, Iterator last,
+                                Functor functor, Value mask) {
+      while (first != last && !(functor(*first) & mask)) {
+        ++first;
+      }
+      if (first == last) {
+        return first;
+      }
+      --last;
+      while (first != last && (functor(*last) & mask)) {
+        --last;
+      }
+      if (first == last) {
+        return first;
+      }
+      std::iter_swap(first, last);
+      ++first;
+      while (true) {
+        while (!(functor(*first) & mask)) {
+          ++first;
+        }
+        --last;
+        while (functor(*last) & mask) {
+          --last;
+        }
+        if (unitRange(last, first)) {
+          return first;
+        }
+        std::iter_swap(first, last);
+        ++first;
+      }
+    }
+
+    template <typename Iterator, typename Functor>
+    Iterator radixSortSignPartition(Iterator first, Iterator last,
+                                    Functor functor) {
+      while (first != last && functor(*first) < 0) {
+        ++first;
+      }
+      if (first == last) {
+        return first;
+      }
+      --last;
+      while (first != last && functor(*last) >= 0) {
+        --last;
+      }
+      if (first == last) {
+        return first;
+      }
+      std::iter_swap(first, last);
+      ++first;
+      while (true) {
+        while (functor(*first) < 0) {
+          ++first;
+        }
+        --last;
+        while (functor(*last) >= 0) {
+          --last;
+        }
+        if (unitRange(last, first)) {
+          return first;
+        }
+        std::iter_swap(first, last);
+        ++first;
+      }
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixIntroSort(Iterator first, Iterator last,
+                        Functor functor, Value mask) {
+      while (mask != 0 && first != last && !unitRange(first, last)) {
+        Iterator cut = radixSortPartition(first, last, functor, mask);
+        mask >>= 1;
+        radixIntroSort(first, cut, functor, mask);
+        first = cut;
+      }
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixSignedSort(Iterator first, Iterator last, Functor functor) {
+
+      Iterator cut = radixSortSignPartition(first, last, functor);
+
+      Value mask;
+      int max_digit;
+      Iterator it;
+
+      mask = ~0; max_digit = 0;
+      for (it = first; it != cut; ++it) {
+        while ((mask & functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1;
+        }
+      }
+      radixIntroSort(first, cut, functor, 1 << max_digit);
+
+      mask = 0; max_digit = 0;
+      for (it = cut; it != last; ++it) {
+        while ((mask | functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1; mask |= 1;
+        }
+      }
+      radixIntroSort(cut, last, functor, 1 << max_digit);
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixUnsignedSort(Iterator first, Iterator last, Functor functor) {
+
+      Value mask = 0;
+      int max_digit = 0;
+
+      Iterator it;
+      for (it = first; it != last; ++it) {
+        while ((mask | functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1; mask |= 1;
+        }
+      }
+      radixIntroSort(first, last, functor, 1 << max_digit);
+    }
+
+
+    template <typename Value,
+              bool sign = std::numeric_limits<Value>::is_signed >
+    struct RadixSortSelector {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        radixSignedSort<Value>(first, last, functor);
+      }
+    };
+
+    template <typename Value>
+    struct RadixSortSelector<Value, false> {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        radixUnsignedSort<Value>(first, last, functor);
+      }
+    };
+
+  }
+
+  /// \ingroup auxalg
+  ///
+  /// \brief Sorts the STL compatible range into ascending order.
+  ///
+  /// The \c radixSort sorts an STL compatible range into ascending
+  /// order.  The radix sort algorithm can sort items which are mapped
+  /// to integers with an adaptable unary function \c functor and the
+  /// order will be ascending according to these mapped values.
+  ///
+  /// It is also possible to use a normal function instead
+  /// of the functor object. If the functor is not given it will use
+  /// the identity function instead.
+  ///
+  /// This is a special quick sort algorithm where the pivot
+  /// values to split the items are choosen to be 2<sup>k</sup>
+  /// for each \c k.
+  /// Therefore, the time complexity of the algorithm is O(log(c)*n) and
+  /// it uses O(log(c)) additional space, where \c c is the maximal value
+  /// and \c n is the number of the items in the container.
+  ///
+  /// \param first The begin of the given range.
+  /// \param last The end of the given range.
+  /// \param functor An adaptible unary function or a normal function
+  /// which maps the items to any integer type which can be either
+  /// signed or unsigned.
+  ///
+  /// \sa stableRadixSort()
+  template <typename Iterator, typename Functor>
+  void radixSort(Iterator first, Iterator last, Functor functor) {
+    using namespace _radix_sort_bits;
+    typedef typename Functor::result_type Value;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator>
+  void radixSort(Iterator first, Iterator last) {
+    using namespace _radix_sort_bits;
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    RadixSortSelector<Value>::sort(first, last, Identity<Value>());
+  }
+
+  namespace _radix_sort_bits {
+
+    template <typename Value>
+    unsigned char valueByte(Value value, int byte) {
+      return value >> (std::numeric_limits<unsigned char>::digits * byte);
+    }
+
+    template <typename Functor, typename Key>
+    void stableRadixIntroSort(Key *first, Key *last, Key *target,
+                              int byte, Functor functor) {
+      const int size =
+        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
+      std::vector<int> counter(size);
+      for (int i = 0; i < size; ++i) {
+        counter[i] = 0;
+      }
+      Key *it = first;
+      while (first != last) {
+        ++counter[valueByte(functor(*first), byte)];
+        ++first;
+      }
+      int prev, num = 0;
+      for (int i = 0; i < size; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      while (it != last) {
+        target[counter[valueByte(functor(*it), byte)]++] = *it;
+        ++it;
+      }
+    }
+
+    template <typename Functor, typename Key>
+    void signedStableRadixIntroSort(Key *first, Key *last, Key *target,
+                                    int byte, Functor functor) {
+      const int size =
+        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
+      std::vector<int> counter(size);
+      for (int i = 0; i < size; ++i) {
+        counter[i] = 0;
+      }
+      Key *it = first;
+      while (first != last) {
+        counter[valueByte(functor(*first), byte)]++;
+        ++first;
+      }
+      int prev, num = 0;
+      for (int i = size / 2; i < size; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      for (int i = 0; i < size / 2; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      while (it != last) {
+        target[counter[valueByte(functor(*it), byte)]++] = *it;
+        ++it;
+      }
+    }
+
+
+    template <typename Value, typename Iterator, typename Functor>
+    void stableRadixSignedSort(Iterator first, Iterator last, Functor functor) {
+      if (first == last) return;
+      typedef typename std::iterator_traits<Iterator>::value_type Key;
+      typedef std::allocator<Key> Allocator;
+      Allocator allocator;
+
+      int length = std::distance(first, last);
+      Key* buffer = allocator.allocate(2 * length);
+      try {
+        bool dir = true;
+        std::copy(first, last, buffer);
+        for (int i = 0; i < int(sizeof(Value)) - 1; ++i) {
+          if (dir) {
+            stableRadixIntroSort(buffer, buffer + length, buffer + length,
+                                 i, functor);
+          } else {
+            stableRadixIntroSort(buffer + length, buffer + 2 * length, buffer,
+                                 i, functor);
+          }
+          dir = !dir;
+        }
+        if (dir) {
+          signedStableRadixIntroSort(buffer, buffer + length, buffer + length,
+                                     sizeof(Value) - 1, functor);
+          std::copy(buffer + length, buffer + 2 * length, first);
+        }        else {
+          signedStableRadixIntroSort(buffer + length, buffer + 2 * length,
+                                     buffer, sizeof(Value) - 1, functor);
+          std::copy(buffer, buffer + length, first);
+        }
+      } catch (...) {
+        allocator.deallocate(buffer, 2 * length);
+        throw;
+      }
+      allocator.deallocate(buffer, 2 * length);
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void stableRadixUnsignedSort(Iterator first, Iterator last,
+                                 Functor functor) {
+      if (first == last) return;
+      typedef typename std::iterator_traits<Iterator>::value_type Key;
+      typedef std::allocator<Key> Allocator;
+      Allocator allocator;
+
+      int length = std::distance(first, last);
+      Key *buffer = allocator.allocate(2 * length);
+      try {
+        bool dir = true;
+        std::copy(first, last, buffer);
+        for (int i = 0; i < int(sizeof(Value)); ++i) {
+          if (dir) {
+            stableRadixIntroSort(buffer, buffer + length,
+                                 buffer + length, i, functor);
+          } else {
+            stableRadixIntroSort(buffer + length, buffer + 2 * length,
+                                 buffer, i, functor);
+          }
+          dir = !dir;
+        }
+        if (dir) {
+          std::copy(buffer, buffer + length, first);
+        }        else {
+          std::copy(buffer + length, buffer + 2 * length, first);
+        }
+      } catch (...) {
+        allocator.deallocate(buffer, 2 * length);
+        throw;
+      }
+      allocator.deallocate(buffer, 2 * length);
+    }
+
+
+
+    template <typename Value,
+              bool sign = std::numeric_limits<Value>::is_signed >
+    struct StableRadixSortSelector {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        stableRadixSignedSort<Value>(first, last, functor);
+      }
+    };
+
+    template <typename Value>
+    struct StableRadixSortSelector<Value, false> {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        stableRadixUnsignedSort<Value>(first, last, functor);
+      }
+    };
+
+  }
+
+  /// \ingroup auxalg
+  ///
+  /// \brief Sorts the STL compatible range into ascending order in a stable
+  /// way.
+  ///
+  /// This function sorts an STL compatible range into ascending
+  /// order according to an integer mapping in the same as radixSort() does.
+  ///
+  /// This sorting algorithm is stable, i.e. the order of two equal
+  /// elements remains the same after the sorting.
+  ///
+  /// This sort algorithm  use a radix forward sort on the
+  /// bytes of the integer number. The algorithm sorts the items
+  /// byte-by-byte. First, it counts how many times a byte value occurs
+  /// in the container, then it copies the corresponding items to
+  /// another container in asceding order in O(n) time.
+  ///
+  /// The time complexity of the algorithm is O(log(c)*n) and
+  /// it uses O(n) additional space, where \c c is the
+  /// maximal value and \c n is the number of the items in the
+  /// container.
+  ///
+
+  /// \param first The begin of the given range.
+  /// \param last The end of the given range.
+  /// \param functor An adaptible unary function or a normal function
+  /// which maps the items to any integer type which can be either
+  /// signed or unsigned.
+  /// \sa radixSort()
+  template <typename Iterator, typename Functor>
+  void stableRadixSort(Iterator first, Iterator last, Functor functor) {
+    using namespace _radix_sort_bits;
+    typedef typename Functor::result_type Value;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator>
+  void stableRadixSort(Iterator first, Iterator last) {
+    using namespace _radix_sort_bits;
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    StableRadixSortSelector<Value>::sort(first, last, Identity<Value>());
+  }
+
+}
+
+#endif
diff --git a/lemon/random.cc b/lemon/random.cc
new file mode 100644
index 0000000..0295121
--- /dev/null
+++ b/lemon/random.cc
@@ -0,0 +1,29 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Instantiation of the Random class.
+
+#include <lemon/random.h>
+
+namespace lemon {
+  /// \brief Global random number generator instance
+  ///
+  /// A global Mersenne Twister random number generator instance.
+  Random rnd;
+}
diff --git a/lemon/random.h b/lemon/random.h
new file mode 100644
index 0000000..8de74ed
--- /dev/null
+++ b/lemon/random.h
@@ -0,0 +1,1005 @@
+/* -*- 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.
+ *
+ */
+
+/*
+ * This file contains the reimplemented version of the Mersenne Twister
+ * Generator of Matsumoto and Nishimura.
+ *
+ * See the appropriate copyright notice below.
+ *
+ * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The names of its contributors may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Any feedback is very welcome.
+ * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+ * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+ */
+
+#ifndef LEMON_RANDOM_H
+#define LEMON_RANDOM_H
+
+#include <algorithm>
+#include <iterator>
+#include <vector>
+#include <limits>
+#include <fstream>
+
+#include <lemon/math.h>
+#include <lemon/dim2.h>
+
+#ifndef WIN32
+#include <sys/time.h>
+#include <ctime>
+#include <sys/types.h>
+#include <unistd.h>
+#else
+#include <lemon/bits/windows.h>
+#endif
+
+///\ingroup misc
+///\file
+///\brief Mersenne Twister random number generator
+
+namespace lemon {
+
+  namespace _random_bits {
+
+    template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
+    struct RandomTraits {};
+
+    template <typename _Word>
+    struct RandomTraits<_Word, 32> {
+
+      typedef _Word Word;
+      static const int bits = 32;
+
+      static const int length = 624;
+      static const int shift = 397;
+
+      static const Word mul = 0x6c078965u;
+      static const Word arrayInit = 0x012BD6AAu;
+      static const Word arrayMul1 = 0x0019660Du;
+      static const Word arrayMul2 = 0x5D588B65u;
+
+      static const Word mask = 0x9908B0DFu;
+      static const Word loMask = (1u << 31) - 1;
+      static const Word hiMask = ~loMask;
+
+
+      static Word tempering(Word rnd) {
+        rnd ^= (rnd >> 11);
+        rnd ^= (rnd << 7) & 0x9D2C5680u;
+        rnd ^= (rnd << 15) & 0xEFC60000u;
+        rnd ^= (rnd >> 18);
+        return rnd;
+      }
+
+    };
+
+    template <typename _Word>
+    struct RandomTraits<_Word, 64> {
+
+      typedef _Word Word;
+      static const int bits = 64;
+
+      static const int length = 312;
+      static const int shift = 156;
+
+      static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
+      static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
+      static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
+      static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
+
+      static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
+      static const Word loMask = (Word(1u) << 31) - 1;
+      static const Word hiMask = ~loMask;
+
+      static Word tempering(Word rnd) {
+        rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
+        rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
+        rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
+        rnd ^= (rnd >> 43);
+        return rnd;
+      }
+
+    };
+
+    template <typename _Word>
+    class RandomCore {
+    public:
+
+      typedef _Word Word;
+
+    private:
+
+      static const int bits = RandomTraits<Word>::bits;
+
+      static const int length = RandomTraits<Word>::length;
+      static const int shift = RandomTraits<Word>::shift;
+
+    public:
+
+      void initState() {
+        static const Word seedArray[4] = {
+          0x12345u, 0x23456u, 0x34567u, 0x45678u
+        };
+
+        initState(seedArray, seedArray + 4);
+      }
+
+      void initState(Word seed) {
+
+        static const Word mul = RandomTraits<Word>::mul;
+
+        current = state;
+
+        Word *curr = state + length - 1;
+        curr[0] = seed; --curr;
+        for (int i = 1; i < length; ++i) {
+          curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
+          --curr;
+        }
+      }
+
+      template <typename Iterator>
+      void initState(Iterator begin, Iterator end) {
+
+        static const Word init = RandomTraits<Word>::arrayInit;
+        static const Word mul1 = RandomTraits<Word>::arrayMul1;
+        static const Word mul2 = RandomTraits<Word>::arrayMul2;
+
+
+        Word *curr = state + length - 1; --curr;
+        Iterator it = begin; int cnt = 0;
+        int num;
+
+        initState(init);
+
+        num = length > end - begin ? length : end - begin;
+        while (num--) {
+          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
+            + *it + cnt;
+          ++it; ++cnt;
+          if (it == end) {
+            it = begin; cnt = 0;
+          }
+          if (curr == state) {
+            curr = state + length - 1; curr[0] = state[0];
+          }
+          --curr;
+        }
+
+        num = length - 1; cnt = length - (curr - state) - 1;
+        while (num--) {
+          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
+            - cnt;
+          --curr; ++cnt;
+          if (curr == state) {
+            curr = state + length - 1; curr[0] = state[0]; --curr;
+            cnt = 1;
+          }
+        }
+
+        state[length - 1] = Word(1) << (bits - 1);
+      }
+
+      void copyState(const RandomCore& other) {
+        std::copy(other.state, other.state + length, state);
+        current = state + (other.current - other.state);
+      }
+
+      Word operator()() {
+        if (current == state) fillState();
+        --current;
+        Word rnd = *current;
+        return RandomTraits<Word>::tempering(rnd);
+      }
+
+    private:
+
+
+      void fillState() {
+        static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
+        static const Word loMask = RandomTraits<Word>::loMask;
+        static const Word hiMask = RandomTraits<Word>::hiMask;
+
+        current = state + length;
+
+        register Word *curr = state + length - 1;
+        register long num;
+
+        num = length - shift;
+        while (num--) {
+          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
+            curr[- shift] ^ mask[curr[-1] & 1ul];
+          --curr;
+        }
+        num = shift - 1;
+        while (num--) {
+          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
+            curr[length - shift] ^ mask[curr[-1] & 1ul];
+          --curr;
+        }
+        state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
+          curr[length - shift] ^ mask[curr[length - 1] & 1ul];
+
+      }
+
+
+      Word *current;
+      Word state[length];
+
+    };
+
+
+    template <typename Result,
+              int shift = (std::numeric_limits<Result>::digits + 1) / 2>
+    struct Masker {
+      static Result mask(const Result& result) {
+        return Masker<Result, (shift + 1) / 2>::
+          mask(static_cast<Result>(result | (result >> shift)));
+      }
+    };
+
+    template <typename Result>
+    struct Masker<Result, 1> {
+      static Result mask(const Result& result) {
+        return static_cast<Result>(result | (result >> 1));
+      }
+    };
+
+    template <typename Result, typename Word,
+              int rest = std::numeric_limits<Result>::digits, int shift = 0,
+              bool last = rest <= std::numeric_limits<Word>::digits>
+    struct IntConversion {
+      static const int bits = std::numeric_limits<Word>::digits;
+
+      static Result convert(RandomCore<Word>& rnd) {
+        return static_cast<Result>(rnd() >> (bits - rest)) << shift;
+      }
+
+    };
+
+    template <typename Result, typename Word, int rest, int shift>
+    struct IntConversion<Result, Word, rest, shift, false> {
+      static const int bits = std::numeric_limits<Word>::digits;
+
+      static Result convert(RandomCore<Word>& rnd) {
+        return (static_cast<Result>(rnd()) << shift) |
+          IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
+      }
+    };
+
+
+    template <typename Result, typename Word,
+              bool one_word = (std::numeric_limits<Word>::digits <
+                               std::numeric_limits<Result>::digits) >
+    struct Mapping {
+      static Result map(RandomCore<Word>& rnd, const Result& bound) {
+        Word max = Word(bound - 1);
+        Result mask = Masker<Result>::mask(bound - 1);
+        Result num;
+        do {
+          num = IntConversion<Result, Word>::convert(rnd) & mask;
+        } while (num > max);
+        return num;
+      }
+    };
+
+    template <typename Result, typename Word>
+    struct Mapping<Result, Word, false> {
+      static Result map(RandomCore<Word>& rnd, const Result& bound) {
+        Word max = Word(bound - 1);
+        Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
+          ::mask(max);
+        Word num;
+        do {
+          num = rnd() & mask;
+        } while (num > max);
+        return num;
+      }
+    };
+
+    template <typename Result, int exp>
+    struct ShiftMultiplier {
+      static const Result multiplier() {
+        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
+        res *= res;
+        if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
+        return res;
+      }
+    };
+
+    template <typename Result>
+    struct ShiftMultiplier<Result, 0> {
+      static const Result multiplier() {
+        return static_cast<Result>(1.0);
+      }
+    };
+
+    template <typename Result>
+    struct ShiftMultiplier<Result, 20> {
+      static const Result multiplier() {
+        return static_cast<Result>(1.0/1048576.0);
+      }
+    };
+
+    template <typename Result>
+    struct ShiftMultiplier<Result, 32> {
+      static const Result multiplier() {
+        return static_cast<Result>(1.0/4294967296.0);
+      }
+    };
+
+    template <typename Result>
+    struct ShiftMultiplier<Result, 53> {
+      static const Result multiplier() {
+        return static_cast<Result>(1.0/9007199254740992.0);
+      }
+    };
+
+    template <typename Result>
+    struct ShiftMultiplier<Result, 64> {
+      static const Result multiplier() {
+        return static_cast<Result>(1.0/18446744073709551616.0);
+      }
+    };
+
+    template <typename Result, int exp>
+    struct Shifting {
+      static Result shift(const Result& result) {
+        return result * ShiftMultiplier<Result, exp>::multiplier();
+      }
+    };
+
+    template <typename Result, typename Word,
+              int rest = std::numeric_limits<Result>::digits, int shift = 0,
+              bool last = rest <= std::numeric_limits<Word>::digits>
+    struct RealConversion{
+      static const int bits = std::numeric_limits<Word>::digits;
+
+      static Result convert(RandomCore<Word>& rnd) {
+        return Shifting<Result, shift + rest>::
+          shift(static_cast<Result>(rnd() >> (bits - rest)));
+      }
+    };
+
+    template <typename Result, typename Word, int rest, int shift>
+    struct RealConversion<Result, Word, rest, shift, false> {
+      static const int bits = std::numeric_limits<Word>::digits;
+
+      static Result convert(RandomCore<Word>& rnd) {
+        return Shifting<Result, shift + bits>::
+          shift(static_cast<Result>(rnd())) +
+          RealConversion<Result, Word, rest-bits, shift + bits>::
+          convert(rnd);
+      }
+    };
+
+    template <typename Result, typename Word>
+    struct Initializer {
+
+      template <typename Iterator>
+      static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
+        std::vector<Word> ws;
+        for (Iterator it = begin; it != end; ++it) {
+          ws.push_back(Word(*it));
+        }
+        rnd.initState(ws.begin(), ws.end());
+      }
+
+      static void init(RandomCore<Word>& rnd, Result seed) {
+        rnd.initState(seed);
+      }
+    };
+
+    template <typename Word>
+    struct BoolConversion {
+      static bool convert(RandomCore<Word>& rnd) {
+        return (rnd() & 1) == 1;
+      }
+    };
+
+    template <typename Word>
+    struct BoolProducer {
+      Word buffer;
+      int num;
+
+      BoolProducer() : num(0) {}
+
+      bool convert(RandomCore<Word>& rnd) {
+        if (num == 0) {
+          buffer = rnd();
+          num = RandomTraits<Word>::bits;
+        }
+        bool r = (buffer & 1);
+        buffer >>= 1;
+        --num;
+        return r;
+      }
+    };
+
+  }
+
+  /// \ingroup misc
+  ///
+  /// \brief Mersenne Twister random number generator
+  ///
+  /// The Mersenne Twister is a twisted generalized feedback
+  /// shift-register generator of Matsumoto and Nishimura. The period
+  /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
+  /// equi-distributed in 623 dimensions for 32-bit numbers. The time
+  /// performance of this generator is comparable to the commonly used
+  /// generators.
+  ///
+  /// This implementation is specialized for both 32-bit and 64-bit
+  /// architectures. The generators differ sligthly in the
+  /// initialization and generation phase so they produce two
+  /// completly different sequences.
+  ///
+  /// The generator gives back random numbers of serveral types. To
+  /// get a random number from a range of a floating point type you
+  /// can use one form of the \c operator() or the \c real() member
+  /// function. If you want to get random number from the {0, 1, ...,
+  /// n-1} integer range use the \c operator[] or the \c integer()
+  /// method. And to get random number from the whole range of an
+  /// integer type you can use the argumentless \c integer() or \c
+  /// uinteger() functions. After all you can get random bool with
+  /// equal chance of true and false or given probability of true
+  /// result with the \c boolean() member functions.
+  ///
+  ///\code
+  /// // The commented code is identical to the other
+  /// double a = rnd();                     // [0.0, 1.0)
+  /// // double a = rnd.real();             // [0.0, 1.0)
+  /// double b = rnd(100.0);                // [0.0, 100.0)
+  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
+  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
+  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
+  /// int d = rnd[100000];                  // 0..99999
+  /// // int d = rnd.integer(100000);       // 0..99999
+  /// int e = rnd[6] + 1;                   // 1..6
+  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
+  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
+  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
+  /// bool g = rnd.boolean();               // P(g = true) = 0.5
+  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
+  ///\endcode
+  ///
+  /// LEMON provides a global instance of the random number
+  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
+  /// good programming convenience to use this global generator to get
+  /// random numbers.
+  class Random {
+  private:
+
+    // Architecture word
+    typedef unsigned long Word;
+
+    _random_bits::RandomCore<Word> core;
+    _random_bits::BoolProducer<Word> bool_producer;
+
+
+  public:
+
+    ///\name Initialization
+    ///
+    /// @{
+
+    /// \brief Default constructor
+    ///
+    /// Constructor with constant seeding.
+    Random() { core.initState(); }
+
+    /// \brief Constructor with seed
+    ///
+    /// Constructor with seed. The current number type will be converted
+    /// to the architecture word type.
+    template <typename Number>
+    Random(Number seed) {
+      _random_bits::Initializer<Number, Word>::init(core, seed);
+    }
+
+    /// \brief Constructor with array seeding
+    ///
+    /// Constructor with array seeding. The given range should contain
+    /// any number type and the numbers will be converted to the
+    /// architecture word type.
+    template <typename Iterator>
+    Random(Iterator begin, Iterator end) {
+      typedef typename std::iterator_traits<Iterator>::value_type Number;
+      _random_bits::Initializer<Number, Word>::init(core, begin, end);
+    }
+
+    /// \brief Copy constructor
+    ///
+    /// Copy constructor. The generated sequence will be identical to
+    /// the other sequence. It can be used to save the current state
+    /// of the generator and later use it to generate the same
+    /// sequence.
+    Random(const Random& other) {
+      core.copyState(other.core);
+    }
+
+    /// \brief Assign operator
+    ///
+    /// Assign operator. The generated sequence will be identical to
+    /// the other sequence. It can be used to save the current state
+    /// of the generator and later use it to generate the same
+    /// sequence.
+    Random& operator=(const Random& other) {
+      if (&other != this) {
+        core.copyState(other.core);
+      }
+      return *this;
+    }
+
+    /// \brief Seeding random sequence
+    ///
+    /// Seeding the random sequence. The current number type will be
+    /// converted to the architecture word type.
+    template <typename Number>
+    void seed(Number seed) {
+      _random_bits::Initializer<Number, Word>::init(core, seed);
+    }
+
+    /// \brief Seeding random sequence
+    ///
+    /// Seeding the random sequence. The given range should contain
+    /// any number type and the numbers will be converted to the
+    /// architecture word type.
+    template <typename Iterator>
+    void seed(Iterator begin, Iterator end) {
+      typedef typename std::iterator_traits<Iterator>::value_type Number;
+      _random_bits::Initializer<Number, Word>::init(core, begin, end);
+    }
+
+    /// \brief Seeding from file or from process id and time
+    ///
+    /// By default, this function calls the \c seedFromFile() member
+    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
+    /// it uses the \c seedFromTime().
+    /// \return Currently always \c true.
+    bool seed() {
+#ifndef WIN32
+      if (seedFromFile("/dev/urandom", 0)) return true;
+#endif
+      if (seedFromTime()) return true;
+      return false;
+    }
+
+    /// \brief Seeding from file
+    ///
+    /// Seeding the random sequence from file. The linux kernel has two
+    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
+    /// could give good seed values for pseudo random generators (The
+    /// difference between two devices is that the <tt>random</tt> may
+    /// block the reading operation while the kernel can give good
+    /// source of randomness, while the <tt>urandom</tt> does not
+    /// block the input, but it could give back bytes with worse
+    /// entropy).
+    /// \param file The source file
+    /// \param offset The offset, from the file read.
+    /// \return \c true when the seeding successes.
+#ifndef WIN32
+    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
+#else
+    bool seedFromFile(const std::string& file = "", int offset = 0)
+#endif
+    {
+      std::ifstream rs(file.c_str());
+      const int size = 4;
+      Word buf[size];
+      if (offset != 0 && !rs.seekg(offset)) return false;
+      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
+      seed(buf, buf + size);
+      return true;
+    }
+
+    /// \brief Seding from process id and time
+    ///
+    /// Seding from process id and time. This function uses the
+    /// current process id and the current time for initialize the
+    /// random sequence.
+    /// \return Currently always \c true.
+    bool seedFromTime() {
+#ifndef WIN32
+      timeval tv;
+      gettimeofday(&tv, 0);
+      seed(getpid() + tv.tv_sec + tv.tv_usec);
+#else
+      seed(bits::getWinRndSeed());
+#endif
+      return true;
+    }
+
+    /// @}
+
+    ///\name Uniform Distributions
+    ///
+    /// @{
+
+    /// \brief Returns a random real number from the range [0, 1)
+    ///
+    /// It returns a random real number from the range [0, 1). The
+    /// default Number type is \c double.
+    template <typename Number>
+    Number real() {
+      return _random_bits::RealConversion<Number, Word>::convert(core);
+    }
+
+    double real() {
+      return real<double>();
+    }
+
+    /// \brief Returns a random real number from the range [0, 1)
+    ///
+    /// It returns a random double from the range [0, 1).
+    double operator()() {
+      return real<double>();
+    }
+
+    /// \brief Returns a random real number from the range [0, b)
+    ///
+    /// It returns a random real number from the range [0, b).
+    double operator()(double b) {
+      return real<double>() * b;
+    }
+
+    /// \brief Returns a random real number from the range [a, b)
+    ///
+    /// It returns a random real number from the range [a, b).
+    double operator()(double a, double b) {
+      return real<double>() * (b - a) + a;
+    }
+
+    /// \brief Returns a random integer from a range
+    ///
+    /// It returns a random integer from the range {0, 1, ..., b - 1}.
+    template <typename Number>
+    Number integer(Number b) {
+      return _random_bits::Mapping<Number, Word>::map(core, b);
+    }
+
+    /// \brief Returns a random integer from a range
+    ///
+    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
+    template <typename Number>
+    Number integer(Number a, Number b) {
+      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
+    }
+
+    /// \brief Returns a random integer from a range
+    ///
+    /// It returns a random integer from the range {0, 1, ..., b - 1}.
+    template <typename Number>
+    Number operator[](Number b) {
+      return _random_bits::Mapping<Number, Word>::map(core, b);
+    }
+
+    /// \brief Returns a random non-negative integer
+    ///
+    /// It returns a random non-negative integer uniformly from the
+    /// whole range of the current \c Number type. The default result
+    /// type of this function is <tt>unsigned int</tt>.
+    template <typename Number>
+    Number uinteger() {
+      return _random_bits::IntConversion<Number, Word>::convert(core);
+    }
+
+    unsigned int uinteger() {
+      return uinteger<unsigned int>();
+    }
+
+    /// \brief Returns a random integer
+    ///
+    /// It returns a random integer uniformly from the whole range of
+    /// the current \c Number type. The default result type of this
+    /// function is \c int.
+    template <typename Number>
+    Number integer() {
+      static const int nb = std::numeric_limits<Number>::digits +
+        (std::numeric_limits<Number>::is_signed ? 1 : 0);
+      return _random_bits::IntConversion<Number, Word, nb>::convert(core);
+    }
+
+    int integer() {
+      return integer<int>();
+    }
+
+    /// \brief Returns a random bool
+    ///
+    /// It returns a random bool. The generator holds a buffer for
+    /// random bits. Every time when it become empty the generator makes
+    /// a new random word and fill the buffer up.
+    bool boolean() {
+      return bool_producer.convert(core);
+    }
+
+    /// @}
+
+    ///\name Non-uniform Distributions
+    ///
+    ///@{
+
+    /// \brief Returns a random bool with given probability of true result.
+    ///
+    /// It returns a random bool with given probability of true result.
+    bool boolean(double p) {
+      return operator()() < p;
+    }
+
+    /// Standard normal (Gauss) distribution
+
+    /// Standard normal (Gauss) distribution.
+    /// \note The Cartesian form of the Box-Muller
+    /// transformation is used to generate a random normal distribution.
+    double gauss()
+    {
+      double V1,V2,S;
+      do {
+        V1=2*real<double>()-1;
+        V2=2*real<double>()-1;
+        S=V1*V1+V2*V2;
+      } while(S>=1);
+      return std::sqrt(-2*std::log(S)/S)*V1;
+    }
+    /// Normal (Gauss) distribution with given mean and standard deviation
+
+    /// Normal (Gauss) distribution with given mean and standard deviation.
+    /// \sa gauss()
+    double gauss(double mean,double std_dev)
+    {
+      return gauss()*std_dev+mean;
+    }
+
+    /// Lognormal distribution
+
+    /// Lognormal distribution. The parameters are the mean and the standard
+    /// deviation of <tt>exp(X)</tt>.
+    ///
+    double lognormal(double n_mean,double n_std_dev)
+    {
+      return std::exp(gauss(n_mean,n_std_dev));
+    }
+    /// Lognormal distribution
+
+    /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
+    /// the mean and the standard deviation of <tt>exp(X)</tt>.
+    ///
+    double lognormal(const std::pair<double,double> &params)
+    {
+      return std::exp(gauss(params.first,params.second));
+    }
+    /// Compute the lognormal parameters from mean and standard deviation
+
+    /// This function computes the lognormal parameters from mean and
+    /// standard deviation. The return value can direcly be passed to
+    /// lognormal().
+    std::pair<double,double> lognormalParamsFromMD(double mean,
+                                                   double std_dev)
+    {
+      double fr=std_dev/mean;
+      fr*=fr;
+      double lg=std::log(1+fr);
+      return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
+    }
+    /// Lognormal distribution with given mean and standard deviation
+
+    /// Lognormal distribution with given mean and standard deviation.
+    ///
+    double lognormalMD(double mean,double std_dev)
+    {
+      return lognormal(lognormalParamsFromMD(mean,std_dev));
+    }
+
+    /// Exponential distribution with given mean
+
+    /// This function generates an exponential distribution random number
+    /// with mean <tt>1/lambda</tt>.
+    ///
+    double exponential(double lambda=1.0)
+    {
+      return -std::log(1.0-real<double>())/lambda;
+    }
+
+    /// Gamma distribution with given integer shape
+
+    /// This function generates a gamma distribution random number.
+    ///
+    ///\param k shape parameter (<tt>k>0</tt> integer)
+    double gamma(int k)
+    {
+      double s = 0;
+      for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
+      return s;
+    }
+
+    /// Gamma distribution with given shape and scale parameter
+
+    /// This function generates a gamma distribution random number.
+    ///
+    ///\param k shape parameter (<tt>k>0</tt>)
+    ///\param theta scale parameter
+    ///
+    double gamma(double k,double theta=1.0)
+    {
+      double xi,nu;
+      const double delta = k-std::floor(k);
+      const double v0=E/(E-delta);
+      do {
+        double V0=1.0-real<double>();
+        double V1=1.0-real<double>();
+        double V2=1.0-real<double>();
+        if(V2<=v0)
+          {
+            xi=std::pow(V1,1.0/delta);
+            nu=V0*std::pow(xi,delta-1.0);
+          }
+        else
+          {
+            xi=1.0-std::log(V1);
+            nu=V0*std::exp(-xi);
+          }
+      } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
+      return theta*(xi+gamma(int(std::floor(k))));
+    }
+
+    /// Weibull distribution
+
+    /// This function generates a Weibull distribution random number.
+    ///
+    ///\param k shape parameter (<tt>k>0</tt>)
+    ///\param lambda scale parameter (<tt>lambda>0</tt>)
+    ///
+    double weibull(double k,double lambda)
+    {
+      return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
+    }
+
+    /// Pareto distribution
+
+    /// This function generates a Pareto distribution random number.
+    ///
+    ///\param k shape parameter (<tt>k>0</tt>)
+    ///\param x_min location parameter (<tt>x_min>0</tt>)
+    ///
+    double pareto(double k,double x_min)
+    {
+      return exponential(gamma(k,1.0/x_min))+x_min;
+    }
+
+    /// Poisson distribution
+
+    /// This function generates a Poisson distribution random number with
+    /// parameter \c lambda.
+    ///
+    /// The probability mass function of this distribusion is
+    /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
+    /// \note The algorithm is taken from the book of Donald E. Knuth titled
+    /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
+    /// return value.
+
+    int poisson(double lambda)
+    {
+      const double l = std::exp(-lambda);
+      int k=0;
+      double p = 1.0;
+      do {
+        k++;
+        p*=real<double>();
+      } while (p>=l);
+      return k-1;
+    }
+
+    ///@}
+
+    ///\name Two Dimensional Distributions
+    ///
+    ///@{
+
+    /// Uniform distribution on the full unit circle
+
+    /// Uniform distribution on the full unit circle.
+    ///
+    dim2::Point<double> disc()
+    {
+      double V1,V2;
+      do {
+        V1=2*real<double>()-1;
+        V2=2*real<double>()-1;
+
+      } while(V1*V1+V2*V2>=1);
+      return dim2::Point<double>(V1,V2);
+    }
+    /// A kind of two dimensional normal (Gauss) distribution
+
+    /// This function provides a turning symmetric two-dimensional distribution.
+    /// Both coordinates are of standard normal distribution, but they are not
+    /// independent.
+    ///
+    /// \note The coordinates are the two random variables provided by
+    /// the Box-Muller method.
+    dim2::Point<double> gauss2()
+    {
+      double V1,V2,S;
+      do {
+        V1=2*real<double>()-1;
+        V2=2*real<double>()-1;
+        S=V1*V1+V2*V2;
+      } while(S>=1);
+      double W=std::sqrt(-2*std::log(S)/S);
+      return dim2::Point<double>(W*V1,W*V2);
+    }
+    /// A kind of two dimensional exponential distribution
+
+    /// This function provides a turning symmetric two-dimensional distribution.
+    /// The x-coordinate is of conditionally exponential distribution
+    /// with the condition that x is positive and y=0. If x is negative and
+    /// y=0 then, -x is of exponential distribution. The same is true for the
+    /// y-coordinate.
+    dim2::Point<double> exponential2()
+    {
+      double V1,V2,S;
+      do {
+        V1=2*real<double>()-1;
+        V2=2*real<double>()-1;
+        S=V1*V1+V2*V2;
+      } while(S>=1);
+      double W=-std::log(S)/S;
+      return dim2::Point<double>(W*V1,W*V2);
+    }
+
+    ///@}
+  };
+
+
+  extern Random rnd;
+
+}
+
+#endif
diff --git a/lemon/smart_graph.h b/lemon/smart_graph.h
new file mode 100644
index 0000000..bdbe369
--- /dev/null
+++ b/lemon/smart_graph.h
@@ -0,0 +1,1344 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_SMART_GRAPH_H
+#define LEMON_SMART_GRAPH_H
+
+///\ingroup graphs
+///\file
+///\brief SmartDigraph and SmartGraph classes.
+
+#include <vector>
+
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/bits/graph_extender.h>
+
+namespace lemon {
+
+  class SmartDigraph;
+
+  class SmartDigraphBase {
+  protected:
+
+    struct NodeT
+    {
+      int first_in, first_out;
+      NodeT() {}
+    };
+    struct ArcT
+    {
+      int target, source, next_in, next_out;
+      ArcT() {}
+    };
+
+    std::vector<NodeT> nodes;
+    std::vector<ArcT> arcs;
+
+  public:
+
+    typedef SmartDigraphBase Digraph;
+
+    class Node;
+    class Arc;
+
+  public:
+
+    SmartDigraphBase() : nodes(), arcs() { }
+    SmartDigraphBase(const SmartDigraphBase &_g)
+      : nodes(_g.nodes), arcs(_g.arcs) { }
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return nodes.size(); }
+    int arcNum() const { return arcs.size(); }
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    Node addNode() {
+      int n = nodes.size();
+      nodes.push_back(NodeT());
+      nodes[n].first_in = -1;
+      nodes[n].first_out = -1;
+      return Node(n);
+    }
+
+    Arc addArc(Node u, Node v) {
+      int n = arcs.size();
+      arcs.push_back(ArcT());
+      arcs[n].source = u._id;
+      arcs[n].target = v._id;
+      arcs[n].next_out = nodes[u._id].first_out;
+      arcs[n].next_in = nodes[v._id].first_in;
+      nodes[u._id].first_out = nodes[v._id].first_in = n;
+
+      return Arc(n);
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+    }
+
+    Node source(Arc a) const { return Node(arcs[a._id].source); }
+    Node target(Arc a) const { return Node(arcs[a._id].target); }
+
+    static int id(Node v) { return v._id; }
+    static int id(Arc a) { return a._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+
+    bool valid(Node n) const {
+      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
+    }
+    bool valid(Arc a) const {
+      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
+    }
+
+    class Node {
+      friend class SmartDigraphBase;
+      friend class SmartDigraph;
+
+    protected:
+      int _id;
+      explicit Node(int id) : _id(id) {}
+    public:
+      Node() {}
+      Node (Invalid) : _id(-1) {}
+      bool operator==(const Node i) const {return _id == i._id;}
+      bool operator!=(const Node i) const {return _id != i._id;}
+      bool operator<(const Node i) const {return _id < i._id;}
+    };
+
+
+    class Arc {
+      friend class SmartDigraphBase;
+      friend class SmartDigraph;
+
+    protected:
+      int _id;
+      explicit Arc(int id) : _id(id) {}
+    public:
+      Arc() { }
+      Arc (Invalid) : _id(-1) {}
+      bool operator==(const Arc i) const {return _id == i._id;}
+      bool operator!=(const Arc i) const {return _id != i._id;}
+      bool operator<(const Arc i) const {return _id < i._id;}
+    };
+
+    void first(Node& node) const {
+      node._id = nodes.size() - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = arcs.size() - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc._id = nodes[node._id].first_out;
+    }
+
+    void nextOut(Arc& arc) const {
+      arc._id = arcs[arc._id].next_out;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc._id = nodes[node._id].first_in;
+    }
+
+    void nextIn(Arc& arc) const {
+      arc._id = arcs[arc._id].next_in;
+    }
+
+  };
+
+  typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
+
+  ///\ingroup graphs
+  ///
+  ///\brief A smart directed graph class.
+  ///
+  ///\ref SmartDigraph is a simple and fast digraph implementation.
+  ///It is also quite memory efficient but at the price
+  ///that it does not support node and arc deletion
+  ///(except for the Snapshot feature).
+  ///
+  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
+  ///and it also provides some additional functionalities.
+  ///Most of its member functions and nested classes are documented
+  ///only in the concept class.
+  ///
+  ///This class provides constant time counting for nodes and arcs.
+  ///
+  ///\sa concepts::Digraph
+  ///\sa SmartGraph
+  class SmartDigraph : public ExtendedSmartDigraphBase {
+    typedef ExtendedSmartDigraphBase Parent;
+
+  private:
+    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
+    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
+    /// \brief Assignment of a digraph to another one is \e not allowed.
+    /// Use DigraphCopy instead.
+    void operator=(const SmartDigraph &) {}
+
+  public:
+
+    /// Constructor
+
+    /// Constructor.
+    ///
+    SmartDigraph() {};
+
+    ///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(); }
+
+    ///Add a new arc to the digraph.
+
+    ///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(Node s, Node t) {
+      return Parent::addArc(s, t);
+    }
+
+    /// \brief Node validity check
+    ///
+    /// 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
+    /// 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 \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
+    /// if new arcs are added to the graph.
+    bool valid(Arc a) const { return Parent::valid(a); }
+
+    ///Split a node.
+
+    ///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 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();
+      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);
+      return b;
+    }
+
+    ///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:
+
+    class Snapshot;
+
+  protected:
+
+    void restoreSnapshot(const Snapshot &s)
+    {
+      while(s.arc_num<arcs.size()) {
+        Arc arc = arcFromId(arcs.size()-1);
+        Parent::notifier(Arc()).erase(arc);
+        nodes[arcs.back().source].first_out=arcs.back().next_out;
+        nodes[arcs.back().target].first_in=arcs.back().next_in;
+        arcs.pop_back();
+      }
+      while(s.node_num<nodes.size()) {
+        Node node = nodeFromId(nodes.size()-1);
+        Parent::notifier(Node()).erase(node);
+        nodes.pop_back();
+      }
+    }
+
+  public:
+
+    ///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. 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
+    {
+      SmartDigraph *_graph;
+    protected:
+      friend class SmartDigraph;
+      unsigned int node_num;
+      unsigned int arc_num;
+    public:
+      ///Default constructor.
+
+      ///Default constructor.
+      ///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 given digraph.
+      ///
+      Snapshot(SmartDigraph &gr) : _graph(&gr) {
+        node_num=_graph->nodes.size();
+        arc_num=_graph->arcs.size();
+      }
+
+      ///Make a snapshot.
+
+      ///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.
+      void save(SmartDigraph &gr) {
+        _graph=&gr;
+        node_num=_graph->nodes.size();
+        arc_num=_graph->arcs.size();
+      }
+
+      ///Undo the changes until a snapshot.
+
+      ///This function undos the changes until the last snapshot
+      ///created by save() or Snapshot(SmartDigraph&).
+      void restore()
+      {
+        _graph->restoreSnapshot(*this);
+      }
+    };
+  };
+
+
+  class SmartGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+    };
+
+    struct ArcT {
+      int target;
+      int next_out;
+    };
+
+    std::vector<NodeT> nodes;
+    std::vector<ArcT> arcs;
+
+  public:
+
+    typedef SmartGraphBase Graph;
+
+    class Node;
+    class Arc;
+    class Edge;
+
+    class Node {
+      friend class SmartGraphBase;
+    protected:
+
+      int _id;
+      explicit Node(int id) { _id = id;}
+
+    public:
+      Node() {}
+      Node (Invalid) { _id = -1; }
+      bool operator==(const Node& node) const {return _id == node._id;}
+      bool operator!=(const Node& node) const {return _id != node._id;}
+      bool operator<(const Node& node) const {return _id < node._id;}
+    };
+
+    class Edge {
+      friend class SmartGraphBase;
+    protected:
+
+      int _id;
+      explicit Edge(int id) { _id = id;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { _id = -1; }
+      bool operator==(const Edge& arc) const {return _id == arc._id;}
+      bool operator!=(const Edge& arc) const {return _id != arc._id;}
+      bool operator<(const Edge& arc) const {return _id < arc._id;}
+    };
+
+    class Arc {
+      friend class SmartGraphBase;
+    protected:
+
+      int _id;
+      explicit Arc(int id) { _id = id;}
+
+    public:
+      operator Edge() const {
+        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
+      }
+
+      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;}
+    };
+
+
+
+    SmartGraphBase()
+      : nodes(), arcs() {}
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return nodes.size(); }
+    int edgeNum() const { return arcs.size() / 2; }
+    int arcNum() const { return arcs.size(); }
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
+    Node target(Arc e) const { return Node(arcs[e._id].target); }
+
+    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
+    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
+
+    static bool direction(Arc e) {
+      return (e._id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e._id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = nodes.size() - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = arcs.size() - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void first(Edge& arc) const {
+      arc._id = arcs.size() / 2 - 1;
+    }
+
+    static void next(Edge& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc &arc, const Node& v) const {
+      arc._id = nodes[v._id].first_out;
+    }
+    void nextOut(Arc &arc) const {
+      arc._id = arcs[arc._id].next_out;
+    }
+
+    void firstIn(Arc &arc, const Node& v) const {
+      arc._id = ((nodes[v._id].first_out) ^ 1);
+      if (arc._id == -2) arc._id = -1;
+    }
+    void nextIn(Arc &arc) const {
+      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
+      if (arc._id == -2) arc._id = -1;
+    }
+
+    void firstInc(Edge &arc, bool& d, const Node& v) const {
+      int de = nodes[v._id].first_out;
+      if (de != -1) {
+        arc._id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        arc._id = -1;
+        d = true;
+      }
+    }
+    void nextInc(Edge &arc, bool& d) const {
+      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
+      if (de != -1) {
+        arc._id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        arc._id = -1;
+        d = true;
+      }
+    }
+
+    static int id(Node v) { return v._id; }
+    static int id(Arc e) { return e._id; }
+    static int id(Edge e) { return e._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
+    }
+    bool valid(Arc a) const {
+      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
+    }
+    bool valid(Edge e) const {
+      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
+    }
+
+    Node addNode() {
+      int n = nodes.size();
+      nodes.push_back(NodeT());
+      nodes[n].first_out = -1;
+
+      return Node(n);
+    }
+
+    Edge addEdge(Node u, Node v) {
+      int n = arcs.size();
+      arcs.push_back(ArcT());
+      arcs.push_back(ArcT());
+
+      arcs[n].target = u._id;
+      arcs[n | 1].target = v._id;
+
+      arcs[n].next_out = nodes[v._id].first_out;
+      nodes[v._id].first_out = n;
+
+      arcs[n | 1].next_out = nodes[u._id].first_out;
+      nodes[u._id].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+    }
+
+  };
+
+  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief A smart undirected graph class.
+  ///
+  /// \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:
+    /// Graphs are \e not copy constructible. Use GraphCopy instead.
+    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use GraphCopy instead.
+    void operator=(const SmartGraph &) {}
+
+  public:
+
+    /// Constructor
+
+    /// Constructor.
+    ///
+    SmartGraph() {}
+
+    /// \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(); }
+
+    /// \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 \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
+    /// 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 \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
+    /// if new edges are added to the graph.
+    bool valid(Arc a) const { return Parent::valid(a); }
+
+    ///Clear 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:
+
+    class Snapshot;
+
+  protected:
+
+    void saveSnapshot(Snapshot &s)
+    {
+      s._graph = this;
+      s.node_num = nodes.size();
+      s.arc_num = arcs.size();
+    }
+
+    void restoreSnapshot(const Snapshot &s)
+    {
+      while(s.arc_num<arcs.size()) {
+        int n=arcs.size()-1;
+        Edge arc=edgeFromId(n/2);
+        Parent::notifier(Edge()).erase(arc);
+        std::vector<Arc> dir;
+        dir.push_back(arcFromId(n));
+        dir.push_back(arcFromId(n-1));
+        Parent::notifier(Arc()).erase(dir);
+        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
+        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
+        arcs.pop_back();
+        arcs.pop_back();
+      }
+      while(s.node_num<nodes.size()) {
+        int n=nodes.size()-1;
+        Node node = nodeFromId(n);
+        Parent::notifier(Node()).erase(node);
+        nodes.pop_back();
+      }
+    }
+
+  public:
+
+    ///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
+    {
+      SmartGraph *_graph;
+    protected:
+      friend class SmartGraph;
+      unsigned int node_num;
+      unsigned int arc_num;
+    public:
+      ///Default constructor.
+
+      ///Default constructor.
+      ///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 given graph.
+      ///
+      Snapshot(SmartGraph &gr) {
+        gr.saveSnapshot(*this);
+      }
+
+      ///Make a snapshot.
+
+      ///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.
+      void save(SmartGraph &gr)
+      {
+        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()
+      {
+        _graph->restoreSnapshot(*this);
+      }
+    };
+  };
+
+  class SmartBpGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      int partition_next;
+      int partition_index;
+      bool red;
+    };
+
+    struct ArcT {
+      int target;
+      int next_out;
+    };
+
+    std::vector<NodeT> nodes;
+    std::vector<ArcT> arcs;
+
+    int first_red, first_blue;
+    int max_red, max_blue;
+
+  public:
+
+    typedef SmartBpGraphBase Graph;
+
+    class Node;
+    class Arc;
+    class Edge;
+
+    class Node {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit 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 RedNode : public Node {
+      friend class SmartBpGraphBase;
+    protected:
+
+      explicit RedNode(int pid) : Node(pid) {}
+
+    public:
+      RedNode() {}
+      RedNode(const RedNode& node) : Node(node) {}
+      RedNode(Invalid) : Node(INVALID){}
+    };
+
+    class BlueNode : public Node {
+      friend class SmartBpGraphBase;
+    protected:
+
+      explicit BlueNode(int pid) : Node(pid) {}
+
+    public:
+      BlueNode() {}
+      BlueNode(const BlueNode& node) : Node(node) {}
+      BlueNode(Invalid) : Node(INVALID){}
+    };
+
+    class Edge {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Edge(int id) { _id = id;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { _id = -1; }
+      bool operator==(const Edge& arc) const {return _id == arc._id;}
+      bool operator!=(const Edge& arc) const {return _id != arc._id;}
+      bool operator<(const Edge& arc) const {return _id < arc._id;}
+    };
+
+    class Arc {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Arc(int id) { _id = id;}
+
+    public:
+      operator Edge() const {
+        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
+      }
+
+      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;}
+    };
+
+
+
+    SmartBpGraphBase()
+      : nodes(), arcs(), first_red(-1), first_blue(-1),
+        max_red(-1), max_blue(-1) {}
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return nodes.size(); }
+    int redNum() const { return max_red + 1; }
+    int blueNum() const { return max_blue + 1; }
+    int edgeNum() const { return arcs.size() / 2; }
+    int arcNum() const { return arcs.size(); }
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxRedId() const { return max_red; }
+    int maxBlueId() const { return max_blue; }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    bool red(Node n) const { return nodes[n._id].red; }
+    bool blue(Node n) const { return !nodes[n._id].red; }
+
+    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
+    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
+
+    Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); }
+    Node target(Arc a) const { return Node(arcs[a._id].target); }
+
+    RedNode redNode(Edge e) const {
+      return RedNode(arcs[2 * e._id].target);
+    }
+    BlueNode blueNode(Edge e) const {
+      return BlueNode(arcs[2 * e._id + 1].target);
+    }
+
+    static bool direction(Arc a) {
+      return (a._id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e._id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = nodes.size() - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(RedNode& node) const {
+      node._id = first_red;
+    }
+
+    void next(RedNode& node) const {
+      node._id = nodes[node._id].partition_next;
+    }
+
+    void first(BlueNode& node) const {
+      node._id = first_blue;
+    }
+
+    void next(BlueNode& node) const {
+      node._id = nodes[node._id].partition_next;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = arcs.size() - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void first(Edge& arc) const {
+      arc._id = arcs.size() / 2 - 1;
+    }
+
+    static void next(Edge& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc &arc, const Node& v) const {
+      arc._id = nodes[v._id].first_out;
+    }
+    void nextOut(Arc &arc) const {
+      arc._id = arcs[arc._id].next_out;
+    }
+
+    void firstIn(Arc &arc, const Node& v) const {
+      arc._id = ((nodes[v._id].first_out) ^ 1);
+      if (arc._id == -2) arc._id = -1;
+    }
+    void nextIn(Arc &arc) const {
+      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
+      if (arc._id == -2) arc._id = -1;
+    }
+
+    void firstInc(Edge &arc, bool& d, const Node& v) const {
+      int de = nodes[v._id].first_out;
+      if (de != -1) {
+        arc._id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        arc._id = -1;
+        d = true;
+      }
+    }
+    void nextInc(Edge &arc, bool& d) const {
+      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
+      if (de != -1) {
+        arc._id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        arc._id = -1;
+        d = true;
+      }
+    }
+
+    static int id(Node v) { return v._id; }
+    int id(RedNode v) const { return nodes[v._id].partition_index; }
+    int id(BlueNode v) const { return nodes[v._id].partition_index; }
+    static int id(Arc e) { return e._id; }
+    static int id(Edge e) { return e._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
+    }
+    bool valid(Arc a) const {
+      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
+    }
+    bool valid(Edge e) const {
+      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
+    }
+
+    RedNode addRedNode() {
+      int n = nodes.size();
+      nodes.push_back(NodeT());
+      nodes[n].first_out = -1;
+      nodes[n].red = true;
+      nodes[n].partition_index = ++max_red;
+      nodes[n].partition_next = first_red;
+      first_red = n;
+
+      return RedNode(n);
+    }
+
+    BlueNode addBlueNode() {
+      int n = nodes.size();
+      nodes.push_back(NodeT());
+      nodes[n].first_out = -1;
+      nodes[n].red = false;
+      nodes[n].partition_index = ++max_blue;
+      nodes[n].partition_next = first_blue;
+      first_blue = n;
+
+      return BlueNode(n);
+    }
+
+    Edge addEdge(RedNode u, BlueNode v) {
+      int n = arcs.size();
+      arcs.push_back(ArcT());
+      arcs.push_back(ArcT());
+
+      arcs[n].target = u._id;
+      arcs[n | 1].target = v._id;
+
+      arcs[n].next_out = nodes[v._id].first_out;
+      nodes[v._id].first_out = n;
+
+      arcs[n | 1].next_out = nodes[u._id].first_out;
+      nodes[u._id].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_red = -1;
+      first_blue = -1;
+      max_blue = -1;
+      max_red = -1;
+    }
+
+  };
+
+  typedef BpGraphExtender<SmartBpGraphBase> ExtendedSmartBpGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief A smart undirected bipartite graph class.
+  ///
+  /// \ref SmartBpGraph is a simple and fast bipartite 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::BpGraph "BpGraph 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::BpGraph
+  /// \sa SmartGraph
+  class SmartBpGraph : public ExtendedSmartBpGraphBase {
+    typedef ExtendedSmartBpGraphBase Parent;
+
+  private:
+    /// Graphs are \e not copy constructible. Use GraphCopy instead.
+    SmartBpGraph(const SmartBpGraph &) : ExtendedSmartBpGraphBase() {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use GraphCopy instead.
+    void operator=(const SmartBpGraph &) {}
+
+  public:
+
+    /// Constructor
+
+    /// Constructor.
+    ///
+    SmartBpGraph() {}
+
+    /// \brief Add a new red node to the graph.
+    ///
+    /// This function adds a red new node to the graph.
+    /// \return The new node.
+    RedNode addRedNode() { return Parent::addRedNode(); }
+
+    /// \brief Add a new blue node to the graph.
+    ///
+    /// This function adds a blue new node to the graph.
+    /// \return The new node.
+    BlueNode addBlueNode() { return Parent::addBlueNode(); }
+
+    /// \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(RedNode u, BlueNode v) {
+      return Parent::addEdge(u, v);
+    }
+    Edge addEdge(BlueNode v, RedNode u) {
+      return Parent::addEdge(u, v);
+    }
+
+    /// \brief Node validity check
+    ///
+    /// 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
+    /// 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 \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
+    /// if new edges are added to the graph.
+    bool valid(Arc a) const { return Parent::valid(a); }
+
+    ///Clear 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:
+
+    class Snapshot;
+
+  protected:
+
+    void saveSnapshot(Snapshot &s)
+    {
+      s._graph = this;
+      s.node_num = nodes.size();
+      s.arc_num = arcs.size();
+    }
+
+    void restoreSnapshot(const Snapshot &s)
+    {
+      while(s.arc_num<arcs.size()) {
+        int n=arcs.size()-1;
+        Edge arc=edgeFromId(n/2);
+        Parent::notifier(Edge()).erase(arc);
+        std::vector<Arc> dir;
+        dir.push_back(arcFromId(n));
+        dir.push_back(arcFromId(n-1));
+        Parent::notifier(Arc()).erase(dir);
+        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
+        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
+        arcs.pop_back();
+        arcs.pop_back();
+      }
+      while(s.node_num<nodes.size()) {
+        int n=nodes.size()-1;
+        Node node = nodeFromId(n);
+        if (Parent::red(node)) {
+          first_red = nodes[n].partition_next;
+          if (first_red != -1) {
+            max_red = nodes[first_red].partition_index;
+          } else {
+            max_red = -1;
+          }
+          Parent::notifier(RedNode()).erase(asRedNodeUnsafe(node));
+        } else {
+          first_blue = nodes[n].partition_next;
+          if (first_blue != -1) {
+            max_blue = nodes[first_blue].partition_index;
+          } else {
+            max_blue = -1;
+          }
+          Parent::notifier(BlueNode()).erase(asBlueNodeUnsafe(node));
+        }
+        Parent::notifier(Node()).erase(node);
+        nodes.pop_back();
+      }
+    }
+
+  public:
+
+    ///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 SmartBpGraph 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
+    {
+      SmartBpGraph *_graph;
+    protected:
+      friend class SmartBpGraph;
+      unsigned int node_num;
+      unsigned int arc_num;
+    public:
+      ///Default constructor.
+
+      ///Default constructor.
+      ///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 given graph.
+      ///
+      Snapshot(SmartBpGraph &gr) {
+        gr.saveSnapshot(*this);
+      }
+
+      ///Make a snapshot.
+
+      ///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.
+      void save(SmartBpGraph &gr)
+      {
+        gr.saveSnapshot(*this);
+      }
+
+      ///Undo the changes until the last snapshot.
+
+      ///This function undos the changes until the last snapshot
+      ///created by save() or Snapshot(SmartBpGraph&).
+      void restore()
+      {
+        _graph->restoreSnapshot(*this);
+      }
+    };
+  };
+
+} //namespace lemon
+
+
+#endif //LEMON_SMART_GRAPH_H
diff --git a/lemon/soplex.cc b/lemon/soplex.cc
new file mode 100644
index 0000000..d751723
--- /dev/null
+++ b/lemon/soplex.cc
@@ -0,0 +1,465 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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/soplex.h>
+
+#include <soplex.h>
+#include <spxout.h>
+
+
+///\file
+///\brief Implementation of the LEMON-SOPLEX lp solver interface.
+namespace lemon {
+
+  SoplexLp::SoplexLp() {
+    soplex = new soplex::SoPlex;
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  SoplexLp::~SoplexLp() {
+    delete soplex;
+  }
+
+  SoplexLp::SoplexLp(const SoplexLp& lp) {
+    rows = lp.rows;
+    cols = lp.cols;
+
+    soplex = new soplex::SoPlex;
+    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
+
+    _col_names = lp._col_names;
+    _col_names_ref = lp._col_names_ref;
+
+    _row_names = lp._row_names;
+    _row_names_ref = lp._row_names_ref;
+
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  void SoplexLp::_clear_temporals() {
+    _primal_values.clear();
+    _dual_values.clear();
+  }
+
+  SoplexLp* SoplexLp::newSolver() const {
+    SoplexLp* newlp = new SoplexLp();
+    return newlp;
+  }
+
+  SoplexLp* SoplexLp::cloneSolver() const {
+    SoplexLp* newlp = new SoplexLp(*this);
+    return newlp;
+  }
+
+  const char* SoplexLp::_solverName() const { return "SoplexLp"; }
+
+  int SoplexLp::_addCol() {
+    soplex::LPCol c;
+    c.setLower(-soplex::infinity);
+    c.setUpper(soplex::infinity);
+    soplex->addCol(c);
+
+    _col_names.push_back(std::string());
+
+    return soplex->nCols() - 1;
+  }
+
+  int SoplexLp::_addRow() {
+    soplex::LPRow r;
+    r.setLhs(-soplex::infinity);
+    r.setRhs(soplex::infinity);
+    soplex->addRow(r);
+
+    _row_names.push_back(std::string());
+
+    return soplex->nRows() - 1;
+  }
+
+  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) {
+    soplex->removeCol(i);
+    _col_names_ref.erase(_col_names[i]);
+    _col_names[i] = _col_names.back();
+    _col_names_ref[_col_names.back()] = i;
+    _col_names.pop_back();
+  }
+
+  void SoplexLp::_eraseRow(int i) {
+    soplex->removeRow(i);
+    _row_names_ref.erase(_row_names[i]);
+    _row_names[i] = _row_names.back();
+    _row_names_ref[_row_names.back()] = i;
+    _row_names.pop_back();
+  }
+
+  void SoplexLp::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.relocateIndex(i, cols.maxIndex());
+  }
+  void SoplexLp::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.relocateIndex(i, rows.maxIndex());
+  }
+
+  void SoplexLp::_getColName(int c, std::string &name) const {
+    name = _col_names[c];
+  }
+
+  void SoplexLp::_setColName(int c, const std::string &name) {
+    _col_names_ref.erase(_col_names[c]);
+    _col_names[c] = name;
+    if (!name.empty()) {
+      _col_names_ref.insert(std::make_pair(name, c));
+    }
+  }
+
+  int SoplexLp::_colByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it =
+      _col_names_ref.find(name);
+    if (it != _col_names_ref.end()) {
+      return it->second;
+    } else {
+      return -1;
+    }
+  }
+
+  void SoplexLp::_getRowName(int r, std::string &name) const {
+    name = _row_names[r];
+  }
+
+  void SoplexLp::_setRowName(int r, const std::string &name) {
+    _row_names_ref.erase(_row_names[r]);
+    _row_names[r] = name;
+    if (!name.empty()) {
+      _row_names_ref.insert(std::make_pair(name, r));
+    }
+  }
+
+  int SoplexLp::_rowByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it =
+      _row_names_ref.find(name);
+    if (it != _row_names_ref.end()) {
+      return it->second;
+    } else {
+      return -1;
+    }
+  }
+
+
+  void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      soplex->changeElement(i, j, 0.0);
+    }
+    for(ExprIterator it = b; it != e; ++it) {
+      soplex->changeElement(i, it->first, it->second);
+    }
+  }
+
+  void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const {
+    const soplex::SVector& vec = soplex->rowVector(i);
+    for (int k = 0; k < vec.size(); ++k) {
+      *b = std::make_pair(vec.index(k), vec.value(k));
+      ++b;
+    }
+  }
+
+  void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
+    for (int i = 0; i < soplex->nRows(); ++i) {
+      soplex->changeElement(i, j, 0.0);
+    }
+    for(ExprIterator it = b; it != e; ++it) {
+      soplex->changeElement(it->first, j, it->second);
+    }
+  }
+
+  void SoplexLp::_getColCoeffs(int i, InsertIterator b) const {
+    const soplex::SVector& vec = soplex->colVector(i);
+    for (int k = 0; k < vec.size(); ++k) {
+      *b = std::make_pair(vec.index(k), vec.value(k));
+      ++b;
+    }
+  }
+
+  void SoplexLp::_setCoeff(int i, int j, Value value) {
+    soplex->changeElement(i, j, value);
+  }
+
+  SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const {
+    return soplex->rowVector(i)[j];
+  }
+
+  void SoplexLp::_setColLowerBound(int i, Value value) {
+    LEMON_ASSERT(value != INF, "Invalid bound");
+    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
+  }
+
+  SoplexLp::Value SoplexLp::_getColLowerBound(int i) const {
+    double value = soplex->lower(i);
+    return value != -soplex::infinity ? value : -INF;
+  }
+
+  void SoplexLp::_setColUpperBound(int i, Value value) {
+    LEMON_ASSERT(value != -INF, "Invalid bound");
+    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
+  }
+
+  SoplexLp::Value SoplexLp::_getColUpperBound(int i) const {
+    double value = soplex->upper(i);
+    return value != soplex::infinity ? value : INF;
+  }
+
+  void SoplexLp::_setRowLowerBound(int i, Value lb) {
+    LEMON_ASSERT(lb != INF, "Invalid bound");
+    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
+  }
+
+  SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const {
+    double res = soplex->lhs(i);
+    return res == -soplex::infinity ? -INF : res;
+  }
+
+  void SoplexLp::_setRowUpperBound(int i, Value ub) {
+    LEMON_ASSERT(ub != -INF, "Invalid bound");
+    soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
+  }
+
+  SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const {
+    double res = soplex->rhs(i);
+    return res == soplex::infinity ? INF : res;
+  }
+
+  void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      soplex->changeObj(j, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      soplex->changeObj(it->first, it->second);
+    }
+  }
+
+  void SoplexLp::_getObjCoeffs(InsertIterator b) const {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      Value coef = soplex->obj(j);
+      if (coef != 0.0) {
+        *b = std::make_pair(j, coef);
+        ++b;
+      }
+    }
+  }
+
+  void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
+    soplex->changeObj(i, obj_coef);
+  }
+
+  SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
+    return soplex->obj(i);
+  }
+
+  SoplexLp::SolveExitStatus SoplexLp::_solve() {
+
+    _clear_temporals();
+
+    _applyMessageLevel();
+
+    soplex::SPxSolver::Status status = soplex->solve();
+
+    switch (status) {
+    case soplex::SPxSolver::OPTIMAL:
+    case soplex::SPxSolver::INFEASIBLE:
+    case soplex::SPxSolver::UNBOUNDED:
+      return SOLVED;
+    default:
+      return UNSOLVED;
+    }
+  }
+
+  SoplexLp::Value SoplexLp::_getPrimal(int i) const {
+    if (_primal_values.empty()) {
+      _primal_values.resize(soplex->nCols());
+      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
+      soplex->getPrimal(pv);
+    }
+    return _primal_values[i];
+  }
+
+  SoplexLp::Value SoplexLp::_getDual(int i) const {
+    if (_dual_values.empty()) {
+      _dual_values.resize(soplex->nRows());
+      soplex::Vector dv(_dual_values.size(), &_dual_values.front());
+      soplex->getDual(dv);
+    }
+    return _dual_values[i];
+  }
+
+  SoplexLp::Value SoplexLp::_getPrimalValue() const {
+    return soplex->objValue();
+  }
+
+  SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const {
+    switch (soplex->getBasisColStatus(i)) {
+    case soplex::SPxSolver::BASIC:
+      return BASIC;
+    case soplex::SPxSolver::ON_UPPER:
+      return UPPER;
+    case soplex::SPxSolver::ON_LOWER:
+      return LOWER;
+    case soplex::SPxSolver::FIXED:
+      return FIXED;
+    case soplex::SPxSolver::ZERO:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return VarStatus();
+    }
+  }
+
+  SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const {
+    switch (soplex->getBasisRowStatus(i)) {
+    case soplex::SPxSolver::BASIC:
+      return BASIC;
+    case soplex::SPxSolver::ON_UPPER:
+      return UPPER;
+    case soplex::SPxSolver::ON_LOWER:
+      return LOWER;
+    case soplex::SPxSolver::FIXED:
+      return FIXED;
+    case soplex::SPxSolver::ZERO:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return VarStatus();
+    }
+  }
+
+  SoplexLp::Value SoplexLp::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      _primal_ray.resize(soplex->nCols());
+      soplex::Vector pv(_primal_ray.size(), &_primal_ray.front());
+      soplex->getDualfarkas(pv);
+    }
+    return _primal_ray[i];
+  }
+
+  SoplexLp::Value SoplexLp::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+      _dual_ray.resize(soplex->nRows());
+      soplex::Vector dv(_dual_ray.size(), &_dual_ray.front());
+      soplex->getDualfarkas(dv);
+    }
+    return _dual_ray[i];
+  }
+
+  SoplexLp::ProblemType SoplexLp::_getPrimalType() const {
+    switch (soplex->status()) {
+    case soplex::SPxSolver::OPTIMAL:
+      return OPTIMAL;
+    case soplex::SPxSolver::UNBOUNDED:
+      return UNBOUNDED;
+    case soplex::SPxSolver::INFEASIBLE:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+  }
+
+  SoplexLp::ProblemType SoplexLp::_getDualType() const {
+    switch (soplex->status()) {
+    case soplex::SPxSolver::OPTIMAL:
+      return OPTIMAL;
+    case soplex::SPxSolver::UNBOUNDED:
+      return UNBOUNDED;
+    case soplex::SPxSolver::INFEASIBLE:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+  }
+
+  void SoplexLp::_setSense(Sense sense) {
+    switch (sense) {
+    case MIN:
+      soplex->changeSense(soplex::SPxSolver::MINIMIZE);
+      break;
+    case MAX:
+      soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
+    }
+  }
+
+  SoplexLp::Sense SoplexLp::_getSense() const {
+    switch (soplex->spxSense()) {
+    case soplex::SPxSolver::MAXIMIZE:
+      return MAX;
+    case soplex::SPxSolver::MINIMIZE:
+      return MIN;
+    default:
+      LEMON_ASSERT(false, "Wrong sense.");
+      return SoplexLp::Sense();
+    }
+  }
+
+  void SoplexLp::_clear() {
+    soplex->clear();
+    _col_names.clear();
+    _col_names_ref.clear();
+    _row_names.clear();
+    _row_names_ref.clear();
+    cols.clear();
+    rows.clear();
+    _clear_temporals();
+  }
+
+  void SoplexLp::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _message_level = -1;
+      break;
+    case MESSAGE_ERROR:
+      _message_level = soplex::SPxOut::ERROR;
+      break;
+    case MESSAGE_WARNING:
+      _message_level = soplex::SPxOut::WARNING;
+      break;
+    case MESSAGE_NORMAL:
+      _message_level = soplex::SPxOut::INFO2;
+      break;
+    case MESSAGE_VERBOSE:
+      _message_level = soplex::SPxOut::DEBUG;
+      break;
+    }
+  }
+
+  void SoplexLp::_applyMessageLevel() {
+    soplex::Param::setVerbose(_message_level);
+  }
+
+} //namespace lemon
+
diff --git a/lemon/soplex.h b/lemon/soplex.h
new file mode 100644
index 0000000..be73f3a
--- /dev/null
+++ b/lemon/soplex.h
@@ -0,0 +1,158 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_SOPLEX_H
+#define LEMON_SOPLEX_H
+
+///\file
+///\brief Header of the LEMON-SOPLEX lp solver interface.
+
+#include <vector>
+#include <string>
+
+#include <lemon/lp_base.h>
+
+// Forward declaration
+namespace soplex {
+  class SoPlex;
+}
+
+namespace lemon {
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Interface for the SOPLEX solver
+  ///
+  /// This class implements an interface for the SoPlex LP solver.
+  /// The SoPlex library is an object oriented lp solver library
+  /// developed at the Konrad-Zuse-Zentrum f�r Informationstechnik
+  /// Berlin (ZIB). You can find detailed information about it at the
+  /// <tt>http://soplex.zib.de</tt> address.
+  class SoplexLp : public LpSolver {
+  private:
+
+    soplex::SoPlex* soplex;
+
+    std::vector<std::string> _col_names;
+    std::map<std::string, int> _col_names_ref;
+
+    std::vector<std::string> _row_names;
+    std::map<std::string, int> _row_names_ref;
+
+  private:
+
+    // these values cannot be retrieved element by element
+    mutable std::vector<Value> _primal_values;
+    mutable std::vector<Value> _dual_values;
+
+    mutable std::vector<Value> _primal_ray;
+    mutable std::vector<Value> _dual_ray;
+
+    void _clear_temporals();
+
+  public:
+
+    /// \e
+    SoplexLp();
+    /// \e
+    SoplexLp(const SoplexLp&);
+    /// \e
+    ~SoplexLp();
+    /// \e
+    virtual SoplexLp* newSolver() const;
+    /// \e
+    virtual SoplexLp* cloneSolver() const;
+
+  protected:
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+    virtual void _clear();
+
+    void _messageLevel(MessageLevel m);
+    void _applyMessageLevel();
+
+    int _message_level;
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_SOPLEX_H
+
diff --git a/lemon/static_graph.h b/lemon/static_graph.h
new file mode 100644
index 0000000..1f04e40
--- /dev/null
+++ b/lemon/static_graph.h
@@ -0,0 +1,476 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_STATIC_GRAPH_H
+#define LEMON_STATIC_GRAPH_H
+
+///\ingroup graphs
+///\file
+///\brief StaticDigraph class.
+
+#include <lemon/core.h>
+#include <lemon/bits/graph_extender.h>
+
+namespace lemon {
+
+  class StaticDigraphBase {
+  public:
+
+    StaticDigraphBase()
+      : built(false), node_num(0), arc_num(0),
+        node_first_out(NULL), node_first_in(NULL),
+        arc_source(NULL), arc_target(NULL),
+        arc_next_in(NULL), arc_next_out(NULL) {}
+
+    ~StaticDigraphBase() {
+      if (built) {
+        delete[] node_first_out;
+        delete[] node_first_in;
+        delete[] arc_source;
+        delete[] arc_target;
+        delete[] arc_next_out;
+        delete[] arc_next_in;
+      }
+    }
+
+    class Node {
+      friend class StaticDigraphBase;
+    protected:
+      int id;
+      Node(int _id) : id(_id) {}
+    public:
+      Node() {}
+      Node (Invalid) : id(-1) {}
+      bool operator==(const Node& node) const { return id == node.id; }
+      bool operator!=(const Node& node) const { return id != node.id; }
+      bool operator<(const Node& node) const { return id < node.id; }
+    };
+
+    class Arc {
+      friend class StaticDigraphBase;
+    protected:
+      int id;
+      Arc(int _id) : id(_id) {}
+    public:
+      Arc() { }
+      Arc (Invalid) : id(-1) {}
+      bool operator==(const Arc& arc) const { return id == arc.id; }
+      bool operator!=(const Arc& arc) const { return id != arc.id; }
+      bool operator<(const Arc& arc) const { return id < arc.id; }
+    };
+
+    Node source(const Arc& e) const { return Node(arc_source[e.id]); }
+    Node target(const Arc& e) const { return Node(arc_target[e.id]); }
+
+    void first(Node& n) const { n.id = node_num - 1; }
+    static void next(Node& n) { --n.id; }
+
+    void first(Arc& e) const { e.id = arc_num - 1; }
+    static void next(Arc& e) { --e.id; }
+
+    void firstOut(Arc& e, const Node& n) const {
+      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ?
+        node_first_out[n.id] : -1;
+    }
+    void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
+
+    void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
+    void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
+
+    static int id(const Node& n) { return n.id; }
+    static Node nodeFromId(int id) { return Node(id); }
+    int maxNodeId() const { return node_num - 1; }
+
+    static int id(const Arc& e) { return e.id; }
+    static Arc arcFromId(int id) { return Arc(id); }
+    int maxArcId() const { return arc_num - 1; }
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return node_num; }
+    int arcNum() const { return arc_num; }
+
+  private:
+
+    template <typename Digraph, typename NodeRefMap>
+    class ArcLess {
+    public:
+      typedef typename Digraph::Arc Arc;
+
+      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
+        : digraph(_graph), nodeRef(_nodeRef) {}
+
+      bool operator()(const Arc& left, const Arc& right) const {
+        return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
+      }
+    private:
+      const Digraph& digraph;
+      const NodeRefMap& nodeRef;
+    };
+
+  public:
+
+    typedef True BuildTag;
+
+    void clear() {
+      if (built) {
+        delete[] node_first_out;
+        delete[] node_first_in;
+        delete[] arc_source;
+        delete[] arc_target;
+        delete[] arc_next_out;
+        delete[] arc_next_in;
+      }
+      built = false;
+      node_num = 0;
+      arc_num = 0;
+    }
+
+    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
+    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
+      typedef typename Digraph::Node GNode;
+      typedef typename Digraph::Arc GArc;
+
+      built = true;
+
+      node_num = countNodes(digraph);
+      arc_num = countArcs(digraph);
+
+      node_first_out = new int[node_num + 1];
+      node_first_in = new int[node_num];
+
+      arc_source = new int[arc_num];
+      arc_target = new int[arc_num];
+      arc_next_out = new int[arc_num];
+      arc_next_in = new int[arc_num];
+
+      int node_index = 0;
+      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+        nodeRef[n] = Node(node_index);
+        node_first_in[node_index] = -1;
+        ++node_index;
+      }
+
+      ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
+
+      int arc_index = 0;
+      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+        int source = nodeRef[n].id;
+        std::vector<GArc> arcs;
+        for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
+          arcs.push_back(e);
+        }
+        if (!arcs.empty()) {
+          node_first_out[source] = arc_index;
+          std::sort(arcs.begin(), arcs.end(), arcLess);
+          for (typename std::vector<GArc>::iterator it = arcs.begin();
+               it != arcs.end(); ++it) {
+            int target = nodeRef[digraph.target(*it)].id;
+            arcRef[*it] = Arc(arc_index);
+            arc_source[arc_index] = source;
+            arc_target[arc_index] = target;
+            arc_next_in[arc_index] = node_first_in[target];
+            node_first_in[target] = arc_index;
+            arc_next_out[arc_index] = arc_index + 1;
+            ++arc_index;
+          }
+          arc_next_out[arc_index - 1] = -1;
+        } else {
+          node_first_out[source] = arc_index;
+        }
+      }
+      node_first_out[node_num] = arc_num;
+    }
+
+    template <typename ArcListIterator>
+    void build(int n, ArcListIterator first, ArcListIterator last) {
+      built = true;
+
+      node_num = n;
+      arc_num = std::distance(first, last);
+
+      node_first_out = new int[node_num + 1];
+      node_first_in = new int[node_num];
+
+      arc_source = new int[arc_num];
+      arc_target = new int[arc_num];
+      arc_next_out = new int[arc_num];
+      arc_next_in = new int[arc_num];
+
+      for (int i = 0; i != node_num; ++i) {
+        node_first_in[i] = -1;
+      }
+
+      int arc_index = 0;
+      for (int i = 0; i != node_num; ++i) {
+        node_first_out[i] = arc_index;
+        for ( ; first != last && (*first).first == i; ++first) {
+          int j = (*first).second;
+          LEMON_ASSERT(j >= 0 && j < node_num,
+            "Wrong arc list for StaticDigraph::build()");
+          arc_source[arc_index] = i;
+          arc_target[arc_index] = j;
+          arc_next_in[arc_index] = node_first_in[j];
+          node_first_in[j] = arc_index;
+          arc_next_out[arc_index] = arc_index + 1;
+          ++arc_index;
+        }
+        if (arc_index > node_first_out[i])
+          arc_next_out[arc_index - 1] = -1;
+      }
+      LEMON_ASSERT(first == last,
+        "Wrong arc list for StaticDigraph::build()");
+      node_first_out[node_num] = arc_num;
+    }
+
+  protected:
+
+    void fastFirstOut(Arc& e, const Node& n) const {
+      e.id = node_first_out[n.id];
+    }
+
+    static void fastNextOut(Arc& e) {
+      ++e.id;
+    }
+    void fastLastOut(Arc& e, const Node& n) const {
+      e.id = node_first_out[n.id + 1];
+    }
+
+  protected:
+    bool built;
+    int node_num;
+    int arc_num;
+    int *node_first_out;
+    int *node_first_in;
+    int *arc_source;
+    int *arc_target;
+    int *arc_next_in;
+    int *arc_next_out;
+  };
+
+  typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
+
+
+  /// \ingroup graphs
+  ///
+  /// \brief A static directed graph class.
+  ///
+  /// \ref StaticDigraph is a highly efficient digraph implementation,
+  /// but it is fully static.
+  /// It stores only two \c int values for each node and only four \c int
+  /// values for each arc. Moreover it provides faster item iteration than
+  /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
+  /// iterators, since its arcs are stored in an appropriate order.
+  /// However it only provides build() and clear() functions and does not
+  /// support any other modification of the digraph.
+  ///
+  /// Since this digraph structure is completely static, its nodes and arcs
+  /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
+  /// and <tt>[0..arcNum()-1]</tt>, respectively.
+  /// The index of an item is the same as its ID, it can be obtained
+  /// using the corresponding \ref index() or \ref concepts::Digraph::id()
+  /// "id()" function. A node or arc with a certain index can be obtained
+  /// using node() or arc().
+  ///
+  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes and arcs.
+  ///
+  /// \sa concepts::Digraph
+  class StaticDigraph : public ExtendedStaticDigraphBase {
+  public:
+
+    typedef ExtendedStaticDigraphBase Parent;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Default constructor.
+    StaticDigraph() : Parent() {}
+
+    /// \brief The node with the given index.
+    ///
+    /// This function returns the node with the given index.
+    /// \sa index()
+    static Node node(int ix) { return Parent::nodeFromId(ix); }
+
+    /// \brief The arc with the given index.
+    ///
+    /// This function returns the arc with the given index.
+    /// \sa index()
+    static Arc arc(int ix) { return Parent::arcFromId(ix); }
+
+    /// \brief The index of the given node.
+    ///
+    /// This function returns the index of the the given node.
+    /// \sa node()
+    static int index(Node node) { return Parent::id(node); }
+
+    /// \brief The index of the given arc.
+    ///
+    /// This function returns the index of the the given arc.
+    /// \sa arc()
+    static int index(Arc arc) { return Parent::id(arc); }
+
+    /// \brief Number of nodes.
+    ///
+    /// This function returns the number of nodes.
+    int nodeNum() const { return node_num; }
+
+    /// \brief Number of arcs.
+    ///
+    /// This function returns the number of arcs.
+    int arcNum() const { return arc_num; }
+
+    /// \brief Build the digraph copying another digraph.
+    ///
+    /// This function builds the digraph copying another digraph of any
+    /// kind. It can be called more than once, but in such case, the whole
+    /// structure and all maps will be cleared and rebuilt.
+    ///
+    /// This method also makes possible to copy a digraph to a StaticDigraph
+    /// structure using \ref DigraphCopy.
+    ///
+    /// \param digraph An existing digraph to be copied.
+    /// \param nodeRef The node references will be copied into this map.
+    /// Its key type must be \c Digraph::Node and its value type must be
+    /// \c StaticDigraph::Node.
+    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
+    /// concept.
+    /// \param arcRef The arc references will be copied into this map.
+    /// Its key type must be \c Digraph::Arc and its value type must be
+    /// \c StaticDigraph::Arc.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///
+    /// \note If you do not need the arc references, then you could use
+    /// \ref NullMap for the last parameter. However the node references
+    /// are required by the function itself, thus they must be readable
+    /// from the map.
+    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
+    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
+      if (built) Parent::clear();
+      Parent::build(digraph, nodeRef, arcRef);
+    }
+
+    /// \brief Build the digraph from an arc list.
+    ///
+    /// This function builds the digraph from the given arc list.
+    /// It can be called more than once, but in such case, the whole
+    /// structure and all maps will be cleared and rebuilt.
+    ///
+    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
+    /// specified by STL compatible itartors whose \c value_type must be
+    /// <tt>std::pair<int,int></tt>.
+    /// Each arc must be specified by a pair of integer indices
+    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
+    /// non-decreasing order with respect to their first values.</i>
+    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
+    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
+    ///
+    /// \param n The number of nodes.
+    /// \param begin An iterator pointing to the beginning of the arc list.
+    /// \param end An iterator pointing to the end of the arc list.
+    ///
+    /// For example, a simple digraph can be constructed like this.
+    /// \code
+    ///   std::vector<std::pair<int,int> > arcs;
+    ///   arcs.push_back(std::make_pair(0,1));
+    ///   arcs.push_back(std::make_pair(0,2));
+    ///   arcs.push_back(std::make_pair(1,3));
+    ///   arcs.push_back(std::make_pair(1,2));
+    ///   arcs.push_back(std::make_pair(3,0));
+    ///   StaticDigraph gr;
+    ///   gr.build(4, arcs.begin(), arcs.end());
+    /// \endcode
+    template <typename ArcListIterator>
+    void build(int n, ArcListIterator begin, ArcListIterator end) {
+      if (built) Parent::clear();
+      StaticDigraphBase::build(n, begin, end);
+      notifier(Node()).build();
+      notifier(Arc()).build();
+    }
+
+    /// \brief Clear the digraph.
+    ///
+    /// This function erases all nodes and arcs from the digraph.
+    void clear() {
+      Parent::clear();
+    }
+
+  protected:
+
+    using Parent::fastFirstOut;
+    using Parent::fastNextOut;
+    using Parent::fastLastOut;
+
+  public:
+
+    class OutArcIt : public Arc {
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const StaticDigraph& digraph, const Node& node) {
+        digraph.fastFirstOut(*this, node);
+        digraph.fastLastOut(last, node);
+        if (last == *this) *this = INVALID;
+      }
+
+      OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
+        if (arc != INVALID) {
+          digraph.fastLastOut(last, digraph.source(arc));
+        }
+      }
+
+      OutArcIt& operator++() {
+        StaticDigraph::fastNextOut(*this);
+        if (last == *this) *this = INVALID;
+        return *this;
+      }
+
+    private:
+      Arc last;
+    };
+
+    Node baseNode(const OutArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+    Node runningNode(const OutArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    Node baseNode(const InArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    Node runningNode(const InArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+  };
+
+}
+
+#endif
diff --git a/lemon/suurballe.h b/lemon/suurballe.h
new file mode 100644
index 0000000..f1338a2
--- /dev/null
+++ b/lemon/suurballe.h
@@ -0,0 +1,776 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_SUURBALLE_H
+#define LEMON_SUURBALLE_H
+
+///\ingroup shortest_path
+///\file
+///\brief An algorithm for finding arc-disjoint paths between two
+/// nodes having minimum total length.
+
+#include <vector>
+#include <limits>
+#include <lemon/bin_heap.h>
+#include <lemon/path.h>
+#include <lemon/list_graph.h>
+#include <lemon/dijkstra.h>
+#include <lemon/maps.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of Suurballe algorithm.
+  ///
+  /// Default traits class of Suurballe algorithm.
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam LEN The type of the length map.
+  /// The default value is <tt>GR::ArcMap<int></tt>.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN>
+#else
+  template < typename GR,
+             typename LEN = typename GR::template ArcMap<int> >
+#endif
+  struct SuurballeDefaultTraits
+  {
+    /// The type of the digraph.
+    typedef GR Digraph;
+    /// The type of the length map.
+    typedef LEN LengthMap;
+    /// The type of the lengths.
+    typedef typename LEN::Value Length;
+    /// The type of the flow map.
+    typedef typename GR::template ArcMap<int> FlowMap;
+    /// The type of the potential map.
+    typedef typename GR::template NodeMap<Length> PotentialMap;
+
+    /// \brief The path type
+    ///
+    /// The type used for storing the found arc-disjoint paths.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    typedef lemon::Path<Digraph> Path;
+
+    /// The cross reference type used for the heap.
+    typedef typename GR::template NodeMap<int> HeapCrossRef;
+
+    /// \brief The heap type used for internal Dijkstra computations.
+    ///
+    /// The type of the heap used for internal Dijkstra computations.
+    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept
+    /// and its priority type must be \c Length.
+    typedef BinHeap<Length, HeapCrossRef> Heap;
+  };
+
+  /// \addtogroup shortest_path
+  /// @{
+
+  /// \brief Algorithm for finding arc-disjoint paths between two nodes
+  /// having minimum total length.
+  ///
+  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
+  /// finding arc-disjoint paths having minimum total length (cost)
+  /// from a given source node to a given target node in a digraph.
+  ///
+  /// Note that this problem is a special case of the \ref min_cost_flow
+  /// "minimum cost flow problem". This implementation is actually an
+  /// efficient specialized version of the \ref CapacityScaling
+  /// "successive shortest path" algorithm directly for this problem.
+  /// Therefore this class provides query functions for flow values and
+  /// node potentials (the dual solution) just like the minimum cost flow
+  /// algorithms.
+  ///
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam LEN The type of the length map.
+  /// The default value is <tt>GR::ArcMap<int></tt>.
+  ///
+  /// \warning Length values should be \e non-negative.
+  ///
+  /// \note For finding \e node-disjoint paths, this algorithm can be used
+  /// along with the \ref SplitNodes adaptor.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN, typename TR>
+#else
+  template < typename GR,
+             typename LEN = typename GR::template ArcMap<int>,
+             typename TR = SuurballeDefaultTraits<GR, LEN> >
+#endif
+  class Suurballe
+  {
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+    typedef ConstMap<Arc, int> ConstArcMap;
+    typedef typename GR::template NodeMap<Arc> PredMap;
+
+  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 lengths.
+    typedef typename TR::Length Length;
+
+    /// The type of the flow map.
+    typedef typename TR::FlowMap FlowMap;
+    /// The type of the potential map.
+    typedef typename TR::PotentialMap PotentialMap;
+    /// The type of the path structures.
+    typedef typename TR::Path Path;
+    /// The cross reference type used for the heap.
+    typedef typename TR::HeapCrossRef HeapCrossRef;
+    /// The heap type used for internal Dijkstra computations.
+    typedef typename TR::Heap Heap;
+
+    /// The \ref lemon::SuurballeDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
+
+  private:
+
+    // ResidualDijkstra is a special implementation of the
+    // Dijkstra algorithm for finding shortest paths in the
+    // residual network with respect to the reduced arc lengths
+    // and modifying the node potentials according to the
+    // distance of the nodes.
+    class ResidualDijkstra
+    {
+    private:
+
+      const Digraph &_graph;
+      const LengthMap &_length;
+      const FlowMap &_flow;
+      PotentialMap &_pi;
+      PredMap &_pred;
+      Node _s;
+      Node _t;
+
+      PotentialMap _dist;
+      std::vector<Node> _proc_nodes;
+
+    public:
+
+      // 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);
+        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(), 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
+          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
+            if (_flow[e] == 0) {
+              v = _graph.target(e);
+              switch(heap.state(v)) {
+                case Heap::PRE_HEAP:
+                  heap.push(v, d + _length[e] - _pi[v]);
+                  _pred[v] = e;
+                  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;
+              }
+            }
+          }
+
+          // Traverse incoming arcs
+          for (InArcIt e(_graph, u); e != INVALID; ++e) {
+            if (_flow[e] == 1) {
+              v = _graph.source(e);
+              switch(heap.state(v)) {
+                case Heap::PRE_HEAP:
+                  heap.push(v, d - _length[e] - _pi[v]);
+                  _pred[v] = e;
+                  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;
+              }
+            }
+          }
+        }
+        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;
+      }
+
+    }; //class ResidualDijkstra
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetFlowMapTraits : public Traits {
+      typedef T FlowMap;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c FlowMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c FlowMap type.
+    template <typename T>
+    struct SetFlowMap
+      : public Suurballe<GR, LEN, SetFlowMapTraits<T> > {
+      typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPotentialMapTraits : public Traits {
+      typedef T PotentialMap;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c PotentialMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c PotentialMap type.
+    template <typename T>
+    struct SetPotentialMap
+      : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > {
+      typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c %Path type.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    template <typename T>
+    struct SetPath
+      : public Suurballe<GR, LEN, SetPathTraits<T> > {
+      typedef Suurballe<GR, LEN, SetPathTraits<T> > Create;
+    };
+
+    template <typename H, typename CR>
+    struct SetHeapTraits : public Traits {
+      typedef H Heap;
+      typedef CR HeapCrossRef;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c Heap and \c HeapCrossRef types.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c Heap
+    /// and \c HeapCrossRef types with automatic allocation.
+    /// They will be used for internal Dijkstra computations.
+    /// The heap type must conform to the \ref lemon::concepts::Heap "Heap"
+    /// concept and its priority type must be \c Length.
+    template <typename H,
+              typename CR = typename Digraph::template NodeMap<int> >
+    struct SetHeap
+      : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > {
+      typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create;
+    };
+
+    /// @}
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_graph;
+    // The length map
+    const LengthMap &_length;
+
+    // Arc map of the current flow
+    FlowMap *_flow;
+    bool _local_flow;
+    // Node map of the current potentials
+    PotentialMap *_potential;
+    bool _local_potential;
+
+    // The source node
+    Node _s;
+    // The target node
+    Node _t;
+
+    // Container to store the found paths
+    std::vector<Path> _paths;
+    int _path_num;
+
+    // The pred arc map
+    PredMap _pred;
+
+    // Data for full init
+    PotentialMap *_init_dist;
+    PredMap *_init_pred;
+    bool _full_init;
+
+  protected:
+
+    Suurballe() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    /// \param length The length (cost) values of the arcs.
+    Suurballe( const Digraph &graph,
+               const LengthMap &length ) :
+      _graph(graph), _length(length), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _pred(graph),
+      _init_dist(0), _init_pred(0)
+    {}
+
+    /// Destructor.
+    ~Suurballe() {
+      if (_local_flow) delete _flow;
+      if (_local_potential) delete _potential;
+      delete _init_dist;
+      delete _init_pred;
+    }
+
+    /// \brief Set the flow map.
+    ///
+    /// This function sets the flow map.
+    /// If it is not used before calling \ref run() or \ref init(),
+    /// an instance will be allocated automatically. The destructor
+    /// deallocates this automatically allocated map, of course.
+    ///
+    /// The found flow contains only 0 and 1 values, since it is the
+    /// union of the found arc-disjoint paths.
+    ///
+    /// \return <tt>(*this)</tt>
+    Suurballe& flowMap(FlowMap &map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = ↦
+      return *this;
+    }
+
+    /// \brief Set the potential map.
+    ///
+    /// This function sets the potential map.
+    /// If it is not used before calling \ref run() or \ref init(),
+    /// an instance will be allocated automatically. The destructor
+    /// deallocates this automatically allocated map, of course.
+    ///
+    /// The node potentials provide the dual solution of the underlying
+    /// \ref min_cost_flow "minimum cost flow problem".
+    ///
+    /// \return <tt>(*this)</tt>
+    Suurballe& potentialMap(PotentialMap &map) {
+      if (_local_potential) {
+        delete _potential;
+        _local_potential = false;
+      }
+      _potential = ↦
+      return *this;
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to call the run()
+    /// 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, then you may call findFlow() instead of
+    /// start().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    ///
+    /// \param s The source node.
+    /// \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.run(s, t, k)</tt> is
+    /// just a shortcut of the following code.
+    /// \code
+    ///   s.init(s);
+    ///   s.start(t, k);
+    /// \endcode
+    int run(const Node& s, const Node& t, int k = 2) {
+      init(s);
+      start(t, k);
+      return _path_num;
+    }
+
+    /// \brief Initialize the algorithm.
+    ///
+    /// This function initializes the algorithm with the given source node.
+    ///
+    /// \param s The source node.
+    void init(const Node& s) {
+      _s = s;
+
+      // Initialize maps
+      if (!_flow) {
+        _flow = new FlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_potential) {
+        _potential = new PotentialMap(_graph);
+        _local_potential = true;
+      }
+      _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;
+    }
+
+    /// \brief Execute the algorithm to find an optimal flow.
+    ///
+    /// This function executes the successive shortest path algorithm to
+    /// find a minimum cost flow, which is the union of \c k (or less)
+    /// arc-disjoint paths.
+    ///
+    /// \param t The target node.
+    /// \param k The number of paths to be found.
+    ///
+    /// \return \c k if there are at least \c k arc-disjoint paths from
+    /// the source node to the given node \c t in the digraph.
+    /// Otherwise it returns the number of arc-disjoint paths found.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    int findFlow(const Node& t, int k = 2) {
+      _t = t;
+      ResidualDijkstra dijkstra(*this);
+
+      // Initialization
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_flow)[e] = 0;
+      }
+      if (_full_init) {
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          (*_potential)[n] = (*_init_dist)[n];
+        }
+        Node u = _t;
+        Arc e;
+        while ((e = (*_init_pred)[u]) != INVALID) {
+          (*_flow)[e] = 1;
+          u = _graph.source(e);
+        }
+        _path_num = 1;
+      } else {
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          (*_potential)[n] = 0;
+        }
+        _path_num = 0;
+      }
+
+      // Find shortest paths
+      while (_path_num < k) {
+        // Run Dijkstra
+        if (!dijkstra.run(_path_num)) break;
+        ++_path_num;
+
+        // Set the flow along the found shortest path
+        Node u = _t;
+        Arc e;
+        while ((e = _pred[u]) != INVALID) {
+          if (u == _graph.target(e)) {
+            (*_flow)[e] = 1;
+            u = _graph.source(e);
+          } else {
+            (*_flow)[e] = 0;
+            u = _graph.target(e);
+          }
+        }
+      }
+      return _path_num;
+    }
+
+    /// \brief Compute the paths from the flow.
+    ///
+    /// This function computes arc-disjoint paths from the found minimum
+    /// cost flow, which is the union of them.
+    ///
+    /// \pre \ref init() and \ref findFlow() must be called before using
+    /// this function.
+    void findPaths() {
+      FlowMap res_flow(_graph);
+      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
+
+      _paths.clear();
+      _paths.resize(_path_num);
+      for (int i = 0; i < _path_num; ++i) {
+        Node n = _s;
+        while (n != _t) {
+          OutArcIt e(_graph, n);
+          for ( ; res_flow[e] == 0; ++e) ;
+          n = _graph.target(e);
+          _paths[i].addBack(e);
+          res_flow[e] = 0;
+        }
+      }
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.
+    /// \n The algorithm should be executed before using them.
+
+    /// @{
+
+    /// \brief Return the total length of the found paths.
+    ///
+    /// This function returns the total length of the found paths, i.e.
+    /// the total cost of the found flow.
+    /// The complexity of the function is O(m).
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    Length totalLength() const {
+      Length c = 0;
+      for (ArcIt e(_graph); e != INVALID; ++e)
+        c += (*_flow)[e] * _length[e];
+      return c;
+    }
+
+    /// \brief Return the flow value on the given arc.
+    ///
+    /// This function returns the flow value on the given arc.
+    /// It is \c 1 if the arc is involved in one of the found arc-disjoint
+    /// paths, otherwise it is \c 0.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    int flow(const Arc& arc) const {
+      return (*_flow)[arc];
+    }
+
+    /// \brief Return a const reference to an arc map storing the
+    /// found flow.
+    ///
+    /// This function returns a const reference to an arc map storing
+    /// the flow that is the union of the found arc-disjoint paths.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    const FlowMap& flowMap() const {
+      return *_flow;
+    }
+
+    /// \brief Return the potential of the given node.
+    ///
+    /// This function returns the potential of the given node.
+    /// The node potentials provide the dual solution of the
+    /// underlying \ref min_cost_flow "minimum cost flow problem".
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    Length potential(const Node& node) const {
+      return (*_potential)[node];
+    }
+
+    /// \brief Return a const reference to a node map storing the
+    /// found potentials (the dual solution).
+    ///
+    /// This function returns a const reference to a node map storing
+    /// the found potentials that provide the dual solution of the
+    /// underlying \ref min_cost_flow "minimum cost flow problem".
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    const PotentialMap& potentialMap() const {
+      return *_potential;
+    }
+
+    /// \brief Return the number of the found paths.
+    ///
+    /// This function returns the number of the found paths.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    int pathNum() const {
+      return _path_num;
+    }
+
+    /// \brief Return a const reference to the specified path.
+    ///
+    /// This function returns a const reference to the specified path.
+    ///
+    /// \param i The function returns the <tt>i</tt>-th path.
+    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
+    ///
+    /// \pre \ref run() or \ref findPaths() must be called before using
+    /// this function.
+    const Path& path(int i) const {
+      return _paths[i];
+    }
+
+    /// @}
+
+  }; //class Suurballe
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_SUURBALLE_H
diff --git a/lemon/time_measure.h b/lemon/time_measure.h
new file mode 100644
index 0000000..3f7f077
--- /dev/null
+++ b/lemon/time_measure.h
@@ -0,0 +1,610 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_TIME_MEASURE_H
+#define LEMON_TIME_MEASURE_H
+
+///\ingroup timecount
+///\file
+///\brief Tools for measuring cpu usage
+
+#ifdef WIN32
+#include <lemon/bits/windows.h>
+#else
+#include <unistd.h>
+#include <sys/times.h>
+#include <sys/time.h>
+#endif
+
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \addtogroup timecount
+  /// @{
+
+  /// A class to store (cpu)time instances.
+
+  /// This class stores five time values.
+  /// - a real time
+  /// - a user cpu time
+  /// - a system cpu time
+  /// - a user cpu time of children
+  /// - a system cpu time of children
+  ///
+  /// TimeStamp's can be added to or substracted from each other and
+  /// they can be pushed to a stream.
+  ///
+  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
+  /// class is what you want to use instead.
+
+  class TimeStamp
+  {
+    double utime;
+    double stime;
+    double cutime;
+    double cstime;
+    double rtime;
+
+  public:
+    ///Display format specifier
+
+    ///\e
+    ///
+    enum Format {
+      /// Reports all measured values
+      NORMAL = 0,
+      /// Only real time and an error indicator is displayed
+      SHORT = 1
+    };
+
+  private:
+    static Format _format;
+
+    void _reset() {
+      utime = stime = cutime = cstime = rtime = 0;
+    }
+
+  public:
+
+    ///Set output format
+
+    ///Set output format.
+    ///
+    ///The output format is global for all timestamp instances.
+    static void format(Format f) { _format = f; }
+    ///Retrieve the current output format
+
+    ///Retrieve the current output format
+    ///
+    ///The output format is global for all timestamp instances.
+    static Format format() { return _format; }
+
+
+    ///Read the current time values of the process
+    void stamp()
+    {
+#ifndef WIN32
+      timeval tv;
+      gettimeofday(&tv, 0);
+      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
+
+      tms ts;
+      double tck=sysconf(_SC_CLK_TCK);
+      times(&ts);
+      utime=ts.tms_utime/tck;
+      stime=ts.tms_stime/tck;
+      cutime=ts.tms_cutime/tck;
+      cstime=ts.tms_cstime/tck;
+#else
+      bits::getWinProcTimes(rtime, utime, stime, cutime, cstime);
+#endif
+    }
+
+    /// Constructor initializing with zero
+    TimeStamp()
+    { _reset(); }
+    ///Constructor initializing with the current time values of the process
+    TimeStamp(void *) { stamp();}
+
+    ///Set every time value to zero
+    TimeStamp &reset() {_reset();return *this;}
+
+    ///\e
+    TimeStamp &operator+=(const TimeStamp &b)
+    {
+      utime+=b.utime;
+      stime+=b.stime;
+      cutime+=b.cutime;
+      cstime+=b.cstime;
+      rtime+=b.rtime;
+      return *this;
+    }
+    ///\e
+    TimeStamp operator+(const TimeStamp &b) const
+    {
+      TimeStamp t(*this);
+      return t+=b;
+    }
+    ///\e
+    TimeStamp &operator-=(const TimeStamp &b)
+    {
+      utime-=b.utime;
+      stime-=b.stime;
+      cutime-=b.cutime;
+      cstime-=b.cstime;
+      rtime-=b.rtime;
+      return *this;
+    }
+    ///\e
+    TimeStamp operator-(const TimeStamp &b) const
+    {
+      TimeStamp t(*this);
+      return t-=b;
+    }
+    ///\e
+    TimeStamp &operator*=(double b)
+    {
+      utime*=b;
+      stime*=b;
+      cutime*=b;
+      cstime*=b;
+      rtime*=b;
+      return *this;
+    }
+    ///\e
+    TimeStamp operator*(double b) const
+    {
+      TimeStamp t(*this);
+      return t*=b;
+    }
+    friend TimeStamp operator*(double b,const TimeStamp &t);
+    ///\e
+    TimeStamp &operator/=(double b)
+    {
+      utime/=b;
+      stime/=b;
+      cutime/=b;
+      cstime/=b;
+      rtime/=b;
+      return *this;
+    }
+    ///\e
+    TimeStamp operator/(double b) const
+    {
+      TimeStamp t(*this);
+      return t/=b;
+    }
+    ///The time ellapsed since the last call of stamp()
+    TimeStamp ellapsed() const
+    {
+      TimeStamp t(NULL);
+      return t-*this;
+    }
+
+    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
+
+    ///Gives back the user time of the process
+    double userTime() const
+    {
+      return utime;
+    }
+    ///Gives back the system time of the process
+    double systemTime() const
+    {
+      return stime;
+    }
+    ///Gives back the user time of the process' children
+
+    ///\note On <tt>WIN32</tt> platform this value is not calculated.
+    ///
+    double cUserTime() const
+    {
+      return cutime;
+    }
+    ///Gives back the user time of the process' children
+
+    ///\note On <tt>WIN32</tt> platform this value is not calculated.
+    ///
+    double cSystemTime() const
+    {
+      return cstime;
+    }
+    ///Gives back the real time
+    double realTime() const {return rtime;}
+  };
+
+  inline TimeStamp operator*(double b,const TimeStamp &t)
+  {
+    return t*b;
+  }
+
+  ///Prints the time counters
+
+  ///Prints the time counters in the following form:
+  ///
+  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
+  ///
+  /// where the values are the
+  /// \li \c u: user cpu time,
+  /// \li \c s: system cpu time,
+  /// \li \c cu: user cpu time of children,
+  /// \li \c cs: system cpu time of children,
+  /// \li \c real: real time.
+  /// \relates TimeStamp
+  /// \note On <tt>WIN32</tt> platform the cummulative values are not
+  /// calculated.
+  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
+  {
+    switch(t._format)
+      {
+      case TimeStamp::NORMAL:
+        os << "u: " << t.userTime() <<
+          "s, s: " << t.systemTime() <<
+          "s, cu: " << t.cUserTime() <<
+          "s, cs: " << t.cSystemTime() <<
+          "s, real: " << t.realTime() << "s";
+        break;
+      case TimeStamp::SHORT:
+        double total = t.userTime()+t.systemTime()+
+          t.cUserTime()+t.cSystemTime();
+        os << t.realTime()
+           << "s (err: " << round((t.realTime()-total)/
+                                  t.realTime()*10000)/100
+           << "%)";
+        break;
+      }
+    return os;
+  }
+
+  ///Class for measuring the cpu time and real time usage of the process
+
+  ///Class for measuring the cpu time and real time usage of the process.
+  ///It is quite easy-to-use, here is a short example.
+  ///\code
+  /// #include<lemon/time_measure.h>
+  /// #include<iostream>
+  ///
+  /// int main()
+  /// {
+  ///
+  ///   ...
+  ///
+  ///   Timer t;
+  ///   doSomething();
+  ///   std::cout << t << '\n';
+  ///   t.restart();
+  ///   doSomethingElse();
+  ///   std::cout << t << '\n';
+  ///
+  ///   ...
+  ///
+  /// }
+  ///\endcode
+  ///
+  ///The \ref Timer can also be \ref stop() "stopped" and
+  ///\ref start() "started" again, so it is possible to compute collected
+  ///running times.
+  ///
+  ///\warning Depending on the operation system and its actual configuration
+  ///the time counters have a certain (10ms on a typical Linux system)
+  ///granularity.
+  ///Therefore this tool is not appropriate to measure very short times.
+  ///Also, if you start and stop the timer very frequently, it could lead to
+  ///distorted results.
+  ///
+  ///\note If you want to measure the running time of the execution of a certain
+  ///function, consider the usage of \ref TimeReport instead.
+  ///
+  ///\sa TimeReport
+  class Timer
+  {
+    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
+    TimeStamp start_time; //This is the relativ start-time if the timer
+                          //is _running, the collected _running time otherwise.
+
+    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
+
+  public:
+    ///Constructor.
+
+    ///\param run indicates whether or not the timer starts immediately.
+    ///
+    Timer(bool run=true) :_running(run) {_reset();}
+
+    ///\name Control the State of the Timer
+    ///Basically a Timer can be either running or stopped,
+    ///but it provides a bit finer control on the execution.
+    ///The \ref lemon::Timer "Timer" also counts the number of
+    ///\ref lemon::Timer::start() "start()" executions, and it stops
+    ///only after the same amount (or more) \ref lemon::Timer::stop()
+    ///"stop()"s. This can be useful e.g. to compute the running time
+    ///of recursive functions.
+
+    ///@{
+
+    ///Reset and stop the time counters
+
+    ///This function resets and stops the time counters
+    ///\sa restart()
+    void reset()
+    {
+      _running=0;
+      _reset();
+    }
+
+    ///Start the time counters
+
+    ///This function starts the time counters.
+    ///
+    ///If the timer is started more than ones, it will remain running
+    ///until the same amount of \ref stop() is called.
+    ///\sa stop()
+    void start()
+    {
+      if(_running) _running++;
+      else {
+        _running=1;
+        TimeStamp t;
+        t.stamp();
+        start_time=t-start_time;
+      }
+    }
+
+
+    ///Stop the time counters
+
+    ///This function stops the time counters. If start() was executed more than
+    ///once, then the same number of stop() execution is necessary the really
+    ///stop the timer.
+    ///
+    ///\sa halt()
+    ///\sa start()
+    ///\sa restart()
+    ///\sa reset()
+
+    void stop()
+    {
+      if(_running && !--_running) {
+        TimeStamp t;
+        t.stamp();
+        start_time=t-start_time;
+      }
+    }
+
+    ///Halt (i.e stop immediately) the time counters
+
+    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
+    ///is a faster
+    ///equivalent of the following.
+    ///\code
+    ///  while(t.running()) t.stop()
+    ///\endcode
+    ///
+    ///
+    ///\sa stop()
+    ///\sa restart()
+    ///\sa reset()
+
+    void halt()
+    {
+      if(_running) {
+        _running=0;
+        TimeStamp t;
+        t.stamp();
+        start_time=t-start_time;
+      }
+    }
+
+    ///Returns the running state of the timer
+
+    ///This function returns the number of stop() exections that is
+    ///necessary to really stop the timer.
+    ///For example, the timer
+    ///is running if and only if the return value is \c true
+    ///(i.e. greater than
+    ///zero).
+    int running()  { return _running; }
+
+
+    ///Restart the time counters
+
+    ///This function is a shorthand for
+    ///a reset() and a start() calls.
+    ///
+    void restart()
+    {
+      reset();
+      start();
+    }
+
+    ///@}
+
+    ///\name Query Functions for the Ellapsed Time
+
+    ///@{
+
+    ///Gives back the ellapsed user time of the process
+    double userTime() const
+    {
+      return operator TimeStamp().userTime();
+    }
+    ///Gives back the ellapsed system time of the process
+    double systemTime() const
+    {
+      return operator TimeStamp().systemTime();
+    }
+    ///Gives back the ellapsed user time of the process' children
+
+    ///\note On <tt>WIN32</tt> platform this value is not calculated.
+    ///
+    double cUserTime() const
+    {
+      return operator TimeStamp().cUserTime();
+    }
+    ///Gives back the ellapsed user time of the process' children
+
+    ///\note On <tt>WIN32</tt> platform this value is not calculated.
+    ///
+    double cSystemTime() const
+    {
+      return operator TimeStamp().cSystemTime();
+    }
+    ///Gives back the ellapsed real time
+    double realTime() const
+    {
+      return operator TimeStamp().realTime();
+    }
+    ///Computes the ellapsed time
+
+    ///This conversion computes the ellapsed time, therefore you can print
+    ///the ellapsed time like this.
+    ///\code
+    ///  Timer t;
+    ///  doSomething();
+    ///  std::cout << t << '\n';
+    ///\endcode
+    operator TimeStamp () const
+    {
+      TimeStamp t;
+      t.stamp();
+      return _running?t-start_time:start_time;
+    }
+
+
+    ///@}
+  };
+
+  ///Same as Timer but prints a report on destruction.
+
+  ///Same as \ref Timer but prints a report on destruction.
+  ///This example shows its usage.
+  ///\code
+  ///  void myAlg(ListGraph &g,int n)
+  ///  {
+  ///    TimeReport tr("Running time of myAlg: ");
+  ///    ... //Here comes the algorithm
+  ///  }
+  ///\endcode
+  ///
+  ///\sa Timer
+  ///\sa NoTimeReport
+  class TimeReport : public Timer
+  {
+    std::string _title;
+    std::ostream &_os;
+    bool _active;
+  public:
+    ///Constructor
+
+    ///Constructor.
+    ///\param title This text will be printed before the ellapsed time.
+    ///\param os The stream to print the report to.
+    ///\param run Sets whether the timer should start immediately.
+    ///\param active Sets whether the report should actually be printed
+    ///       on destruction.
+    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true,
+               bool active=true)
+      : Timer(run), _title(title), _os(os), _active(active) {}
+    ///Destructor that prints the ellapsed time
+    ~TimeReport()
+    {
+      if(_active) _os << _title << *this << std::endl;
+    }
+
+    ///Retrieve the activity status
+
+    ///\e
+    ///
+    bool active() const { return _active; }
+    ///Set the activity status
+
+    /// This function set whether the time report should actually be printed
+    /// on destruction.
+    void active(bool a) { _active=a; }
+  };
+
+  ///'Do nothing' version of TimeReport
+
+  ///\sa TimeReport
+  ///
+  class NoTimeReport
+  {
+  public:
+    ///\e
+    NoTimeReport(std::string,std::ostream &,bool) {}
+    ///\e
+    NoTimeReport(std::string,std::ostream &) {}
+    ///\e
+    NoTimeReport(std::string) {}
+    ///\e Do nothing.
+    ~NoTimeReport() {}
+
+    operator TimeStamp () const { return TimeStamp(); }
+    void reset() {}
+    void start() {}
+    void stop() {}
+    void halt() {}
+    int running() { return 0; }
+    void restart() {}
+    double userTime() const { return 0; }
+    double systemTime() const { return 0; }
+    double cUserTime() const { return 0; }
+    double cSystemTime() const { return 0; }
+    double realTime() const { return 0; }
+  };
+
+  ///Tool to measure the running time more exactly.
+
+  ///This function calls \c f several times and returns the average
+  ///running time. The number of the executions will be choosen in such a way
+  ///that the full real running time will be roughly between \c min_time
+  ///and <tt>2*min_time</tt>.
+  ///\param f the function object to be measured.
+  ///\param min_time the minimum total running time.
+  ///\retval num if it is not \c NULL, then the actual
+  ///        number of execution of \c f will be written into <tt>*num</tt>.
+  ///\retval full_time if it is not \c NULL, then the actual
+  ///        total running time will be written into <tt>*full_time</tt>.
+  ///\return The average running time of \c f.
+
+  template<class F>
+  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
+                            TimeStamp *full_time=NULL)
+  {
+    TimeStamp full;
+    unsigned int total=0;
+    Timer t;
+    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
+      for(;total<tn;total++) f();
+      full=t;
+    }
+    if(num) *num=total;
+    if(full_time) *full_time=full;
+    return full/total;
+  }
+
+  /// @}
+
+
+} //namespace lemon
+
+#endif //LEMON_TIME_MEASURE_H
diff --git a/lemon/tolerance.h b/lemon/tolerance.h
new file mode 100644
index 0000000..36a7512
--- /dev/null
+++ b/lemon/tolerance.h
@@ -0,0 +1,242 @@
+/* -*- 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_TOLERANCE_H
+#define LEMON_TOLERANCE_H
+
+///\ingroup misc
+///\file
+///\brief A basic tool to handle the anomalies of calculation with
+///floating point numbers.
+///
+
+namespace lemon {
+
+  /// \addtogroup misc
+  /// @{
+
+  ///\brief A class to provide a basic way to
+  ///handle the comparison of numbers that are obtained
+  ///as a result of a probably inexact computation.
+  ///
+  ///\ref Tolerance is a class to provide a basic way to
+  ///handle the comparison of numbers that are obtained
+  ///as a result of a probably inexact computation.
+  ///
+  ///The general implementation is suitable only if the data type is exact,
+  ///like the integer types, otherwise a specialized version must be
+  ///implemented. These specialized classes like
+  ///Tolerance<double> may offer additional tuning parameters.
+  ///
+  ///\sa Tolerance<float>
+  ///\sa Tolerance<double>
+  ///\sa Tolerance<long double>
+
+  template<class T>
+  class Tolerance
+  {
+  public:
+    typedef T Value;
+
+    ///\name Comparisons
+    ///The concept is that these bool functions return \c true only if
+    ///the related comparisons hold even if some numerical error appeared
+    ///during the computations.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    static bool less(Value a,Value b) {return a<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    static bool different(Value a,Value b) {return a!=b;}
+    ///Returns \c true if \c a is \e surely positive
+    static bool positive(Value a) {return static_cast<Value>(0) < a;}
+    ///Returns \c true if \c a is \e surely negative
+    static bool negative(Value a) {return a < static_cast<Value>(0);}
+    ///Returns \c true if \c a is \e surely non-zero
+    static bool nonZero(Value a) {return a != static_cast<Value>(0);}
+
+    ///@}
+
+    ///Returns the zero value.
+    static Value zero() {return static_cast<Value>(0);}
+
+    //   static bool finite(Value a) {}
+    //   static Value big() {}
+    //   static Value negativeBig() {}
+  };
+
+
+  ///Float specialization of Tolerance.
+
+  ///Float specialization of Tolerance.
+  ///\sa Tolerance
+  ///\relates Tolerance
+  template<>
+  class Tolerance<float>
+  {
+    static float def_epsilon;
+    float _epsilon;
+  public:
+    ///\e
+    typedef float Value;
+
+    ///Constructor setting the epsilon tolerance to the default value.
+    Tolerance() : _epsilon(def_epsilon) {}
+    ///Constructor setting the epsilon tolerance to the given value.
+    Tolerance(float e) : _epsilon(e) {}
+
+    ///Returns the epsilon value.
+    Value epsilon() const {return _epsilon;}
+    ///Sets the epsilon value.
+    void epsilon(Value e) {_epsilon=e;}
+
+    ///Returns the default epsilon value.
+    static Value defaultEpsilon() {return def_epsilon;}
+    ///Sets the default epsilon value.
+    static void defaultEpsilon(Value e) {def_epsilon=e;}
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    bool less(Value a,Value b) const {return a+_epsilon<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
+    ///Returns \c true if \c a is \e surely positive
+    bool positive(Value a) const { return _epsilon<a; }
+    ///Returns \c true if \c a is \e surely negative
+    bool negative(Value a) const { return -_epsilon>a; }
+    ///Returns \c true if \c a is \e surely non-zero
+    bool nonZero(Value a) const { return positive(a)||negative(a); }
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+  ///Double specialization of Tolerance.
+
+  ///Double specialization of Tolerance.
+  ///\sa Tolerance
+  ///\relates Tolerance
+  template<>
+  class Tolerance<double>
+  {
+    static double def_epsilon;
+    double _epsilon;
+  public:
+    ///\e
+    typedef double Value;
+
+    ///Constructor setting the epsilon tolerance to the default value.
+    Tolerance() : _epsilon(def_epsilon) {}
+    ///Constructor setting the epsilon tolerance to the given value.
+    Tolerance(double e) : _epsilon(e) {}
+
+    ///Returns the epsilon value.
+    Value epsilon() const {return _epsilon;}
+    ///Sets the epsilon value.
+    void epsilon(Value e) {_epsilon=e;}
+
+    ///Returns the default epsilon value.
+    static Value defaultEpsilon() {return def_epsilon;}
+    ///Sets the default epsilon value.
+    static void defaultEpsilon(Value e) {def_epsilon=e;}
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    bool less(Value a,Value b) const {return a+_epsilon<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
+    ///Returns \c true if \c a is \e surely positive
+    bool positive(Value a) const { return _epsilon<a; }
+    ///Returns \c true if \c a is \e surely negative
+    bool negative(Value a) const { return -_epsilon>a; }
+    ///Returns \c true if \c a is \e surely non-zero
+    bool nonZero(Value a) const { return positive(a)||negative(a); }
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+  ///Long double specialization of Tolerance.
+
+  ///Long double specialization of Tolerance.
+  ///\sa Tolerance
+  ///\relates Tolerance
+  template<>
+  class Tolerance<long double>
+  {
+    static long double def_epsilon;
+    long double _epsilon;
+  public:
+    ///\e
+    typedef long double Value;
+
+    ///Constructor setting the epsilon tolerance to the default value.
+    Tolerance() : _epsilon(def_epsilon) {}
+    ///Constructor setting the epsilon tolerance to the given value.
+    Tolerance(long double e) : _epsilon(e) {}
+
+    ///Returns the epsilon value.
+    Value epsilon() const {return _epsilon;}
+    ///Sets the epsilon value.
+    void epsilon(Value e) {_epsilon=e;}
+
+    ///Returns the default epsilon value.
+    static Value defaultEpsilon() {return def_epsilon;}
+    ///Sets the default epsilon value.
+    static void defaultEpsilon(Value e) {def_epsilon=e;}
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    bool less(Value a,Value b) const {return a+_epsilon<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
+    ///Returns \c true if \c a is \e surely positive
+    bool positive(Value a) const { return _epsilon<a; }
+    ///Returns \c true if \c a is \e surely negative
+    bool negative(Value a) const { return -_epsilon>a; }
+    ///Returns \c true if \c a is \e surely non-zero
+    bool nonZero(Value a) const { return positive(a)||negative(a); }
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+  /// @}
+
+} //namespace lemon
+
+#endif //LEMON_TOLERANCE_H
diff --git a/lemon/unionfind.h b/lemon/unionfind.h
new file mode 100644
index 0000000..3d96b37
--- /dev/null
+++ b/lemon/unionfind.h
@@ -0,0 +1,1824 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_UNION_FIND_H
+#define LEMON_UNION_FIND_H
+
+//!\ingroup auxdat
+//!\file
+//!\brief Union-Find data structures.
+//!
+
+#include <vector>
+#include <list>
+#include <utility>
+#include <algorithm>
+#include <functional>
+
+#include <lemon/core.h>
+
+namespace lemon {
+
+  /// \ingroup auxdat
+  ///
+  /// \brief A \e Union-Find data structure implementation
+  ///
+  /// The class implements the \e Union-Find data structure.
+  /// The union operation uses rank heuristic, while
+  /// the find operation uses path compression.
+  /// 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.
+  ///
+  /// It is primarily used in Kruskal algorithm for finding minimal
+  /// cost spanning tree in a graph.
+  /// \sa kruskal()
+  ///
+  /// \pre You need to add all the elements by the \ref insert()
+  /// method.
+  template <typename IM>
+  class UnionFind {
+  public:
+
+    ///\e
+    typedef IM ItemIntMap;
+    ///\e
+    typedef typename ItemIntMap::Key Item;
+
+  private:
+    // If the items vector stores negative value for an item then
+    // that item is root item and it has -items[it] component size.
+    // Else the items[it] contains the index of the parent.
+    std::vector<int> items;
+    ItemIntMap& index;
+
+    bool rep(int idx) const {
+      return items[idx] < 0;
+    }
+
+    int repIndex(int idx) const {
+      int k = idx;
+      while (!rep(k)) {
+        k = items[k] ;
+      }
+      while (idx != k) {
+        int next = items[idx];
+        const_cast<int&>(items[idx]) = k;
+        idx = next;
+      }
+      return k;
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor of the UnionFind class. You should give an item to
+    /// integer map which will be used from the data structure. If you
+    /// modify directly this map that may cause segmentation fault,
+    /// invalid data structure, or infinite loop when you use again
+    /// the union-find.
+    UnionFind(ItemIntMap& m) : index(m) {}
+
+    /// \brief Returns the index of the element's component.
+    ///
+    /// The method returns the index of the element's component.
+    /// This is an integer between zero and the number of inserted elements.
+    ///
+    int find(const Item& a) {
+      return repIndex(index[a]);
+    }
+
+    /// \brief Clears the union-find data structure
+    ///
+    /// Erase each item from the data structure.
+    void clear() {
+      items.clear();
+    }
+
+    /// \brief Inserts a new element into the structure.
+    ///
+    /// This method inserts a new element into the data structure.
+    ///
+    /// The method returns the index of the new component.
+    int insert(const Item& a) {
+      int n = items.size();
+      items.push_back(-1);
+      index.set(a,n);
+      return n;
+    }
+
+    /// \brief Joining the components of element \e a and element \e b.
+    ///
+    /// This is the \e union operation of the Union-Find structure.
+    /// Joins the component of element \e a and component of
+    /// element \e b. If \e a and \e b are in the same component then
+    /// it returns false otherwise it returns true.
+    bool join(const Item& a, const Item& b) {
+      int ka = repIndex(index[a]);
+      int kb = repIndex(index[b]);
+
+      if ( ka == kb )
+        return false;
+
+      if (items[ka] < items[kb]) {
+        items[ka] += items[kb];
+        items[kb] = ka;
+      } else {
+        items[kb] += items[ka];
+        items[ka] = kb;
+      }
+      return true;
+    }
+
+    /// \brief Returns the size of the component of element \e a.
+    ///
+    /// Returns the size of the component of element \e a.
+    int size(const Item& a) {
+      int k = repIndex(index[a]);
+      return - items[k];
+    }
+
+  };
+
+  /// \ingroup auxdat
+  ///
+  /// \brief A \e Union-Find data structure implementation which
+  /// is able to enumerate the components.
+  ///
+  /// The class implements a \e Union-Find data structure
+  /// which is able to enumerate the components and the items in
+  /// a component. If you don't need this feature then perhaps it's
+  /// better to use the \ref UnionFind class which is more efficient.
+  ///
+  /// The union operation uses rank heuristic, while
+  /// the find operation uses path compression.
+  ///
+  /// \pre You need to add all the elements by the \ref insert()
+  /// method.
+  ///
+  template <typename IM>
+  class UnionFindEnum {
+  public:
+
+    ///\e
+    typedef IM ItemIntMap;
+    ///\e
+    typedef typename ItemIntMap::Key Item;
+
+  private:
+
+    ItemIntMap& index;
+
+    // If the parent stores negative value for an item then that item
+    // is root item and it has ~(items[it].parent) component id.  Else
+    // the items[it].parent contains the index of the parent.
+    //
+    // The \c next and \c prev provides the double-linked
+    // cyclic list of one component's items.
+    struct ItemT {
+      int parent;
+      Item item;
+
+      int next, prev;
+    };
+
+    std::vector<ItemT> items;
+    int firstFreeItem;
+
+    struct ClassT {
+      int size;
+      int firstItem;
+      int next, prev;
+    };
+
+    std::vector<ClassT> classes;
+    int firstClass, firstFreeClass;
+
+    int newClass() {
+      if (firstFreeClass == -1) {
+        int cdx = classes.size();
+        classes.push_back(ClassT());
+        return cdx;
+      } else {
+        int cdx = firstFreeClass;
+        firstFreeClass = classes[firstFreeClass].next;
+        return cdx;
+      }
+    }
+
+    int newItem() {
+      if (firstFreeItem == -1) {
+        int idx = items.size();
+        items.push_back(ItemT());
+        return idx;
+      } else {
+        int idx = firstFreeItem;
+        firstFreeItem = items[firstFreeItem].next;
+        return idx;
+      }
+    }
+
+
+    bool rep(int idx) const {
+      return items[idx].parent < 0;
+    }
+
+    int repIndex(int idx) const {
+      int k = idx;
+      while (!rep(k)) {
+        k = items[k].parent;
+      }
+      while (idx != k) {
+        int next = items[idx].parent;
+        const_cast<int&>(items[idx].parent) = k;
+        idx = next;
+      }
+      return k;
+    }
+
+    int classIndex(int idx) const {
+      return ~(items[repIndex(idx)].parent);
+    }
+
+    void singletonItem(int idx) {
+      items[idx].next = idx;
+      items[idx].prev = idx;
+    }
+
+    void laceItem(int idx, int rdx) {
+      items[idx].prev = rdx;
+      items[idx].next = items[rdx].next;
+      items[items[rdx].next].prev = idx;
+      items[rdx].next = idx;
+    }
+
+    void unlaceItem(int idx) {
+      items[items[idx].prev].next = items[idx].next;
+      items[items[idx].next].prev = items[idx].prev;
+
+      items[idx].next = firstFreeItem;
+      firstFreeItem = idx;
+    }
+
+    void spliceItems(int ak, int bk) {
+      items[items[ak].prev].next = bk;
+      items[items[bk].prev].next = ak;
+      int tmp = items[ak].prev;
+      items[ak].prev = items[bk].prev;
+      items[bk].prev = tmp;
+
+    }
+
+    void laceClass(int cls) {
+      if (firstClass != -1) {
+        classes[firstClass].prev = cls;
+      }
+      classes[cls].next = firstClass;
+      classes[cls].prev = -1;
+      firstClass = cls;
+    }
+
+    void unlaceClass(int cls) {
+      if (classes[cls].prev != -1) {
+        classes[classes[cls].prev].next = classes[cls].next;
+      } else {
+        firstClass = classes[cls].next;
+      }
+      if (classes[cls].next != -1) {
+        classes[classes[cls].next].prev = classes[cls].prev;
+      }
+
+      classes[cls].next = firstFreeClass;
+      firstFreeClass = cls;
+    }
+
+  public:
+
+    UnionFindEnum(ItemIntMap& _index)
+      : index(_index), items(), firstFreeItem(-1),
+        firstClass(-1), firstFreeClass(-1) {}
+
+    /// \brief Inserts the given element into a new component.
+    ///
+    /// This method creates a new component consisting only of the
+    /// given element.
+    ///
+    int insert(const Item& item) {
+      int idx = newItem();
+
+      index.set(item, idx);
+
+      singletonItem(idx);
+      items[idx].item = item;
+
+      int cdx = newClass();
+
+      items[idx].parent = ~cdx;
+
+      laceClass(cdx);
+      classes[cdx].size = 1;
+      classes[cdx].firstItem = idx;
+
+      firstClass = cdx;
+
+      return cdx;
+    }
+
+    /// \brief Inserts the given element into the component of the others.
+    ///
+    /// This methods inserts the element \e a into the component of the
+    /// element \e comp.
+    void insert(const Item& item, int cls) {
+      int rdx = classes[cls].firstItem;
+      int idx = newItem();
+
+      index.set(item, idx);
+
+      laceItem(idx, rdx);
+
+      items[idx].item = item;
+      items[idx].parent = rdx;
+
+      ++classes[~(items[rdx].parent)].size;
+    }
+
+    /// \brief Clears the union-find data structure
+    ///
+    /// Erase each item from the data structure.
+    void clear() {
+      items.clear();
+      firstClass = -1;
+      firstFreeItem = -1;
+    }
+
+    /// \brief Finds the component of the given element.
+    ///
+    /// The method returns the component id of the given element.
+    int find(const Item &item) const {
+      return ~(items[repIndex(index[item])].parent);
+    }
+
+    /// \brief Joining the component of element \e a and element \e b.
+    ///
+    /// This is the \e union operation of the Union-Find structure.
+    /// Joins the component of element \e a and component of
+    /// element \e b. If \e a and \e b are in the same component then
+    /// returns -1 else returns the remaining class.
+    int join(const Item& a, const Item& b) {
+
+      int ak = repIndex(index[a]);
+      int bk = repIndex(index[b]);
+
+      if (ak == bk) {
+        return -1;
+      }
+
+      int acx = ~(items[ak].parent);
+      int bcx = ~(items[bk].parent);
+
+      int rcx;
+
+      if (classes[acx].size > classes[bcx].size) {
+        classes[acx].size += classes[bcx].size;
+        items[bk].parent = ak;
+        unlaceClass(bcx);
+        rcx = acx;
+      } else {
+        classes[bcx].size += classes[acx].size;
+        items[ak].parent = bk;
+        unlaceClass(acx);
+        rcx = bcx;
+      }
+      spliceItems(ak, bk);
+
+      return rcx;
+    }
+
+    /// \brief Returns the size of the class.
+    ///
+    /// Returns the size of the class.
+    int size(int cls) const {
+      return classes[cls].size;
+    }
+
+    /// \brief Splits up the component.
+    ///
+    /// Splitting the component into singleton components (component
+    /// of size one).
+    void split(int cls) {
+      int fdx = classes[cls].firstItem;
+      int idx = items[fdx].next;
+      while (idx != fdx) {
+        int next = items[idx].next;
+
+        singletonItem(idx);
+
+        int cdx = newClass();
+        items[idx].parent = ~cdx;
+
+        laceClass(cdx);
+        classes[cdx].size = 1;
+        classes[cdx].firstItem = idx;
+
+        idx = next;
+      }
+
+      items[idx].prev = idx;
+      items[idx].next = idx;
+
+      classes[~(items[idx].parent)].size = 1;
+
+    }
+
+    /// \brief Removes the given element from the structure.
+    ///
+    /// Removes the element from its component and if the component becomes
+    /// empty then removes that component from the component list.
+    ///
+    /// \warning It is an error to remove an element which is not in
+    /// the structure.
+    /// \warning This running time of this operation is proportional to the
+    /// number of the items in this class.
+    void erase(const Item& item) {
+      int idx = index[item];
+      int fdx = items[idx].next;
+
+      int cdx = classIndex(idx);
+      if (idx == fdx) {
+        unlaceClass(cdx);
+        items[idx].next = firstFreeItem;
+        firstFreeItem = idx;
+        return;
+      } else {
+        classes[cdx].firstItem = fdx;
+        --classes[cdx].size;
+        items[fdx].parent = ~cdx;
+
+        unlaceItem(idx);
+        idx = items[fdx].next;
+        while (idx != fdx) {
+          items[idx].parent = fdx;
+          idx = items[idx].next;
+        }
+
+      }
+
+    }
+
+    /// \brief Gives back a representant item of the component.
+    ///
+    /// Gives back a representant item of the component.
+    Item item(int cls) const {
+      return items[classes[cls].firstItem].item;
+    }
+
+    /// \brief Removes the component of the given element from the structure.
+    ///
+    /// Removes the component of the given element from the structure.
+    ///
+    /// \warning It is an error to give an element which is not in the
+    /// structure.
+    void eraseClass(int cls) {
+      int fdx = classes[cls].firstItem;
+      unlaceClass(cls);
+      items[items[fdx].prev].next = firstFreeItem;
+      firstFreeItem = fdx;
+    }
+
+    /// \brief LEMON style iterator for the representant items.
+    ///
+    /// ClassIt is a lemon style iterator for the components. It iterates
+    /// on the ids of the classes.
+    class ClassIt {
+    public:
+      /// \brief Constructor of the iterator
+      ///
+      /// Constructor of the iterator
+      ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
+        cdx = unionFind->firstClass;
+      }
+
+      /// \brief Constructor to get invalid iterator
+      ///
+      /// Constructor to get invalid iterator
+      ClassIt(Invalid) : unionFind(0), cdx(-1) {}
+
+      /// \brief Increment operator
+      ///
+      /// It steps to the next representant item.
+      ClassIt& operator++() {
+        cdx = unionFind->classes[cdx].next;
+        return *this;
+      }
+
+      /// \brief Conversion operator
+      ///
+      /// It converts the iterator to the current representant item.
+      operator int() const {
+        return cdx;
+      }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator
+      bool operator==(const ClassIt& i) {
+        return i.cdx == cdx;
+      }
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator
+      bool operator!=(const ClassIt& i) {
+        return i.cdx != cdx;
+      }
+
+    private:
+      const UnionFindEnum* unionFind;
+      int cdx;
+    };
+
+    /// \brief LEMON style iterator for the items of a component.
+    ///
+    /// ClassIt is a lemon style iterator for the components. It iterates
+    /// on the items of a class. By example if you want to iterate on
+    /// each items of each classes then you may write the next code.
+    ///\code
+    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
+    ///   std::cout << "Class: ";
+    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
+    ///     std::cout << toString(iit) << ' ' << std::endl;
+    ///   }
+    ///   std::cout << std::endl;
+    /// }
+    ///\endcode
+    class ItemIt {
+    public:
+      /// \brief Constructor of the iterator
+      ///
+      /// Constructor of the iterator. The iterator iterates
+      /// on the class of the \c item.
+      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
+        fdx = idx = unionFind->classes[cls].firstItem;
+      }
+
+      /// \brief Constructor to get invalid iterator
+      ///
+      /// Constructor to get invalid iterator
+      ItemIt(Invalid) : unionFind(0), idx(-1) {}
+
+      /// \brief Increment operator
+      ///
+      /// It steps to the next item in the class.
+      ItemIt& operator++() {
+        idx = unionFind->items[idx].next;
+        if (idx == fdx) idx = -1;
+        return *this;
+      }
+
+      /// \brief Conversion operator
+      ///
+      /// It converts the iterator to the current item.
+      operator const Item&() const {
+        return unionFind->items[idx].item;
+      }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator
+      bool operator==(const ItemIt& i) {
+        return i.idx == idx;
+      }
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator
+      bool operator!=(const ItemIt& i) {
+        return i.idx != idx;
+      }
+
+    private:
+      const UnionFindEnum* unionFind;
+      int idx, fdx;
+    };
+
+  };
+
+  /// \ingroup auxdat
+  ///
+  /// \brief A \e Extend-Find data structure implementation which
+  /// is able to enumerate the components.
+  ///
+  /// The class implements an \e Extend-Find data structure which is
+  /// able to enumerate the components and the items in a
+  /// component. The data structure is a simplification of the
+  /// Union-Find structure, and it does not allow to merge two components.
+  ///
+  /// \pre You need to add all the elements by the \ref insert()
+  /// method.
+  template <typename IM>
+  class ExtendFindEnum {
+  public:
+
+    ///\e
+    typedef IM ItemIntMap;
+    ///\e
+    typedef typename ItemIntMap::Key Item;
+
+  private:
+
+    ItemIntMap& index;
+
+    struct ItemT {
+      int cls;
+      Item item;
+      int next, prev;
+    };
+
+    std::vector<ItemT> items;
+    int firstFreeItem;
+
+    struct ClassT {
+      int firstItem;
+      int next, prev;
+    };
+
+    std::vector<ClassT> classes;
+
+    int firstClass, firstFreeClass;
+
+    int newClass() {
+      if (firstFreeClass != -1) {
+        int cdx = firstFreeClass;
+        firstFreeClass = classes[cdx].next;
+        return cdx;
+      } else {
+        classes.push_back(ClassT());
+        return classes.size() - 1;
+      }
+    }
+
+    int newItem() {
+      if (firstFreeItem != -1) {
+        int idx = firstFreeItem;
+        firstFreeItem = items[idx].next;
+        return idx;
+      } else {
+        items.push_back(ItemT());
+        return items.size() - 1;
+      }
+    }
+
+  public:
+
+    /// \brief Constructor
+    ExtendFindEnum(ItemIntMap& _index)
+      : index(_index), items(), firstFreeItem(-1),
+        classes(), firstClass(-1), firstFreeClass(-1) {}
+
+    /// \brief Inserts the given element into a new component.
+    ///
+    /// This method creates a new component consisting only of the
+    /// given element.
+    int insert(const Item& item) {
+      int cdx = newClass();
+      classes[cdx].prev = -1;
+      classes[cdx].next = firstClass;
+      if (firstClass != -1) {
+        classes[firstClass].prev = cdx;
+      }
+      firstClass = cdx;
+
+      int idx = newItem();
+      items[idx].item = item;
+      items[idx].cls = cdx;
+      items[idx].prev = idx;
+      items[idx].next = idx;
+
+      classes[cdx].firstItem = idx;
+
+      index.set(item, idx);
+
+      return cdx;
+    }
+
+    /// \brief Inserts the given element into the given component.
+    ///
+    /// This methods inserts the element \e item a into the \e cls class.
+    void insert(const Item& item, int cls) {
+      int idx = newItem();
+      int rdx = classes[cls].firstItem;
+      items[idx].item = item;
+      items[idx].cls = cls;
+
+      items[idx].prev = rdx;
+      items[idx].next = items[rdx].next;
+      items[items[rdx].next].prev = idx;
+      items[rdx].next = idx;
+
+      index.set(item, idx);
+    }
+
+    /// \brief Clears the union-find data structure
+    ///
+    /// Erase each item from the data structure.
+    void clear() {
+      items.clear();
+      classes.clear();
+      firstClass = firstFreeClass = firstFreeItem = -1;
+    }
+
+    /// \brief Gives back the class of the \e item.
+    ///
+    /// Gives back the class of the \e item.
+    int find(const Item &item) const {
+      return items[index[item]].cls;
+    }
+
+    /// \brief Gives back a representant item of the component.
+    ///
+    /// Gives back a representant item of the component.
+    Item item(int cls) const {
+      return items[classes[cls].firstItem].item;
+    }
+
+    /// \brief Removes the given element from the structure.
+    ///
+    /// Removes the element from its component and if the component becomes
+    /// empty then removes that component from the component list.
+    ///
+    /// \warning It is an error to remove an element which is not in
+    /// the structure.
+    void erase(const Item &item) {
+      int idx = index[item];
+      int cdx = items[idx].cls;
+
+      if (idx == items[idx].next) {
+        if (classes[cdx].prev != -1) {
+          classes[classes[cdx].prev].next = classes[cdx].next;
+        } else {
+          firstClass = classes[cdx].next;
+        }
+        if (classes[cdx].next != -1) {
+          classes[classes[cdx].next].prev = classes[cdx].prev;
+        }
+        classes[cdx].next = firstFreeClass;
+        firstFreeClass = cdx;
+      } else {
+        classes[cdx].firstItem = items[idx].next;
+        items[items[idx].next].prev = items[idx].prev;
+        items[items[idx].prev].next = items[idx].next;
+      }
+      items[idx].next = firstFreeItem;
+      firstFreeItem = idx;
+
+    }
+
+
+    /// \brief Removes the component of the given element from the structure.
+    ///
+    /// Removes the component of the given element from the structure.
+    ///
+    /// \warning It is an error to give an element which is not in the
+    /// structure.
+    void eraseClass(int cdx) {
+      int idx = classes[cdx].firstItem;
+      items[items[idx].prev].next = firstFreeItem;
+      firstFreeItem = idx;
+
+      if (classes[cdx].prev != -1) {
+        classes[classes[cdx].prev].next = classes[cdx].next;
+      } else {
+        firstClass = classes[cdx].next;
+      }
+      if (classes[cdx].next != -1) {
+        classes[classes[cdx].next].prev = classes[cdx].prev;
+      }
+      classes[cdx].next = firstFreeClass;
+      firstFreeClass = cdx;
+    }
+
+    /// \brief LEMON style iterator for the classes.
+    ///
+    /// ClassIt is a lemon style iterator for the components. It iterates
+    /// on the ids of classes.
+    class ClassIt {
+    public:
+      /// \brief Constructor of the iterator
+      ///
+      /// Constructor of the iterator
+      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
+        cdx = extendFind->firstClass;
+      }
+
+      /// \brief Constructor to get invalid iterator
+      ///
+      /// Constructor to get invalid iterator
+      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
+
+      /// \brief Increment operator
+      ///
+      /// It steps to the next representant item.
+      ClassIt& operator++() {
+        cdx = extendFind->classes[cdx].next;
+        return *this;
+      }
+
+      /// \brief Conversion operator
+      ///
+      /// It converts the iterator to the current class id.
+      operator int() const {
+        return cdx;
+      }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator
+      bool operator==(const ClassIt& i) {
+        return i.cdx == cdx;
+      }
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator
+      bool operator!=(const ClassIt& i) {
+        return i.cdx != cdx;
+      }
+
+    private:
+      const ExtendFindEnum* extendFind;
+      int cdx;
+    };
+
+    /// \brief LEMON style iterator for the items of a component.
+    ///
+    /// ClassIt is a lemon style iterator for the components. It iterates
+    /// on the items of a class. By example if you want to iterate on
+    /// each items of each classes then you may write the next code.
+    ///\code
+    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
+    ///   std::cout << "Class: ";
+    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
+    ///     std::cout << toString(iit) << ' ' << std::endl;
+    ///   }
+    ///   std::cout << std::endl;
+    /// }
+    ///\endcode
+    class ItemIt {
+    public:
+      /// \brief Constructor of the iterator
+      ///
+      /// Constructor of the iterator. The iterator iterates
+      /// on the class of the \c item.
+      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
+        fdx = idx = extendFind->classes[cls].firstItem;
+      }
+
+      /// \brief Constructor to get invalid iterator
+      ///
+      /// Constructor to get invalid iterator
+      ItemIt(Invalid) : extendFind(0), idx(-1) {}
+
+      /// \brief Increment operator
+      ///
+      /// It steps to the next item in the class.
+      ItemIt& operator++() {
+        idx = extendFind->items[idx].next;
+        if (fdx == idx) idx = -1;
+        return *this;
+      }
+
+      /// \brief Conversion operator
+      ///
+      /// It converts the iterator to the current item.
+      operator const Item&() const {
+        return extendFind->items[idx].item;
+      }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator
+      bool operator==(const ItemIt& i) {
+        return i.idx == idx;
+      }
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator
+      bool operator!=(const ItemIt& i) {
+        return i.idx != idx;
+      }
+
+    private:
+      const ExtendFindEnum* extendFind;
+      int idx, fdx;
+    };
+
+  };
+
+  /// \ingroup auxdat
+  ///
+  /// \brief A \e Union-Find data structure implementation which
+  /// is able to store a priority for each item and retrieve the minimum of
+  /// each class.
+  ///
+  /// A \e Union-Find data structure implementation which is able to
+  /// store a priority for each item and retrieve the minimum of each
+  /// class. In addition, it supports the joining and splitting the
+  /// components. If you don't need this feature then you makes
+  /// better to use the \ref UnionFind class which is more efficient.
+  ///
+  /// The union-find data strcuture based on a (2, 16)-tree with a
+  /// tournament minimum selection on the internal nodes. The insert
+  /// operation takes O(1), the find, set, decrease and increase takes
+  /// O(log(n)), where n is the number of nodes in the current
+  /// component.  The complexity of join and split is O(log(n)*k),
+  /// where n is the sum of the number of the nodes and k is the
+  /// number of joined components or the number of the components
+  /// after the split.
+  ///
+  /// \pre You need to add all the elements by the \ref insert()
+  /// method.
+  template <typename V, typename IM, typename Comp = std::less<V> >
+  class HeapUnionFind {
+  public:
+
+    ///\e
+    typedef V Value;
+    ///\e
+    typedef typename IM::Key Item;
+    ///\e
+    typedef IM ItemIntMap;
+    ///\e
+    typedef Comp Compare;
+
+  private:
+
+    static const int cmax = 16;
+
+    ItemIntMap& index;
+
+    struct ClassNode {
+      int parent;
+      int depth;
+
+      int left, right;
+      int next, prev;
+    };
+
+    int first_class;
+    int first_free_class;
+    std::vector<ClassNode> classes;
+
+    int newClass() {
+      if (first_free_class < 0) {
+        int id = classes.size();
+        classes.push_back(ClassNode());
+        return id;
+      } else {
+        int id = first_free_class;
+        first_free_class = classes[id].next;
+        return id;
+      }
+    }
+
+    void deleteClass(int id) {
+      classes[id].next = first_free_class;
+      first_free_class = id;
+    }
+
+    struct ItemNode {
+      int parent;
+      Item item;
+      Value prio;
+      int next, prev;
+      int left, right;
+      int size;
+    };
+
+    int first_free_node;
+    std::vector<ItemNode> nodes;
+
+    int newNode() {
+      if (first_free_node < 0) {
+        int id = nodes.size();
+        nodes.push_back(ItemNode());
+        return id;
+      } else {
+        int id = first_free_node;
+        first_free_node = nodes[id].next;
+        return id;
+      }
+    }
+
+    void deleteNode(int id) {
+      nodes[id].next = first_free_node;
+      first_free_node = id;
+    }
+
+    Comp comp;
+
+    int findClass(int id) const {
+      int kd = id;
+      while (kd >= 0) {
+        kd = nodes[kd].parent;
+      }
+      return ~kd;
+    }
+
+    int leftNode(int id) const {
+      int kd = ~(classes[id].parent);
+      for (int i = 0; i < classes[id].depth; ++i) {
+        kd = nodes[kd].left;
+      }
+      return kd;
+    }
+
+    int nextNode(int id) const {
+      int depth = 0;
+      while (id >= 0 && nodes[id].next == -1) {
+        id = nodes[id].parent;
+        ++depth;
+      }
+      if (id < 0) {
+        return -1;
+      }
+      id = nodes[id].next;
+      while (depth--) {
+        id = nodes[id].left;
+      }
+      return id;
+    }
+
+
+    void setPrio(int id) {
+      int jd = nodes[id].left;
+      nodes[id].prio = nodes[jd].prio;
+      nodes[id].item = nodes[jd].item;
+      jd = nodes[jd].next;
+      while (jd != -1) {
+        if (comp(nodes[jd].prio, nodes[id].prio)) {
+          nodes[id].prio = nodes[jd].prio;
+          nodes[id].item = nodes[jd].item;
+        }
+        jd = nodes[jd].next;
+      }
+    }
+
+    void push(int id, int jd) {
+      nodes[id].size = 1;
+      nodes[id].left = nodes[id].right = jd;
+      nodes[jd].next = nodes[jd].prev = -1;
+      nodes[jd].parent = id;
+    }
+
+    void pushAfter(int id, int jd) {
+      int kd = nodes[id].parent;
+      if (nodes[id].next != -1) {
+        nodes[nodes[id].next].prev = jd;
+        if (kd >= 0) {
+          nodes[kd].size += 1;
+        }
+      } else {
+        if (kd >= 0) {
+          nodes[kd].right = jd;
+          nodes[kd].size += 1;
+        }
+      }
+      nodes[jd].next = nodes[id].next;
+      nodes[jd].prev = id;
+      nodes[id].next = jd;
+      nodes[jd].parent = kd;
+    }
+
+    void pushRight(int id, int jd) {
+      nodes[id].size += 1;
+      nodes[jd].prev = nodes[id].right;
+      nodes[jd].next = -1;
+      nodes[nodes[id].right].next = jd;
+      nodes[id].right = jd;
+      nodes[jd].parent = id;
+    }
+
+    void popRight(int id) {
+      nodes[id].size -= 1;
+      int jd = nodes[id].right;
+      nodes[nodes[jd].prev].next = -1;
+      nodes[id].right = nodes[jd].prev;
+    }
+
+    void splice(int id, int jd) {
+      nodes[id].size += nodes[jd].size;
+      nodes[nodes[id].right].next = nodes[jd].left;
+      nodes[nodes[jd].left].prev = nodes[id].right;
+      int kd = nodes[jd].left;
+      while (kd != -1) {
+        nodes[kd].parent = id;
+        kd = nodes[kd].next;
+      }
+      nodes[id].right = nodes[jd].right;
+    }
+
+    void split(int id, int jd) {
+      int kd = nodes[id].parent;
+      nodes[kd].right = nodes[id].prev;
+      nodes[nodes[id].prev].next = -1;
+
+      nodes[jd].left = id;
+      nodes[id].prev = -1;
+      int num = 0;
+      while (id != -1) {
+        nodes[id].parent = jd;
+        nodes[jd].right = id;
+        id = nodes[id].next;
+        ++num;
+      }
+      nodes[kd].size -= num;
+      nodes[jd].size = num;
+    }
+
+    void pushLeft(int id, int jd) {
+      nodes[id].size += 1;
+      nodes[jd].next = nodes[id].left;
+      nodes[jd].prev = -1;
+      nodes[nodes[id].left].prev = jd;
+      nodes[id].left = jd;
+      nodes[jd].parent = id;
+    }
+
+    void popLeft(int id) {
+      nodes[id].size -= 1;
+      int jd = nodes[id].left;
+      nodes[nodes[jd].next].prev = -1;
+      nodes[id].left = nodes[jd].next;
+    }
+
+    void repairLeft(int id) {
+      int jd = ~(classes[id].parent);
+      while (nodes[jd].left != -1) {
+        int kd = nodes[jd].left;
+        if (nodes[jd].size == 1) {
+          if (nodes[jd].parent < 0) {
+            classes[id].parent = ~kd;
+            classes[id].depth -= 1;
+            nodes[kd].parent = ~id;
+            deleteNode(jd);
+            jd = kd;
+          } else {
+            int pd = nodes[jd].parent;
+            if (nodes[nodes[jd].next].size < cmax) {
+              pushLeft(nodes[jd].next, nodes[jd].left);
+              if (less(jd, nodes[jd].next) ||
+                  nodes[jd].item == nodes[pd].item) {
+                nodes[nodes[jd].next].prio = nodes[jd].prio;
+                nodes[nodes[jd].next].item = nodes[jd].item;
+              }
+              popLeft(pd);
+              deleteNode(jd);
+              jd = pd;
+            } else {
+              int ld = nodes[nodes[jd].next].left;
+              popLeft(nodes[jd].next);
+              pushRight(jd, ld);
+              if (less(ld, nodes[jd].left) ||
+                  nodes[ld].item == nodes[pd].item) {
+                nodes[jd].item = nodes[ld].item;
+                nodes[jd].prio = nodes[ld].prio;
+              }
+              if (nodes[nodes[jd].next].item == nodes[ld].item) {
+                setPrio(nodes[jd].next);
+              }
+              jd = nodes[jd].left;
+            }
+          }
+        } else {
+          jd = nodes[jd].left;
+        }
+      }
+    }
+
+    void repairRight(int id) {
+      int jd = ~(classes[id].parent);
+      while (nodes[jd].right != -1) {
+        int kd = nodes[jd].right;
+        if (nodes[jd].size == 1) {
+          if (nodes[jd].parent < 0) {
+            classes[id].parent = ~kd;
+            classes[id].depth -= 1;
+            nodes[kd].parent = ~id;
+            deleteNode(jd);
+            jd = kd;
+          } else {
+            int pd = nodes[jd].parent;
+            if (nodes[nodes[jd].prev].size < cmax) {
+              pushRight(nodes[jd].prev, nodes[jd].right);
+              if (less(jd, nodes[jd].prev) ||
+                  nodes[jd].item == nodes[pd].item) {
+                nodes[nodes[jd].prev].prio = nodes[jd].prio;
+                nodes[nodes[jd].prev].item = nodes[jd].item;
+              }
+              popRight(pd);
+              deleteNode(jd);
+              jd = pd;
+            } else {
+              int ld = nodes[nodes[jd].prev].right;
+              popRight(nodes[jd].prev);
+              pushLeft(jd, ld);
+              if (less(ld, nodes[jd].right) ||
+                  nodes[ld].item == nodes[pd].item) {
+                nodes[jd].item = nodes[ld].item;
+                nodes[jd].prio = nodes[ld].prio;
+              }
+              if (nodes[nodes[jd].prev].item == nodes[ld].item) {
+                setPrio(nodes[jd].prev);
+              }
+              jd = nodes[jd].right;
+            }
+          }
+        } else {
+          jd = nodes[jd].right;
+        }
+      }
+    }
+
+
+    bool less(int id, int jd) const {
+      return comp(nodes[id].prio, nodes[jd].prio);
+    }
+
+  public:
+
+    /// \brief Returns true when the given class is alive.
+    ///
+    /// Returns true when the given class is alive, ie. the class is
+    /// not nested into other class.
+    bool alive(int cls) const {
+      return classes[cls].parent < 0;
+    }
+
+    /// \brief Returns true when the given class is trivial.
+    ///
+    /// Returns true when the given class is trivial, ie. the class
+    /// contains just one item directly.
+    bool trivial(int cls) const {
+      return classes[cls].left == -1;
+    }
+
+    /// \brief Constructs the union-find.
+    ///
+    /// Constructs the union-find.
+    /// \brief _index The index map of the union-find. The data
+    /// structure uses internally for store references.
+    HeapUnionFind(ItemIntMap& _index)
+      : index(_index), first_class(-1),
+        first_free_class(-1), first_free_node(-1) {}
+
+    /// \brief Clears the union-find data structure
+    ///
+    /// Erase each item from the data structure.
+    void clear() {
+      nodes.clear();
+      classes.clear();
+      first_free_node = first_free_class = first_class = -1;
+    }
+
+    /// \brief Insert a new node into a new component.
+    ///
+    /// Insert a new node into a new component.
+    /// \param item The item of the new node.
+    /// \param prio The priority of the new node.
+    /// \return The class id of the one-item-heap.
+    int insert(const Item& item, const Value& prio) {
+      int id = newNode();
+      nodes[id].item = item;
+      nodes[id].prio = prio;
+      nodes[id].size = 0;
+
+      nodes[id].prev = -1;
+      nodes[id].next = -1;
+
+      nodes[id].left = -1;
+      nodes[id].right = -1;
+
+      nodes[id].item = item;
+      index[item] = id;
+
+      int class_id = newClass();
+      classes[class_id].parent = ~id;
+      classes[class_id].depth = 0;
+
+      classes[class_id].left = -1;
+      classes[class_id].right = -1;
+
+      if (first_class != -1) {
+        classes[first_class].prev = class_id;
+      }
+      classes[class_id].next = first_class;
+      classes[class_id].prev = -1;
+      first_class = class_id;
+
+      nodes[id].parent = ~class_id;
+
+      return class_id;
+    }
+
+    /// \brief The class of the item.
+    ///
+    /// \return The alive class id of the item, which is not nested into
+    /// other classes.
+    ///
+    /// The time complexity is O(log(n)).
+    int find(const Item& item) const {
+      return findClass(index[item]);
+    }
+
+    /// \brief Joins the classes.
+    ///
+    /// The current function joins the given classes. The parameter is
+    /// an STL range which should be contains valid class ids. The
+    /// time complexity is O(log(n)*k) where n is the overall number
+    /// of the joined nodes and k is the number of classes.
+    /// \return The class of the joined classes.
+    /// \pre The range should contain at least two class ids.
+    template <typename Iterator>
+    int join(Iterator begin, Iterator end) {
+      std::vector<int> cs;
+      for (Iterator it = begin; it != end; ++it) {
+        cs.push_back(*it);
+      }
+
+      int class_id = newClass();
+      { // creation union-find
+
+        if (first_class != -1) {
+          classes[first_class].prev = class_id;
+        }
+        classes[class_id].next = first_class;
+        classes[class_id].prev = -1;
+        first_class = class_id;
+
+        classes[class_id].depth = classes[cs[0]].depth;
+        classes[class_id].parent = classes[cs[0]].parent;
+        nodes[~(classes[class_id].parent)].parent = ~class_id;
+
+        int l = cs[0];
+
+        classes[class_id].left = l;
+        classes[class_id].right = l;
+
+        if (classes[l].next != -1) {
+          classes[classes[l].next].prev = classes[l].prev;
+        }
+        classes[classes[l].prev].next = classes[l].next;
+
+        classes[l].prev = -1;
+        classes[l].next = -1;
+
+        classes[l].depth = leftNode(l);
+        classes[l].parent = class_id;
+
+      }
+
+      { // merging of heap
+        int l = class_id;
+        for (int ci = 1; ci < int(cs.size()); ++ci) {
+          int r = cs[ci];
+          int rln = leftNode(r);
+          if (classes[l].depth > classes[r].depth) {
+            int id = ~(classes[l].parent);
+            for (int i = classes[r].depth + 1; i < classes[l].depth; ++i) {
+              id = nodes[id].right;
+            }
+            while (id >= 0 && nodes[id].size == cmax) {
+              int new_id = newNode();
+              int right_id = nodes[id].right;
+
+              popRight(id);
+              if (nodes[id].item == nodes[right_id].item) {
+                setPrio(id);
+              }
+              push(new_id, right_id);
+              pushRight(new_id, ~(classes[r].parent));
+
+              if (less(~classes[r].parent, right_id)) {
+                nodes[new_id].item = nodes[~classes[r].parent].item;
+                nodes[new_id].prio = nodes[~classes[r].parent].prio;
+              } else {
+                nodes[new_id].item = nodes[right_id].item;
+                nodes[new_id].prio = nodes[right_id].prio;
+              }
+
+              id = nodes[id].parent;
+              classes[r].parent = ~new_id;
+            }
+            if (id < 0) {
+              int new_parent = newNode();
+              nodes[new_parent].next = -1;
+              nodes[new_parent].prev = -1;
+              nodes[new_parent].parent = ~l;
+
+              push(new_parent, ~(classes[l].parent));
+              pushRight(new_parent, ~(classes[r].parent));
+              setPrio(new_parent);
+
+              classes[l].parent = ~new_parent;
+              classes[l].depth += 1;
+            } else {
+              pushRight(id, ~(classes[r].parent));
+              while (id >= 0 && less(~(classes[r].parent), id)) {
+                nodes[id].prio = nodes[~(classes[r].parent)].prio;
+                nodes[id].item = nodes[~(classes[r].parent)].item;
+                id = nodes[id].parent;
+              }
+            }
+          } else if (classes[r].depth > classes[l].depth) {
+            int id = ~(classes[r].parent);
+            for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) {
+              id = nodes[id].left;
+            }
+            while (id >= 0 && nodes[id].size == cmax) {
+              int new_id = newNode();
+              int left_id = nodes[id].left;
+
+              popLeft(id);
+              if (nodes[id].prio == nodes[left_id].prio) {
+                setPrio(id);
+              }
+              push(new_id, left_id);
+              pushLeft(new_id, ~(classes[l].parent));
+
+              if (less(~classes[l].parent, left_id)) {
+                nodes[new_id].item = nodes[~classes[l].parent].item;
+                nodes[new_id].prio = nodes[~classes[l].parent].prio;
+              } else {
+                nodes[new_id].item = nodes[left_id].item;
+                nodes[new_id].prio = nodes[left_id].prio;
+              }
+
+              id = nodes[id].parent;
+              classes[l].parent = ~new_id;
+
+            }
+            if (id < 0) {
+              int new_parent = newNode();
+              nodes[new_parent].next = -1;
+              nodes[new_parent].prev = -1;
+              nodes[new_parent].parent = ~l;
+
+              push(new_parent, ~(classes[r].parent));
+              pushLeft(new_parent, ~(classes[l].parent));
+              setPrio(new_parent);
+
+              classes[r].parent = ~new_parent;
+              classes[r].depth += 1;
+            } else {
+              pushLeft(id, ~(classes[l].parent));
+              while (id >= 0 && less(~(classes[l].parent), id)) {
+                nodes[id].prio = nodes[~(classes[l].parent)].prio;
+                nodes[id].item = nodes[~(classes[l].parent)].item;
+                id = nodes[id].parent;
+              }
+            }
+            nodes[~(classes[r].parent)].parent = ~l;
+            classes[l].parent = classes[r].parent;
+            classes[l].depth = classes[r].depth;
+          } else {
+            if (classes[l].depth != 0 &&
+                nodes[~(classes[l].parent)].size +
+                nodes[~(classes[r].parent)].size <= cmax) {
+              splice(~(classes[l].parent), ~(classes[r].parent));
+              deleteNode(~(classes[r].parent));
+              if (less(~(classes[r].parent), ~(classes[l].parent))) {
+                nodes[~(classes[l].parent)].prio =
+                  nodes[~(classes[r].parent)].prio;
+                nodes[~(classes[l].parent)].item =
+                  nodes[~(classes[r].parent)].item;
+              }
+            } else {
+              int new_parent = newNode();
+              nodes[new_parent].next = nodes[new_parent].prev = -1;
+              push(new_parent, ~(classes[l].parent));
+              pushRight(new_parent, ~(classes[r].parent));
+              setPrio(new_parent);
+
+              classes[l].parent = ~new_parent;
+              classes[l].depth += 1;
+              nodes[new_parent].parent = ~l;
+            }
+          }
+          if (classes[r].next != -1) {
+            classes[classes[r].next].prev = classes[r].prev;
+          }
+          classes[classes[r].prev].next = classes[r].next;
+
+          classes[r].prev = classes[l].right;
+          classes[classes[l].right].next = r;
+          classes[l].right = r;
+          classes[r].parent = l;
+
+          classes[r].next = -1;
+          classes[r].depth = rln;
+        }
+      }
+      return class_id;
+    }
+
+    /// \brief Split the class to subclasses.
+    ///
+    /// The current function splits the given class. The join, which
+    /// made the current class, stored a reference to the
+    /// subclasses. The \c splitClass() member restores the classes
+    /// and creates the heaps. The parameter is an STL output iterator
+    /// which will be filled with the subclass ids. The time
+    /// complexity is O(log(n)*k) where n is the overall number of
+    /// nodes in the splitted classes and k is the number of the
+    /// classes.
+    template <typename Iterator>
+    void split(int cls, Iterator out) {
+      std::vector<int> cs;
+      { // splitting union-find
+        int id = cls;
+        int l = classes[id].left;
+
+        classes[l].parent = classes[id].parent;
+        classes[l].depth = classes[id].depth;
+
+        nodes[~(classes[l].parent)].parent = ~l;
+
+        *out++ = l;
+
+        while (l != -1) {
+          cs.push_back(l);
+          l = classes[l].next;
+        }
+
+        classes[classes[id].right].next = first_class;
+        classes[first_class].prev = classes[id].right;
+        first_class = classes[id].left;
+
+        if (classes[id].next != -1) {
+          classes[classes[id].next].prev = classes[id].prev;
+        }
+        classes[classes[id].prev].next = classes[id].next;
+
+        deleteClass(id);
+      }
+
+      {
+        for (int i = 1; i < int(cs.size()); ++i) {
+          int l = classes[cs[i]].depth;
+          while (nodes[nodes[l].parent].left == l) {
+            l = nodes[l].parent;
+          }
+          int r = l;
+          while (nodes[l].parent >= 0) {
+            l = nodes[l].parent;
+            int new_node = newNode();
+
+            nodes[new_node].prev = -1;
+            nodes[new_node].next = -1;
+
+            split(r, new_node);
+            pushAfter(l, new_node);
+            setPrio(l);
+            setPrio(new_node);
+            r = new_node;
+          }
+          classes[cs[i]].parent = ~r;
+          classes[cs[i]].depth = classes[~(nodes[l].parent)].depth;
+          nodes[r].parent = ~cs[i];
+
+          nodes[l].next = -1;
+          nodes[r].prev = -1;
+
+          repairRight(~(nodes[l].parent));
+          repairLeft(cs[i]);
+
+          *out++ = cs[i];
+        }
+      }
+    }
+
+    /// \brief Gives back the priority of the current item.
+    ///
+    /// Gives back the priority of the current item.
+    const Value& operator[](const Item& item) const {
+      return nodes[index[item]].prio;
+    }
+
+    /// \brief Sets the priority of the current item.
+    ///
+    /// Sets the priority of the current item.
+    void set(const Item& item, const Value& prio) {
+      if (comp(prio, nodes[index[item]].prio)) {
+        decrease(item, prio);
+      } else if (!comp(prio, nodes[index[item]].prio)) {
+        increase(item, prio);
+      }
+    }
+
+    /// \brief Increase the priority of the current item.
+    ///
+    /// Increase the priority of the current item.
+    void increase(const Item& item, const Value& prio) {
+      int id = index[item];
+      int kd = nodes[id].parent;
+      nodes[id].prio = prio;
+      while (kd >= 0 && nodes[kd].item == item) {
+        setPrio(kd);
+        kd = nodes[kd].parent;
+      }
+    }
+
+    /// \brief Increase the priority of the current item.
+    ///
+    /// Increase the priority of the current item.
+    void decrease(const Item& item, const Value& prio) {
+      int id = index[item];
+      int kd = nodes[id].parent;
+      nodes[id].prio = prio;
+      while (kd >= 0 && less(id, kd)) {
+        nodes[kd].prio = prio;
+        nodes[kd].item = item;
+        kd = nodes[kd].parent;
+      }
+    }
+
+    /// \brief Gives back the minimum priority of the class.
+    ///
+    /// Gives back the minimum priority of the class.
+    const Value& classPrio(int cls) const {
+      return nodes[~(classes[cls].parent)].prio;
+    }
+
+    /// \brief Gives back the minimum priority item of the class.
+    ///
+    /// \return Gives back the minimum priority item of the class.
+    const Item& classTop(int cls) const {
+      return nodes[~(classes[cls].parent)].item;
+    }
+
+    /// \brief Gives back a representant item of the class.
+    ///
+    /// Gives back a representant item of the class.
+    /// The representant is indpendent from the priorities of the
+    /// items.
+    const Item& classRep(int id) const {
+      int parent = classes[id].parent;
+      return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
+    }
+
+    /// \brief LEMON style iterator for the items of a class.
+    ///
+    /// ClassIt is a lemon style iterator for the components. It iterates
+    /// on the items of a class. By example if you want to iterate on
+    /// each items of each classes then you may write the next code.
+    ///\code
+    /// for (ClassIt cit(huf); cit != INVALID; ++cit) {
+    ///   std::cout << "Class: ";
+    ///   for (ItemIt iit(huf, cit); iit != INVALID; ++iit) {
+    ///     std::cout << toString(iit) << ' ' << std::endl;
+    ///   }
+    ///   std::cout << std::endl;
+    /// }
+    ///\endcode
+    class ItemIt {
+    private:
+
+      const HeapUnionFind* _huf;
+      int _id, _lid;
+
+    public:
+
+      /// \brief Default constructor
+      ///
+      /// Default constructor
+      ItemIt() {}
+
+      ItemIt(const HeapUnionFind& huf, int cls) : _huf(&huf) {
+        int id = cls;
+        int parent = _huf->classes[id].parent;
+        if (parent >= 0) {
+          _id = _huf->classes[id].depth;
+          if (_huf->classes[id].next != -1) {
+            _lid = _huf->classes[_huf->classes[id].next].depth;
+          } else {
+            _lid = -1;
+          }
+        } else {
+          _id = _huf->leftNode(id);
+          _lid = -1;
+        }
+      }
+
+      /// \brief Increment operator
+      ///
+      /// It steps to the next item in the class.
+      ItemIt& operator++() {
+        _id = _huf->nextNode(_id);
+        return *this;
+      }
+
+      /// \brief Conversion operator
+      ///
+      /// It converts the iterator to the current item.
+      operator const Item&() const {
+        return _huf->nodes[_id].item;
+      }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator
+      bool operator==(const ItemIt& i) {
+        return i._id == _id;
+      }
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator
+      bool operator!=(const ItemIt& i) {
+        return i._id != _id;
+      }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator
+      bool operator==(Invalid) {
+        return _id == _lid;
+      }
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator
+      bool operator!=(Invalid) {
+        return _id != _lid;
+      }
+
+    };
+
+    /// \brief Class iterator
+    ///
+    /// The iterator stores
+    class ClassIt {
+    private:
+
+      const HeapUnionFind* _huf;
+      int _id;
+
+    public:
+
+      ClassIt(const HeapUnionFind& huf)
+        : _huf(&huf), _id(huf.first_class) {}
+
+      ClassIt(const HeapUnionFind& huf, int cls)
+        : _huf(&huf), _id(huf.classes[cls].left) {}
+
+      ClassIt(Invalid) : _huf(0), _id(-1) {}
+
+      const ClassIt& operator++() {
+        _id = _huf->classes[_id].next;
+        return *this;
+      }
+
+      /// \brief Equality operator
+      ///
+      /// Equality operator
+      bool operator==(const ClassIt& i) {
+        return i._id == _id;
+      }
+
+      /// \brief Inequality operator
+      ///
+      /// Inequality operator
+      bool operator!=(const ClassIt& i) {
+        return i._id != _id;
+      }
+
+      operator int() const {
+        return _id;
+      }
+
+    };
+
+  };
+
+  //! @}
+
+} //namespace lemon
+
+#endif //LEMON_UNION_FIND_H
diff --git a/scripts/unify-sources.sh b/scripts/unify-sources.sh
new file mode 100755
index 0000000..6aae63a
--- /dev/null
+++ b/scripts/unify-sources.sh
@@ -0,0 +1,390 @@
+#!/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`
+HGROOT=`hg root`
+
+function hg_year() {
+    if [ -n "$(hg st $1)" ]; then
+        echo $YEAR
+    else
+        hg log -l 1 --template='{date|isodate}\n' $1 |
+        cut -d '-' -f 1
+    fi
+}
+
+# file enumaration modes
+
+function all_files() {
+    hg status -a -m -c |
+    cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
+    while read file; do echo $HGROOT/$file; done
+}
+
+function modified_files() {
+    hg status -a -m |
+    cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
+    while read file; do echo $HGROOT/$file; done
+}
+
+function changed_files() {
+    {
+        if [ -n "$HG_PARENT1" ]
+        then
+            hg status --rev $HG_PARENT1:$HG_NODE -a -m
+        fi
+        if [ -n "$HG_PARENT2" ]
+        then
+            hg status --rev $HG_PARENT2:$HG_NODE -a -m
+        fi
+    } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
+    sort | uniq |
+    while read file; do echo $HGROOT/$file; done
+}
+
+function given_files() {
+    for file in $GIVEN_FILES
+    do
+	echo $file
+    done
+}
+
+# actions
+
+function update_action() {
+    if ! diff -q $1 $2 >/dev/null
+    then
+	echo -n " [$3 updated]"
+	rm $2
+	mv $1 $2
+	CHANGED=YES
+    fi
+}
+
+function update_warning() {
+    echo -n " [$2 warning]"
+    WARNED=YES
+}
+
+function update_init() {
+    echo Update source files...
+    TOTAL_FILES=0
+    CHANGED_FILES=0
+    WARNED_FILES=0
+}
+
+function update_done() {
+    echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
+    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
+}
+
+function update_begin() {
+    ((TOTAL_FILES++))
+    CHANGED=NO
+    WARNED=NO
+}
+
+function update_end() {
+    if [ $CHANGED == YES ]
+    then
+	((++CHANGED_FILES))
+    fi
+    if [ $WARNED == YES ]
+    then
+	((++WARNED_FILES))
+    fi
+}
+
+function check_action() {
+    if [ "$3" == 'tabs' ]
+    then
+        if echo $2 | grep -q -v -E 'Makefile\.am$'
+        then
+            PATTERN=$(echo -e '\t')
+        else
+            PATTERN='        '
+        fi
+    elif [ "$3" == 'trailing spaces' ]
+    then
+        PATTERN='\ +$'
+    else
+        PATTERN='*'
+    fi
+
+    if ! diff -q $1 $2 >/dev/null
+    then
+        if [ "$PATTERN" == '*' ]
+        then
+            diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" |
+              sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g"
+        else
+            grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g"
+        fi
+        FAILED=YES
+    fi
+}
+
+function check_warning() {
+    if [ "$2" == 'long lines' ]
+    then
+        grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g"
+    else
+        echo "$1: warning: $2"
+    fi
+    WARNED=YES
+}
+
+function check_init() {
+    echo Check source files...
+    FAILED_FILES=0
+    WARNED_FILES=0
+    TOTAL_FILES=0
+}
+
+function check_done() {
+    echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
+    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
+
+    if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ]
+    then
+	if [ "$WARNING" == 'INTERACTIVE' ]
+	then
+	    echo -n "Are the files with errors/warnings acceptable? (yes/no) "
+	    while read answer
+	    do
+		if [ "$answer" == 'yes' ]
+		then
+		    return 0
+		elif [ "$answer" == 'no' ]
+		then
+		    return 1
+		fi
+		echo -n "Are the files with errors/warnings acceptable? (yes/no) "
+	    done
+	elif [ "$WARNING" == 'WERROR' ]
+	then
+	    return 1
+	fi
+    fi
+}
+
+function check_begin() {
+    ((TOTAL_FILES++))
+    FAILED=NO
+    WARNED=NO
+}
+
+function check_end() {
+    if [ $FAILED == YES ]
+    then
+	((++FAILED_FILES))
+    fi
+    if [ $WARNED == YES ]
+    then
+	((++WARNED_FILES))
+    fi
+}
+
+
+
+# checks
+
+function header_check() {
+    if echo $1 | grep -q -E 'Makefile\.am$'
+    then
+	return
+    fi
+
+    TMP_FILE=`mktemp`
+
+    (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-"$(hg_year $1)"
+ * 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.
+ *
+ */
+"
+    awk 'BEGIN { pm=0; }
+     pm==3 { print }
+     /\/\* / && pm==0 { pm=1;}
+     /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
+     /\*\// && pm==1 { pm=2;}
+    ' $1
+    ) >$TMP_FILE
+
+    "$ACTION"_action "$TMP_FILE" "$1" header
+}
+
+function tabs_check() {
+    if echo $1 | grep -q -v -E 'Makefile\.am$'
+    then
+        OLD_PATTERN=$(echo -e '\t')
+        NEW_PATTERN='        '
+    else
+        OLD_PATTERN='        '
+        NEW_PATTERN=$(echo -e '\t')
+    fi
+    TMP_FILE=`mktemp`
+    cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
+
+    "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
+}
+
+function spaces_check() {
+    TMP_FILE=`mktemp`
+    cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
+
+    "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
+}
+
+function long_lines_check() {
+    if cat $1 | grep -q -E '.{81,}'
+    then
+	"$ACTION"_warning $1 'long lines'
+    fi
+}
+
+# process the file
+
+function process_file() {
+    if [ "$ACTION" == 'update' ]
+    then
+        echo -n "    $ACTION $1..."
+    else
+        echo "	  $ACTION $1..."
+    fi
+
+    CHECKING="header tabs spaces long_lines"
+
+    "$ACTION"_begin $1
+    for check in $CHECKING
+    do
+	"$check"_check $1
+    done
+    "$ACTION"_end $1
+    if [ "$ACTION" == 'update' ]
+    then
+        echo
+    fi
+}
+
+function process_all {
+    "$ACTION"_init
+    while read file
+    do
+	process_file $file
+    done < <($FILES)
+    "$ACTION"_done
+}
+
+while [ $# -gt 0 ]
+do
+    
+    if [ "$1" == '--help' ] || [ "$1" == '-h' ]
+    then
+	echo -n \
+"Usage:
+  $0 [OPTIONS] [files]
+Options:
+  --dry-run|-n
+     Check the files, but do not modify them.
+  --interactive|-i
+     If --dry-run is specified and the checker emits warnings,
+     then the user is asked if the warnings should be considered
+     errors.
+  --werror|-w
+     Make all warnings into errors.
+  --all|-a
+     Check all source files in the repository.
+  --modified|-m
+     Check only the modified (and new) source files. This option is
+     useful to check the modification before making a commit.
+  --changed|-c
+     Check only the changed source files compared to the parent(s) of
+     the current hg node.  This option is useful as hg hook script.
+     To automatically check all your changes before making a commit,
+     add the following section to the appropriate .hg/hgrc file.
+
+       [hooks]
+       pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
+
+  --help|-h
+     Print this help message.
+  files
+     The files to check/unify. If no file names are given, the modified
+     source files will be checked/unified (just like using the
+     --modified|-m option).
+"
+        exit 0
+    elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
+    then
+	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
+	ACTION=check
+    elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
+    then
+	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
+	FILES=all_files
+    elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
+    then
+	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
+	FILES=changed_files
+    elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
+    then
+	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
+	FILES=modified_files
+    elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
+    then
+	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
+	WARNING='INTERACTIVE'
+    elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
+    then
+	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
+	WARNING='WERROR'
+    elif [ $(echo x$1 | cut -c 2) == '-' ]
+    then
+	echo "Invalid option $1" >&2 && exit 1
+    else
+	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
+	GIVEN_FILES=$@
+	FILES=given_files
+	break
+    fi
+    
+    shift
+done
+
+if [ -z $FILES ]
+then
+    FILES=modified_files
+fi
+
+if [ -z $ACTION ]
+then
+    ACTION=update
+fi
+
+process_all
diff --git a/scripts/valgrind-wrapper.sh b/scripts/valgrind-wrapper.sh
new file mode 100755
index 0000000..bbb1222
--- /dev/null
+++ b/scripts/valgrind-wrapper.sh
@@ -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
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..96fc5dd
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,161 @@
+INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}
+  ${PROJECT_BINARY_DIR}
+)
+
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
+
+SET(TEST_WITH_VALGRIND "NO" CACHE STRING
+  "Run the test with valgrind (YES/NO).")
+SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.")
+
+SET(TESTS
+  adaptors_test
+  arc_look_up_test
+  bellman_ford_test
+  bfs_test
+  bpgraph_test
+  circulation_test
+  connectivity_test
+  counter_test
+  dfs_test
+  digraph_test
+  dijkstra_test
+  dim_test
+  edge_set_test
+  error_test
+  euler_test
+  fractional_matching_test
+  gomory_hu_test
+  graph_copy_test
+  graph_test
+  graph_utils_test
+  hao_orlin_test
+  heap_test
+  kruskal_test
+  lgf_reader_writer_test
+  lgf_test
+  maps_test
+  matching_test
+  max_cardinality_search_test
+  max_clique_test
+  max_flow_test
+  min_cost_arborescence_test
+  min_cost_flow_test
+  min_mean_cycle_test
+  nagamochi_ibaraki_test
+  path_test
+  planarity_test
+  radix_sort_test
+  random_test
+  suurballe_test
+  time_measure_test
+  tsp_test
+  unionfind_test
+)
+
+IF(LEMON_HAVE_LP)
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(lp_test lp_test.cc)
+  ELSE()
+    ADD_EXECUTABLE(lp_test EXCLUDE_FROM_ALL lp_test.cc)
+  ENDIF()
+
+  SET(LP_TEST_LIBS lemon)
+
+  IF(LEMON_HAVE_GLPK)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CPLEX)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${ILOG_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CLP)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_SOPLEX)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${SOPLEX_LIBRARIES})
+  ENDIF()
+
+  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
+  ADD_TEST(lp_test lp_test)
+  ADD_DEPENDENCIES(check lp_test)
+
+  IF(WIN32 AND LEMON_HAVE_GLPK)
+    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
+    )
+  ENDIF()
+
+  IF(WIN32 AND LEMON_HAVE_CPLEX)
+    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
+    )
+  ENDIF()
+ENDIF()
+
+IF(LEMON_HAVE_MIP)
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(mip_test mip_test.cc)
+  ELSE()
+    ADD_EXECUTABLE(mip_test EXCLUDE_FROM_ALL mip_test.cc)
+  ENDIF()
+
+  SET(MIP_TEST_LIBS lemon)
+
+  IF(LEMON_HAVE_GLPK)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CPLEX)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${ILOG_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CBC)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
+  ENDIF()
+
+  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
+  ADD_TEST(mip_test mip_test)
+  ADD_DEPENDENCIES(check mip_test)
+
+  IF(WIN32 AND LEMON_HAVE_GLPK)
+    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
+    )
+  ENDIF()
+
+  IF(WIN32 AND LEMON_HAVE_CPLEX)
+    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
+    )
+  ENDIF()
+ENDIF()
+
+FOREACH(TEST_NAME ${TESTS})
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
+  ELSE()
+    ADD_EXECUTABLE(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_NAME}.cc)
+  ENDIF()
+  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
+    IF(TEST_WITH_VALGRIND)
+      ADD_TEST(${TEST_NAME}
+        valgrind --error-exitcode=1 ${VALGRIND_FLAGS}
+        ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} )
+    ELSE()
+      ADD_TEST(${TEST_NAME} ${TEST_NAME})
+    ENDIF()
+  ADD_DEPENDENCIES(check ${TEST_NAME})
+ENDFOREACH()
diff --git a/test/adaptors_test.cc b/test/adaptors_test.cc
new file mode 100644
index 0000000..9077db9
--- /dev/null
+++ b/test/adaptors_test.cc
@@ -0,0 +1,1468 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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 <limits>
+
+#include <lemon/list_graph.h>
+#include <lemon/grid_graph.h>
+#include <lemon/bfs.h>
+#include <lemon/path.h>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/graph_components.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concept_check.h>
+
+#include <lemon/adaptors.h>
+
+#include "test/test_tools.h"
+#include "test/graph_test.h"
+
+using namespace lemon;
+
+void checkReverseDigraph() {
+  // Check concepts
+  checkConcept<concepts::Digraph, ReverseDigraph<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, ReverseDigraph<ListDigraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               ReverseDigraph<ListDigraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               ReverseDigraph<ListDigraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               ReverseDigraph<ListDigraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               ReverseDigraph<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef ReverseDigraph<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  // Add nodes and arcs to the original digraph
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a3);
+
+  // Check the adaptor
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 0);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 2);
+
+  checkGraphInArcList(adaptor, n1, 2);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the orientation of the arcs
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    check(adaptor.source(a) == digraph.target(a), "Wrong reverse");
+    check(adaptor.target(a) == digraph.source(a), "Wrong reverse");
+  }
+
+  // Add and erase nodes and arcs in the digraph through the adaptor
+  Adaptor::Node n4 = adaptor.addNode();
+
+  Adaptor::Arc a4 = adaptor.addArc(n4, n3);
+  Adaptor::Arc a5 = adaptor.addArc(n2, n4);
+  Adaptor::Arc a6 = adaptor.addArc(n2, n4);
+  Adaptor::Arc a7 = adaptor.addArc(n1, n4);
+  Adaptor::Arc a8 = adaptor.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(a6,a7,a8);
+
+  adaptor.erase(a1);
+  adaptor.erase(n3);
+
+  // Check the adaptor
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 4);
+  checkGraphConArcList(adaptor, 4);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n4, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the digraph
+  checkGraphNodeList(digraph, 3);
+  checkGraphArcList(digraph, 4);
+  checkGraphConArcList(digraph, 4);
+
+  checkGraphOutArcList(digraph, n1, 0);
+  checkGraphOutArcList(digraph, n2, 1);
+  checkGraphOutArcList(digraph, n4, 3);
+
+  checkGraphInArcList(digraph, n1, 2);
+  checkGraphInArcList(digraph, n2, 2);
+  checkGraphInArcList(digraph, n4, 0);
+
+  checkNodeIds(digraph);
+  checkArcIds(digraph);
+
+  checkGraphNodeMap(digraph);
+  checkGraphArcMap(digraph);
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = n4;
+  nd = n4;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = a4;
+  ad = a5;
+  Adaptor::Arc aa = a1;
+  aa = a2;
+}
+
+void checkSubDigraph() {
+  // Check concepts
+  checkConcept<concepts::Digraph, SubDigraph<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, SubDigraph<ListDigraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               SubDigraph<ListDigraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               SubDigraph<ListDigraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               SubDigraph<ListDigraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               SubDigraph<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Digraph::NodeMap<bool> NodeFilter;
+  typedef Digraph::ArcMap<bool> ArcFilter;
+  typedef SubDigraph<Digraph, NodeFilter, ArcFilter> Adaptor;
+
+  Digraph digraph;
+  NodeFilter node_filter(digraph);
+  ArcFilter arc_filter(digraph);
+  Adaptor adaptor(digraph, node_filter, arc_filter);
+
+  // Add nodes and arcs to the original digraph and the adaptor
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
+
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide an arc
+  adaptor.status(a2, false);
+  adaptor.disable(a3);
+  if (!adaptor.status(a3)) adaptor.enable(a3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 2);
+  checkGraphConArcList(adaptor, 2);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide a node
+  adaptor.status(n1, false);
+  adaptor.disable(n3);
+  if (!adaptor.status(n3)) adaptor.enable(n3);
+
+  checkGraphNodeList(adaptor, 2);
+  checkGraphArcList(adaptor, 1);
+  checkGraphConArcList(adaptor, 1);
+
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n2, 0);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide all nodes and arcs
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = n3;
+  nd = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = a3;
+  ad = a3;
+  Adaptor::Arc aa = a1;
+  aa = a2;
+}
+
+void checkFilterNodes1() {
+  // Check concepts
+  checkConcept<concepts::Digraph, FilterNodes<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, FilterNodes<ListDigraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               FilterNodes<ListDigraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               FilterNodes<ListDigraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               FilterNodes<ListDigraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               FilterNodes<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Digraph::NodeMap<bool> NodeFilter;
+  typedef FilterNodes<Digraph, NodeFilter> Adaptor;
+
+  Digraph digraph;
+  NodeFilter node_filter(digraph);
+  Adaptor adaptor(digraph, node_filter);
+
+  // Add nodes and arcs to the original digraph and the adaptor
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide a node
+  adaptor.status(n1, false);
+  adaptor.disable(n3);
+  if (!adaptor.status(n3)) adaptor.enable(n3);
+
+  checkGraphNodeList(adaptor, 2);
+  checkGraphArcList(adaptor, 1);
+  checkGraphConArcList(adaptor, 1);
+
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n2, 0);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide all nodes
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = n3;
+  nd = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = a3;
+  ad = a3;
+  Adaptor::Arc aa = a1;
+  aa = a2;
+}
+
+void checkFilterArcs() {
+  // Check concepts
+  checkConcept<concepts::Digraph, FilterArcs<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, FilterArcs<ListDigraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               FilterArcs<ListDigraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               FilterArcs<ListDigraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               FilterArcs<ListDigraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               FilterArcs<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Digraph::ArcMap<bool> ArcFilter;
+  typedef FilterArcs<Digraph, ArcFilter> Adaptor;
+
+  Digraph digraph;
+  ArcFilter arc_filter(digraph);
+  Adaptor adaptor(digraph, arc_filter);
+
+  // Add nodes and arcs to the original digraph and the adaptor
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
+
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide an arc
+  adaptor.status(a2, false);
+  adaptor.disable(a3);
+  if (!adaptor.status(a3)) adaptor.enable(a3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 2);
+  checkGraphConArcList(adaptor, 2);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide all arcs
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = n3;
+  nd = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = a3;
+  ad = a3;
+  Adaptor::Arc aa = a1;
+  aa = a2;
+}
+
+void checkUndirector() {
+  // Check concepts
+  checkConcept<concepts::Graph, Undirector<concepts::Digraph> >();
+  checkConcept<concepts::Graph, Undirector<ListDigraph> >();
+  checkConcept<concepts::AlterableGraphComponent<>,
+               Undirector<ListDigraph> >();
+  checkConcept<concepts::ExtendableGraphComponent<>,
+               Undirector<ListDigraph> >();
+  checkConcept<concepts::ErasableGraphComponent<>,
+               Undirector<ListDigraph> >();
+  checkConcept<concepts::ClearableGraphComponent<>,
+               Undirector<ListDigraph> >();
+
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Undirector<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  // Add nodes and arcs/edges to the original digraph and the adaptor
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
+
+  // Check the original digraph
+  checkGraphNodeList(digraph, 3);
+  checkGraphArcList(digraph, 3);
+  checkGraphConArcList(digraph, 3);
+
+  checkGraphOutArcList(digraph, n1, 2);
+  checkGraphOutArcList(digraph, n2, 1);
+  checkGraphOutArcList(digraph, n3, 0);
+
+  checkGraphInArcList(digraph, n1, 0);
+  checkGraphInArcList(digraph, n2, 1);
+  checkGraphInArcList(digraph, n3, 2);
+
+  checkNodeIds(digraph);
+  checkArcIds(digraph);
+
+  checkGraphNodeMap(digraph);
+  checkGraphArcMap(digraph);
+
+  // Check the adaptor
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 2);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Check the edges of the adaptor
+  for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) {
+    check(adaptor.u(e) == digraph.source(e), "Wrong undir");
+    check(adaptor.v(e) == digraph.target(e), "Wrong undir");
+  }
+
+  // Check CombinedArcMap
+  typedef Adaptor::CombinedArcMap
+    <Digraph::ArcMap<int>, Digraph::ArcMap<int> > IntCombinedMap;
+  typedef Adaptor::CombinedArcMap
+    <Digraph::ArcMap<bool>, Digraph::ArcMap<bool> > BoolCombinedMap;
+  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
+    IntCombinedMap>();
+  checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
+    BoolCombinedMap>();
+
+  Digraph::ArcMap<int> fw_map(digraph), bk_map(digraph);
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    fw_map[a] = digraph.id(a);
+    bk_map[a] = -digraph.id(a);
+  }
+
+  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::ArcMap<int> >
+    comb_map(fw_map, bk_map);
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    if (adaptor.source(a) == digraph.source(a)) {
+      check(comb_map[a] == fw_map[a], "Wrong combined map");
+    } else {
+      check(comb_map[a] == bk_map[a], "Wrong combined map");
+    }
+  }
+
+  // Check the conversion of nodes and arcs/edges
+  Digraph::Node nd = n3;
+  nd = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = e3;
+  ad = e3;
+  Adaptor::Edge ea = a1;
+  ea = a2;
+}
+
+void checkResidualDigraph() {
+  // Check concepts
+  checkConcept<concepts::Digraph, ResidualDigraph<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, ResidualDigraph<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Digraph::ArcMap<int> IntArcMap;
+  typedef ResidualDigraph<Digraph, IntArcMap> Adaptor;
+
+  Digraph digraph;
+  IntArcMap capacity(digraph), flow(digraph);
+  Adaptor adaptor(digraph, capacity, flow);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+  Digraph::Node n4 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n1, n4);
+  Digraph::Arc a4 = digraph.addArc(n2, n3);
+  Digraph::Arc a5 = digraph.addArc(n2, n4);
+  Digraph::Arc a6 = digraph.addArc(n3, n4);
+
+  capacity[a1] = 8;
+  capacity[a2] = 6;
+  capacity[a3] = 4;
+  capacity[a4] = 4;
+  capacity[a5] = 6;
+  capacity[a6] = 10;
+
+  // Check the adaptor with various flow values
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    flow[a] = 0;
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, n1, 3);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 1);
+  checkGraphOutArcList(adaptor, n4, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    flow[a] = capacity[a] / 2;
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 12);
+  checkGraphConArcList(adaptor, 12);
+
+  checkGraphOutArcList(adaptor, n1, 3);
+  checkGraphOutArcList(adaptor, n2, 3);
+  checkGraphOutArcList(adaptor, n3, 3);
+  checkGraphOutArcList(adaptor, n4, 3);
+
+  checkGraphInArcList(adaptor, n1, 3);
+  checkGraphInArcList(adaptor, n2, 3);
+  checkGraphInArcList(adaptor, n3, 3);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    flow[a] = capacity[a];
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, n1, 0);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 2);
+  checkGraphOutArcList(adaptor, n4, 3);
+
+  checkGraphInArcList(adaptor, n1, 3);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 1);
+  checkGraphInArcList(adaptor, n4, 0);
+
+  // Saturate all backward arcs
+  // (set the flow to zero on all forward arcs)
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    if (adaptor.backward(a))
+      adaptor.augment(a, adaptor.residualCapacity(a));
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, n1, 3);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 1);
+  checkGraphOutArcList(adaptor, n4, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  // Find maximum flow by augmenting along shortest paths
+  int flow_value = 0;
+  Adaptor::ResidualCapacity res_cap(adaptor);
+  while (true) {
+
+    Bfs<Adaptor> bfs(adaptor);
+    bfs.run(n1, n4);
+
+    if (!bfs.reached(n4)) break;
+
+    Path<Adaptor> p = bfs.path(n4);
+
+    int min = std::numeric_limits<int>::max();
+    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
+      if (res_cap[a] < min) min = res_cap[a];
+    }
+
+    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
+      adaptor.augment(a, min);
+    }
+    flow_value += min;
+  }
+
+  check(flow_value == 18, "Wrong flow with res graph adaptor");
+
+  // Check forward() and backward()
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    check(adaptor.forward(a) != adaptor.backward(a),
+          "Wrong forward() or backward()");
+    check((adaptor.forward(a) && adaptor.forward(Digraph::Arc(a)) == a) ||
+          (adaptor.backward(a) && adaptor.backward(Digraph::Arc(a)) == a),
+          "Wrong forward() or backward()");
+  }
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = Adaptor::NodeIt(adaptor);
+  nd = ++Adaptor::NodeIt(adaptor);
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = Adaptor::ArcIt(adaptor);
+  ad = ++Adaptor::ArcIt(adaptor);
+}
+
+void checkSplitNodes() {
+  // Check concepts
+  checkConcept<concepts::Digraph, SplitNodes<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, SplitNodes<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef SplitNodes<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a1,a2,a3);
+
+  checkGraphNodeList(adaptor, 6);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0);
+
+  checkGraphInArcList(adaptor, adaptor.inNode(n1), 0);
+  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n2), 1);
+  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n3), 2);
+  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check split
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    if (adaptor.origArc(a)) {
+      Digraph::Arc oa = a;
+      check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)),
+            "Wrong split");
+      check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)),
+            "Wrong split");
+    } else {
+      Digraph::Node on = a;
+      check(adaptor.source(a) == adaptor.inNode(on), "Wrong split");
+      check(adaptor.target(a) == adaptor.outNode(on), "Wrong split");
+    }
+  }
+
+  // Check combined node map
+  typedef Adaptor::CombinedNodeMap
+    <Digraph::NodeMap<int>, Digraph::NodeMap<int> > IntCombinedNodeMap;
+  typedef Adaptor::CombinedNodeMap
+    <Digraph::NodeMap<bool>, Digraph::NodeMap<bool> > BoolCombinedNodeMap;
+  checkConcept<concepts::ReferenceMap<Adaptor::Node, int, int&, const int&>,
+    IntCombinedNodeMap>();
+//checkConcept<concepts::ReferenceMap<Adaptor::Node, bool, bool&, const bool&>,
+//  BoolCombinedNodeMap>();
+  checkConcept<concepts::ReadWriteMap<Adaptor::Node, bool>,
+    BoolCombinedNodeMap>();
+
+  Digraph::NodeMap<int> in_map(digraph), out_map(digraph);
+  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+    in_map[n] = digraph.id(n);
+    out_map[n] = -digraph.id(n);
+  }
+
+  Adaptor::CombinedNodeMap<Digraph::NodeMap<int>, Digraph::NodeMap<int> >
+    node_map(in_map, out_map);
+  for (Adaptor::NodeIt n(adaptor); n != INVALID; ++n) {
+    if (adaptor.inNode(n)) {
+      check(node_map[n] == in_map[n], "Wrong combined node map");
+    } else {
+      check(node_map[n] == out_map[n], "Wrong combined node map");
+    }
+  }
+
+  // Check combined arc map
+  typedef Adaptor::CombinedArcMap
+    <Digraph::ArcMap<int>, Digraph::NodeMap<int> > IntCombinedArcMap;
+  typedef Adaptor::CombinedArcMap
+    <Digraph::ArcMap<bool>, Digraph::NodeMap<bool> > BoolCombinedArcMap;
+  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
+    IntCombinedArcMap>();
+//checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
+//  BoolCombinedArcMap>();
+  checkConcept<concepts::ReadWriteMap<Adaptor::Arc, bool>,
+    BoolCombinedArcMap>();
+
+  Digraph::ArcMap<int> a_map(digraph);
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    a_map[a] = digraph.id(a);
+  }
+
+  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::NodeMap<int> >
+    arc_map(a_map, out_map);
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    check(arc_map[adaptor.arc(a)] == a_map[a],  "Wrong combined arc map");
+  }
+  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+    check(arc_map[adaptor.arc(n)] == out_map[n],  "Wrong combined arc map");
+  }
+
+  // Check the conversion of nodes
+  Digraph::Node nd = adaptor.inNode(n1);
+  check (nd == n1, "Wrong node conversion");
+  nd = adaptor.outNode(n2);
+  check (nd == n2, "Wrong node conversion");
+}
+
+void checkSubGraph() {
+  // Check concepts
+  checkConcept<concepts::Graph, SubGraph<concepts::Graph> >();
+  checkConcept<concepts::Graph, SubGraph<ListGraph> >();
+  checkConcept<concepts::AlterableGraphComponent<>,
+               SubGraph<ListGraph> >();
+  checkConcept<concepts::ExtendableGraphComponent<>,
+               SubGraph<ListGraph> >();
+  checkConcept<concepts::ErasableGraphComponent<>,
+               SubGraph<ListGraph> >();
+  checkConcept<concepts::ClearableGraphComponent<>,
+               SubGraph<ListGraph> >();
+
+  // Create a graph and an adaptor
+  typedef ListGraph Graph;
+  typedef Graph::NodeMap<bool> NodeFilter;
+  typedef Graph::EdgeMap<bool> EdgeFilter;
+  typedef SubGraph<Graph, NodeFilter, EdgeFilter> Adaptor;
+
+  Graph graph;
+  NodeFilter node_filter(graph);
+  EdgeFilter edge_filter(graph);
+  Adaptor adaptor(graph, node_filter, edge_filter);
+
+  // Add nodes and edges to the original graph and the adaptor
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+  Adaptor::Node n4 = adaptor.addNode();
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
+  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
+
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 2);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 3);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide an edge
+  adaptor.status(e2, false);
+  adaptor.disable(e3);
+  if (!adaptor.status(e3)) adaptor.enable(e3);
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 1);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide a node
+  adaptor.status(n1, false);
+  adaptor.disable(n3);
+  if (!adaptor.status(n3)) adaptor.enable(n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 4);
+  checkGraphEdgeList(adaptor, 2);
+  checkGraphConArcList(adaptor, 4);
+  checkGraphConEdgeList(adaptor, 2);
+
+  checkGraphIncEdgeArcLists(adaptor, n2, 1);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide all nodes and edges
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Check the conversion of nodes and edges
+  Graph::Node ng = n3;
+  ng = n4;
+  Adaptor::Node na = n1;
+  na = n2;
+  Graph::Edge eg = e3;
+  eg = e4;
+  Adaptor::Edge ea = e1;
+  ea = e2;
+}
+
+void checkFilterNodes2() {
+  // Check concepts
+  checkConcept<concepts::Graph, FilterNodes<concepts::Graph> >();
+  checkConcept<concepts::Graph, FilterNodes<ListGraph> >();
+  checkConcept<concepts::AlterableGraphComponent<>,
+               FilterNodes<ListGraph> >();
+  checkConcept<concepts::ExtendableGraphComponent<>,
+               FilterNodes<ListGraph> >();
+  checkConcept<concepts::ErasableGraphComponent<>,
+               FilterNodes<ListGraph> >();
+  checkConcept<concepts::ClearableGraphComponent<>,
+               FilterNodes<ListGraph> >();
+
+  // Create a graph and an adaptor
+  typedef ListGraph Graph;
+  typedef Graph::NodeMap<bool> NodeFilter;
+  typedef FilterNodes<Graph, NodeFilter> Adaptor;
+
+  // Add nodes and edges to the original graph and the adaptor
+  Graph graph;
+  NodeFilter node_filter(graph);
+  Adaptor adaptor(graph, node_filter);
+
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+  Adaptor::Node n4 = adaptor.addNode();
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
+  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 2);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 3);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide a node
+  adaptor.status(n1, false);
+  adaptor.disable(n3);
+  if (!adaptor.status(n3)) adaptor.enable(n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 4);
+  checkGraphEdgeList(adaptor, 2);
+  checkGraphConArcList(adaptor, 4);
+  checkGraphConEdgeList(adaptor, 2);
+
+  checkGraphIncEdgeArcLists(adaptor, n2, 1);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide all nodes
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Check the conversion of nodes and edges
+  Graph::Node ng = n3;
+  ng = n4;
+  Adaptor::Node na = n1;
+  na = n2;
+  Graph::Edge eg = e3;
+  eg = e4;
+  Adaptor::Edge ea = e1;
+  ea = e2;
+}
+
+void checkFilterEdges() {
+  // Check concepts
+  checkConcept<concepts::Graph, FilterEdges<concepts::Graph> >();
+  checkConcept<concepts::Graph, FilterEdges<ListGraph> >();
+  checkConcept<concepts::AlterableGraphComponent<>,
+               FilterEdges<ListGraph> >();
+  checkConcept<concepts::ExtendableGraphComponent<>,
+               FilterEdges<ListGraph> >();
+  checkConcept<concepts::ErasableGraphComponent<>,
+               FilterEdges<ListGraph> >();
+  checkConcept<concepts::ClearableGraphComponent<>,
+               FilterEdges<ListGraph> >();
+
+  // Create a graph and an adaptor
+  typedef ListGraph Graph;
+  typedef Graph::EdgeMap<bool> EdgeFilter;
+  typedef FilterEdges<Graph, EdgeFilter> Adaptor;
+
+  Graph graph;
+  EdgeFilter edge_filter(graph);
+  Adaptor adaptor(graph, edge_filter);
+
+  // Add nodes and edges to the original graph and the adaptor
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+  Adaptor::Node n4 = adaptor.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
+  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
+
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 2);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 3);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide an edge
+  adaptor.status(e2, false);
+  adaptor.disable(e3);
+  if (!adaptor.status(e3)) adaptor.enable(e3);
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 1);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide all edges
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Check the conversion of nodes and edges
+  Graph::Node ng = n3;
+  ng = n4;
+  Adaptor::Node na = n1;
+  na = n2;
+  Graph::Edge eg = e3;
+  eg = e4;
+  Adaptor::Edge ea = e1;
+  ea = e2;
+}
+
+void checkOrienter() {
+  // Check concepts
+  checkConcept<concepts::Digraph, Orienter<concepts::Graph> >();
+  checkConcept<concepts::Digraph, Orienter<ListGraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               Orienter<ListGraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               Orienter<ListGraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               Orienter<ListGraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               Orienter<ListGraph> >();
+
+  // Create a graph and an adaptor
+  typedef ListGraph Graph;
+  typedef ListGraph::EdgeMap<bool> DirMap;
+  typedef Orienter<Graph> Adaptor;
+
+  Graph graph;
+  DirMap dir(graph);
+  Adaptor adaptor(graph, dir);
+
+  // Add nodes and edges to the original graph and the adaptor
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Adaptor::Arc e3 = adaptor.addArc(n2, n3);
+
+  dir[e1] = dir[e2] = dir[e3] = true;
+
+  // Check the original graph
+  checkGraphNodeList(graph, 3);
+  checkGraphArcList(graph, 6);
+  checkGraphConArcList(graph, 6);
+  checkGraphEdgeList(graph, 3);
+  checkGraphConEdgeList(graph, 3);
+
+  checkGraphIncEdgeArcLists(graph, n1, 2);
+  checkGraphIncEdgeArcLists(graph, n2, 2);
+  checkGraphIncEdgeArcLists(graph, n3, 2);
+
+  checkNodeIds(graph);
+  checkArcIds(graph);
+  checkEdgeIds(graph);
+
+  checkGraphNodeMap(graph);
+  checkGraphArcMap(graph);
+  checkGraphEdgeMap(graph);
+
+  // Check the adaptor
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check direction changing
+  {
+    dir[e1] = true;
+    Adaptor::Node u = adaptor.source(e1);
+    Adaptor::Node v = adaptor.target(e1);
+
+    dir[e1] = false;
+    check (u == adaptor.target(e1), "Wrong dir");
+    check (v == adaptor.source(e1), "Wrong dir");
+
+    check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir");
+    dir[e1] = n1 == u;
+  }
+
+  {
+    dir[e2] = true;
+    Adaptor::Node u = adaptor.source(e2);
+    Adaptor::Node v = adaptor.target(e2);
+
+    dir[e2] = false;
+    check (u == adaptor.target(e2), "Wrong dir");
+    check (v == adaptor.source(e2), "Wrong dir");
+
+    check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir");
+    dir[e2] = n3 == u;
+  }
+
+  {
+    dir[e3] = true;
+    Adaptor::Node u = adaptor.source(e3);
+    Adaptor::Node v = adaptor.target(e3);
+
+    dir[e3] = false;
+    check (u == adaptor.target(e3), "Wrong dir");
+    check (v == adaptor.source(e3), "Wrong dir");
+
+    check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir");
+    dir[e3] = n2 == u;
+  }
+
+  // Check the adaptor again
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 1);
+
+  checkGraphInArcList(adaptor, n1, 1);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check reverseArc()
+  adaptor.reverseArc(e2);
+  adaptor.reverseArc(e3);
+  adaptor.reverseArc(e2);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 0);
+  checkGraphOutArcList(adaptor, n3, 2);
+
+  checkGraphInArcList(adaptor, n1, 1);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 0);
+
+  // Check the conversion of nodes and arcs/edges
+  Graph::Node ng = n3;
+  ng = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Graph::Edge eg = e3;
+  eg = e3;
+  Adaptor::Arc aa = e1;
+  aa = e2;
+}
+
+void checkCombiningAdaptors() {
+  // Create a grid graph
+  GridGraph graph(2,2);
+  GridGraph::Node n1 = graph(0,0);
+  GridGraph::Node n2 = graph(0,1);
+  GridGraph::Node n3 = graph(1,0);
+  GridGraph::Node n4 = graph(1,1);
+
+  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;
+
+  // Apply several adaptors on the grid graph
+  typedef Orienter< const GridGraph, GridGraph::EdgeMap<bool> >
+    OrientedGridGraph;
+  typedef SplitNodes<OrientedGridGraph> SplitGridGraph;
+  typedef Undirector<const SplitGridGraph> USplitGridGraph;
+  checkConcept<concepts::Digraph, SplitGridGraph>();
+  checkConcept<concepts::Graph, USplitGridGraph>();
+
+  OrientedGridGraph oadaptor = orienter(graph, dir_map);
+  SplitGridGraph adaptor = splitNodes(oadaptor);
+  USplitGridGraph uadaptor = undirector(adaptor);
+
+  // Check adaptor
+  checkGraphNodeList(adaptor, 8);
+  checkGraphArcList(adaptor, 8);
+  checkGraphConArcList(adaptor, 8);
+
+  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);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check uadaptor
+  checkGraphNodeList(uadaptor, 8);
+  checkGraphEdgeList(uadaptor, 8);
+  checkGraphArcList(uadaptor, 16);
+  checkGraphConEdgeList(uadaptor, 8);
+  checkGraphConArcList(uadaptor, 16);
+
+  checkNodeIds(uadaptor);
+  checkEdgeIds(uadaptor);
+  checkArcIds(uadaptor);
+
+  checkGraphNodeMap(uadaptor);
+  checkGraphEdgeMap(uadaptor);
+  checkGraphArcMap(uadaptor);
+
+  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);
+}
+
+int main(int, const char **) {
+  // Check the digraph adaptors (using ListDigraph)
+  checkReverseDigraph();
+  checkSubDigraph();
+  checkFilterNodes1();
+  checkFilterArcs();
+  checkUndirector();
+  checkResidualDigraph();
+  checkSplitNodes();
+
+  // Check the graph adaptors (using ListGraph)
+  checkSubGraph();
+  checkFilterNodes2();
+  checkFilterEdges();
+  checkOrienter();
+
+  // Combine adaptors (using GridGraph)
+  checkCombiningAdaptors();
+
+  return 0;
+}
diff --git a/test/arc_look_up_test.cc b/test/arc_look_up_test.cc
new file mode 100644
index 0000000..2f4edf5
--- /dev/null
+++ b/test/arc_look_up_test.cc
@@ -0,0 +1,84 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include "lemon/list_graph.h"
+#include "lemon/lgf_reader.h"
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+const std::string lgf =
+  "@nodes\n"
+"label\n"
+"0\n"
+"1\n"
+"2\n"
+"3\n"
+"4\n"
+"5\n"
+"6\n"
+"@arcs\n"
+"label\n"
+"5 6 0\n"
+"5 4 1\n"
+"4 6 2\n"
+"3 4 3\n"
+"3 4 4\n"
+"3 2 5\n"
+"3 5 6\n"
+"3 5 7\n"
+"3 5 8\n"
+"3 5 9\n"
+"2 4 10\n"
+"2 4 11\n"
+"2 4 12\n"
+"2 4 13\n"
+"1 2 14\n"
+"1 2 15\n"
+"1 0 16\n"
+"1 3 17\n"
+"1 3 18\n"
+"1 3 19\n"
+"1 3 20\n"
+"0 2 21\n"
+"0 2 22\n"
+"0 2 23\n"
+"0 2 24\n";
+
+
+int main() {
+  ListDigraph graph;
+  std::istringstream lgfs(lgf);
+  DigraphReader<ListDigraph>(graph, lgfs).run();
+
+  AllArcLookUp<ListDigraph> lookup(graph);
+
+  int numArcs = countArcs(graph);
+
+  int arcCnt = 0;
+  for(ListDigraph::NodeIt n1(graph); n1 != INVALID; ++n1)
+    for(ListDigraph::NodeIt n2(graph); n2 != INVALID; ++n2)
+      for(ListDigraph::Arc a = lookup(n1, n2); a != INVALID;
+          a = lookup(n1, n2, a))
+        ++arcCnt;
+  check(arcCnt==numArcs, "Wrong total number of arcs");
+
+  return 0;
+}
diff --git a/test/bellman_ford_test.cc b/test/bellman_ford_test.cc
new file mode 100644
index 0000000..14faa07
--- /dev/null
+++ b/test/bellman_ford_test.cc
@@ -0,0 +1,289 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/bellman_ford.h>
+#include <lemon/path.h>
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "@arcs\n"
+  "    length\n"
+  "0 1 3\n"
+  "1 2 -3\n"
+  "1 2 -5\n"
+  "1 3 -2\n"
+  "0 2 -1\n"
+  "1 2 -4\n"
+  "0 3 2\n"
+  "4 2 -5\n"
+  "2 3 1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 3\n";
+
+
+void checkBellmanFordCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
+  typedef BellmanFord<Digraph, LengthMap> BF;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+
+  Digraph gr;
+  Node s, t, n;
+  Arc e;
+  Value l;
+  ::lemon::ignore_unused_variable_warning(l);
+  int k=3;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+  BF::DistMap d(gr);
+  BF::PredMap p(gr);
+  LengthMap length;
+  concepts::Path<Digraph> pp;
+
+  {
+    BF bf_test(gr,length);
+    const BF& const_bf_test = bf_test;
+
+    bf_test.run(s);
+    bf_test.run(s,k);
+
+    bf_test.init();
+    bf_test.addSource(s);
+    bf_test.addSource(s, 1);
+    b = bf_test.processNextRound();
+    b = bf_test.processNextWeakRound();
+
+    bf_test.start();
+    bf_test.checkedStart();
+    bf_test.limitedStart(k);
+
+    l  = const_bf_test.dist(t);
+    e  = const_bf_test.predArc(t);
+    s  = const_bf_test.predNode(t);
+    b  = const_bf_test.reached(t);
+    d  = const_bf_test.distMap();
+    p  = const_bf_test.predMap();
+    pp = const_bf_test.path(t);
+    pp = const_bf_test.negativeCycle();
+
+    for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
+  }
+  {
+    BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
+      ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
+      ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
+      ::Create bf_test(gr,length);
+
+    LengthMap length_map;
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,Value> dist_map;
+
+    bf_test
+      .lengthMap(length_map)
+      .predMap(pred_map)
+      .distMap(dist_map);
+
+    bf_test.run(s);
+    bf_test.run(s,k);
+
+    bf_test.init();
+    bf_test.addSource(s);
+    bf_test.addSource(s, 1);
+    b = bf_test.processNextRound();
+    b = bf_test.processNextWeakRound();
+
+    bf_test.start();
+    bf_test.checkedStart();
+    bf_test.limitedStart(k);
+
+    l  = bf_test.dist(t);
+    e  = bf_test.predArc(t);
+    s  = bf_test.predNode(t);
+    b  = bf_test.reached(t);
+    pp = bf_test.path(t);
+    pp = bf_test.negativeCycle();
+  }
+}
+
+void checkBellmanFordFunctionCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+  typedef Digraph::Arc Arc;
+  typedef Digraph::Node Node;
+  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
+
+  Digraph g;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+
+  bellmanFord(g,LengthMap()).run(Node());
+  b = bellmanFord(g,LengthMap()).run(Node(),Node());
+  bellmanFord(g,LengthMap())
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,Value>())
+    .run(Node());
+  b=bellmanFord(g,LengthMap())
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,Value>())
+    .path(concepts::Path<Digraph>())
+    .dist(Value())
+    .run(Node(),Node());
+}
+
+
+template <typename Digraph, typename Value>
+void checkBellmanFord() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  typedef typename Digraph::template ArcMap<Value> LengthMap;
+
+  Digraph gr;
+  Node s, t;
+  LengthMap length(gr);
+
+  std::istringstream input(test_lgf);
+  digraphReader(gr, input).
+    arcMap("length", length).
+    node("source", s).
+    node("target", t).
+    run();
+
+  BellmanFord<Digraph, LengthMap>
+    bf(gr, length);
+  bf.run(s);
+  Path<Digraph> p = bf.path(t);
+
+  check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
+  check(p.length() == 3, "path() found a wrong path.");
+  check(checkPath(gr, p), "path() found a wrong path.");
+  check(pathSource(gr, p) == s, "path() found a wrong path.");
+  check(pathTarget(gr, p) == t, "path() found a wrong path.");
+
+  ListPath<Digraph> path;
+  Value dist = 0;
+  bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
+
+  check(reached && dist == -1, "Bellman-Ford found a wrong path.");
+  check(path.length() == 3, "path() found a wrong path.");
+  check(checkPath(gr, path), "path() found a wrong path.");
+  check(pathSource(gr, path) == s, "path() found a wrong path.");
+  check(pathTarget(gr, path) == t, "path() found a wrong path.");
+
+  for(ArcIt e(gr); e!=INVALID; ++e) {
+    Node u=gr.source(e);
+    Node v=gr.target(e);
+    check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
+          "Wrong output. dist(target)-dist(source)-arc_length=" <<
+          bf.dist(v) - bf.dist(u) - length[e]);
+  }
+
+  for(NodeIt v(gr); v!=INVALID; ++v) {
+    if (bf.reached(v)) {
+      check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
+      if (bf.predArc(v)!=INVALID ) {
+        Arc e=bf.predArc(v);
+        Node u=gr.source(e);
+        check(u==bf.predNode(v),"Wrong tree.");
+        check(bf.dist(v) - bf.dist(u) == length[e],
+              "Wrong distance! Difference: " <<
+              bf.dist(v) - bf.dist(u) - length[e]);
+      }
+    }
+  }
+}
+
+void checkBellmanFordNegativeCycle() {
+  DIGRAPH_TYPEDEFS(SmartDigraph);
+
+  SmartDigraph gr;
+  IntArcMap length(gr);
+
+  Node n1 = gr.addNode();
+  Node n2 = gr.addNode();
+  Node n3 = gr.addNode();
+  Node n4 = gr.addNode();
+
+  Arc a1 = gr.addArc(n1, n2);
+  Arc a2 = gr.addArc(n2, n2);
+
+  length[a1] = 2;
+  length[a2] = -1;
+
+  {
+    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
+    bf.run(n1);
+    StaticPath<SmartDigraph> p = bf.negativeCycle();
+    check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
+          "Wrong negative cycle.");
+  }
+
+  length[a2] = 0;
+
+  {
+    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
+    bf.run(n1);
+    check(bf.negativeCycle().empty(),
+          "Negative cycle should not be found.");
+  }
+
+  length[gr.addArc(n1, n3)] = 5;
+  length[gr.addArc(n4, n3)] = 1;
+  length[gr.addArc(n2, n4)] = 2;
+  length[gr.addArc(n3, n2)] = -4;
+
+  {
+    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
+    bf.init();
+    bf.addSource(n1);
+    for (int i = 0; i < 4; ++i) {
+      check(bf.negativeCycle().empty(),
+            "Negative cycle should not be found.");
+      bf.processNextRound();
+    }
+    StaticPath<SmartDigraph> p = bf.negativeCycle();
+    check(p.length() == 3, "Wrong negative cycle.");
+    check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
+          "Wrong negative cycle.");
+  }
+}
+
+int main() {
+  checkBellmanFord<ListDigraph, int>();
+  checkBellmanFord<SmartDigraph, double>();
+  checkBellmanFordNegativeCycle();
+  return 0;
+}
diff --git a/test/bfs_test.cc b/test/bfs_test.cc
new file mode 100644
index 0000000..976fa88
--- /dev/null
+++ b/test/bfs_test.cc
@@ -0,0 +1,239 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/bfs.h>
+#include <lemon/path.h>
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@arcs\n"
+  "     label\n"
+  "0 1  0\n"
+  "1 2  1\n"
+  "2 3  2\n"
+  "3 4  3\n"
+  "0 3  4\n"
+  "0 3  5\n"
+  "5 2  6\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 4\n";
+
+void checkBfsCompile()
+{
+  typedef concepts::Digraph Digraph;
+  typedef Bfs<Digraph> BType;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+
+  Digraph G;
+  Node s, t, n;
+  Arc e;
+  int l, i;
+  ::lemon::ignore_unused_variable_warning(l,i);
+  bool b;
+  BType::DistMap d(G);
+  BType::PredMap p(G);
+  Path<Digraph> pp;
+  concepts::ReadMap<Node,bool> nm;
+
+  {
+    BType bfs_test(G);
+    const BType& const_bfs_test = bfs_test;
+
+    bfs_test.run(s);
+    bfs_test.run(s,t);
+    bfs_test.run();
+
+    bfs_test.init();
+    bfs_test.addSource(s);
+    n = bfs_test.processNextNode();
+    n = bfs_test.processNextNode(t, b);
+    n = bfs_test.processNextNode(nm, n);
+    n = const_bfs_test.nextNode();
+    b = const_bfs_test.emptyQueue();
+    i = const_bfs_test.queueSize();
+
+    bfs_test.start();
+    bfs_test.start(t);
+    bfs_test.start(nm);
+
+    l  = const_bfs_test.dist(t);
+    e  = const_bfs_test.predArc(t);
+    s  = const_bfs_test.predNode(t);
+    b  = const_bfs_test.reached(t);
+    d  = const_bfs_test.distMap();
+    p  = const_bfs_test.predMap();
+    pp = const_bfs_test.path(t);
+  }
+  {
+    BType
+      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
+      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
+      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
+      ::SetStandardProcessedMap
+      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
+      ::Create bfs_test(G);
+
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,int> dist_map;
+    concepts::ReadWriteMap<Node,bool> reached_map;
+    concepts::WriteMap<Node,bool> processed_map;
+
+    bfs_test
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .reachedMap(reached_map)
+      .processedMap(processed_map);
+
+    bfs_test.run(s);
+    bfs_test.run(s,t);
+    bfs_test.run();
+
+    bfs_test.init();
+    bfs_test.addSource(s);
+    n = bfs_test.processNextNode();
+    n = bfs_test.processNextNode(t, b);
+    n = bfs_test.processNextNode(nm, n);
+    n = bfs_test.nextNode();
+    b = bfs_test.emptyQueue();
+    i = bfs_test.queueSize();
+
+    bfs_test.start();
+    bfs_test.start(t);
+    bfs_test.start(nm);
+
+    l  = bfs_test.dist(t);
+    e  = bfs_test.predArc(t);
+    s  = bfs_test.predNode(t);
+    b  = bfs_test.reached(t);
+    pp = bfs_test.path(t);
+  }
+}
+
+void checkBfsFunctionCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+  typedef Digraph::Arc Arc;
+  typedef Digraph::Node Node;
+
+  Digraph g;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+
+  bfs(g).run(Node());
+  b=bfs(g).run(Node(),Node());
+  bfs(g).run();
+  bfs(g)
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,VType>())
+    .reachedMap(concepts::ReadWriteMap<Node,bool>())
+    .processedMap(concepts::WriteMap<Node,bool>())
+    .run(Node());
+  b=bfs(g)
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,VType>())
+    .reachedMap(concepts::ReadWriteMap<Node,bool>())
+    .processedMap(concepts::WriteMap<Node,bool>())
+    .path(concepts::Path<Digraph>())
+    .dist(VType())
+    .run(Node(),Node());
+  bfs(g)
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,VType>())
+    .reachedMap(concepts::ReadWriteMap<Node,bool>())
+    .processedMap(concepts::WriteMap<Node,bool>())
+    .run();
+}
+
+template <class Digraph>
+void checkBfs() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node s, t;
+
+  std::istringstream input(test_lgf);
+  digraphReader(G, input).
+    node("source", s).
+    node("target", t).
+    run();
+
+  Bfs<Digraph> bfs_test(G);
+  bfs_test.run(s);
+
+  check(bfs_test.dist(t)==2,"Bfs found a wrong path.");
+
+  Path<Digraph> p = bfs_test.path(t);
+  check(p.length()==2,"path() found a wrong path.");
+  check(checkPath(G, p),"path() found a wrong path.");
+  check(pathSource(G, p) == s,"path() found a wrong path.");
+  check(pathTarget(G, p) == t,"path() found a wrong path.");
+
+
+  for(ArcIt a(G); a!=INVALID; ++a) {
+    Node u=G.source(a);
+    Node v=G.target(a);
+    check( !bfs_test.reached(u) ||
+           (bfs_test.dist(v) <= bfs_test.dist(u)+1),
+           "Wrong output. " << G.id(u) << "->" << G.id(v));
+  }
+
+  for(NodeIt v(G); v!=INVALID; ++v) {
+    if (bfs_test.reached(v)) {
+      check(v==s || bfs_test.predArc(v)!=INVALID, "Wrong tree.");
+      if (bfs_test.predArc(v)!=INVALID ) {
+        Arc a=bfs_test.predArc(v);
+        Node u=G.source(a);
+        check(u==bfs_test.predNode(v),"Wrong tree.");
+        check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
+              "Wrong distance. Difference: "
+              << std::abs(bfs_test.dist(v) - bfs_test.dist(u) - 1));
+      }
+    }
+  }
+
+  {
+    NullMap<Node,Arc> myPredMap;
+    bfs(G).predMap(myPredMap).run(s);
+  }
+}
+
+int main()
+{
+  checkBfs<ListDigraph>();
+  checkBfs<SmartDigraph>();
+  return 0;
+}
diff --git a/test/bpgraph_test.cc b/test/bpgraph_test.cc
new file mode 100644
index 0000000..45fc5b8
--- /dev/null
+++ b/test/bpgraph_test.cc
@@ -0,0 +1,456 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/bpgraph.h>
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/full_graph.h>
+
+#include "test_tools.h"
+#include "graph_test.h"
+
+using namespace lemon;
+using namespace lemon::concepts;
+
+template <class BpGraph>
+void checkBpGraphBuild() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  checkGraphNodeList(G, 0);
+  checkGraphRedNodeList(G, 0);
+  checkGraphBlueNodeList(G, 0);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  G.reserveNode(3);
+  G.reserveEdge(3);
+
+  RedNode
+    rn1 = G.addRedNode();
+  checkGraphNodeList(G, 1);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 0);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  BlueNode
+    bn1 = G.addBlueNode(),
+    bn2 = G.addBlueNode();
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  Edge e1 = G.addEdge(rn1, bn2);
+  check(G.redNode(e1) == rn1 && G.blueNode(e1) == bn2, "Wrong edge");
+  check(G.u(e1) == rn1 && G.v(e1) == bn2, "Wrong edge");
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 1);
+  checkGraphArcList(G, 2);
+
+  checkGraphIncEdgeArcLists(G, rn1, 1);
+  checkGraphIncEdgeArcLists(G, bn1, 0);
+  checkGraphIncEdgeArcLists(G, bn2, 1);
+
+  checkGraphConEdgeList(G, 1);
+  checkGraphConArcList(G, 2);
+
+  Edge
+    e2 = G.addEdge(bn1, rn1),
+    e3 = G.addEdge(rn1, bn2);
+  ::lemon::ignore_unused_variable_warning(e2,e3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, rn1, 3);
+  checkGraphIncEdgeArcLists(G, bn1, 1);
+  checkGraphIncEdgeArcLists(G, bn2, 2);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkRedNodeIds(G);
+  checkBlueNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+
+  checkGraphNodeMap(G);
+  checkGraphRedNodeMap(G);
+  checkGraphBlueNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+}
+
+template <class BpGraph>
+void checkBpGraphErase() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  RedNode
+    n1 = G.addRedNode(), n4 = G.addRedNode();
+  BlueNode
+    n2 = G.addBlueNode(), n3 = G.addBlueNode();
+  Edge
+    e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3),
+    e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e3,e4);
+
+  // Check edge deletion
+  G.erase(e2);
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+  checkGraphIncEdgeArcLists(G, n4, 2);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+
+  // Check node deletion
+  G.erase(n3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 1);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n4, 1);
+
+  checkGraphConEdgeList(G, 2);
+  checkGraphConArcList(G, 4);
+
+}
+
+template <class BpGraph>
+void checkBpGraphAlter() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  RedNode
+    n1 = G.addRedNode(), n4 = G.addRedNode();
+  BlueNode
+    n2 = G.addBlueNode(), n3 = G.addBlueNode();
+  Edge
+    e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3),
+    e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e3,e4);
+
+  G.changeRed(e2, n4);
+  check(G.redNode(e2) == n4, "Wrong red node");
+  check(G.blueNode(e2) == n3, "Wrong blue node");
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n3, 2);
+  checkGraphIncEdgeArcLists(G, n4, 3);
+
+  checkGraphConEdgeList(G, 4);
+  checkGraphConArcList(G, 8);
+
+  G.changeBlue(e2, n2);
+  check(G.redNode(e2) == n4, "Wrong red node");
+  check(G.blueNode(e2) == n2, "Wrong blue node");
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+  checkGraphIncEdgeArcLists(G, n4, 3);
+
+  checkGraphConEdgeList(G, 4);
+  checkGraphConArcList(G, 8);
+}
+
+
+template <class BpGraph>
+void checkBpGraphSnapshot() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  RedNode
+    n1 = G.addRedNode();
+  BlueNode
+    n2 = G.addBlueNode(),
+    n3 = G.addBlueNode();
+  Edge
+    e1 = G.addEdge(n1, n2),
+    e2 = G.addEdge(n1, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e2);
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  typename BpGraph::Snapshot snapshot(G);
+
+  RedNode n4 = G.addRedNode();
+  G.addEdge(n4, n2);
+  G.addEdge(n4, n3);
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 1);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+
+  checkGraphConEdgeList(G, 2);
+  checkGraphConArcList(G, 4);
+
+  checkNodeIds(G);
+  checkRedNodeIds(G);
+  checkBlueNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+
+  checkGraphNodeMap(G);
+  checkGraphRedNodeMap(G);
+  checkGraphBlueNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+  G.addRedNode();
+  snapshot.save(G);
+
+  G.addEdge(G.addRedNode(), G.addBlueNode());
+
+  snapshot.restore();
+  snapshot.save(G);
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  G.addEdge(G.addRedNode(), G.addBlueNode());
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+}
+
+template <typename BpGraph>
+void checkBpGraphValidity() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+  BpGraph g;
+
+  RedNode
+    n1 = g.addRedNode();
+  BlueNode
+    n2 = g.addBlueNode(),
+    n3 = g.addBlueNode();
+
+  Edge
+    e1 = g.addEdge(n1, n2),
+    e2 = g.addEdge(n1, n3);
+  ::lemon::ignore_unused_variable_warning(e2);
+
+  check(g.valid(n1), "Wrong validity check");
+  check(g.valid(e1), "Wrong validity check");
+  check(g.valid(g.direct(e1, true)), "Wrong validity check");
+
+  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
+}
+
+void checkConcepts() {
+  { // Checking graph components
+    checkConcept<BaseBpGraphComponent, BaseBpGraphComponent >();
+
+    checkConcept<IDableBpGraphComponent<>,
+      IDableBpGraphComponent<> >();
+
+    checkConcept<IterableBpGraphComponent<>,
+      IterableBpGraphComponent<> >();
+
+    checkConcept<AlterableBpGraphComponent<>,
+      AlterableBpGraphComponent<> >();
+
+    checkConcept<MappableBpGraphComponent<>,
+      MappableBpGraphComponent<> >();
+
+    checkConcept<ExtendableBpGraphComponent<>,
+      ExtendableBpGraphComponent<> >();
+
+    checkConcept<ErasableBpGraphComponent<>,
+      ErasableBpGraphComponent<> >();
+
+    checkConcept<ClearableBpGraphComponent<>,
+      ClearableBpGraphComponent<> >();
+
+  }
+  { // Checking skeleton graph
+    checkConcept<BpGraph, BpGraph>();
+  }
+  { // Checking SmartBpGraph
+    checkConcept<BpGraph, SmartBpGraph>();
+    checkConcept<AlterableBpGraphComponent<>, SmartBpGraph>();
+    checkConcept<ExtendableBpGraphComponent<>, SmartBpGraph>();
+    checkConcept<ClearableBpGraphComponent<>, SmartBpGraph>();
+  }
+}
+
+void checkFullBpGraph(int redNum, int blueNum) {
+  typedef FullBpGraph BpGraph;
+  BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G(redNum, blueNum);
+  checkGraphNodeList(G, redNum + blueNum);
+  checkGraphRedNodeList(G, redNum);
+  checkGraphBlueNodeList(G, blueNum);
+  checkGraphEdgeList(G, redNum * blueNum);
+  checkGraphArcList(G, 2 * redNum * blueNum);
+
+  G.resize(redNum, blueNum);
+  checkGraphNodeList(G, redNum + blueNum);
+  checkGraphRedNodeList(G, redNum);
+  checkGraphBlueNodeList(G, blueNum);
+  checkGraphEdgeList(G, redNum * blueNum);
+  checkGraphArcList(G, 2 * redNum * blueNum);
+
+  for (RedNodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, blueNum);
+    checkGraphInArcList(G, n, blueNum);
+    checkGraphIncEdgeList(G, n, blueNum);
+  }
+
+  for (BlueNodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, redNum);
+    checkGraphInArcList(G, n, redNum);
+    checkGraphIncEdgeList(G, n, redNum);
+  }
+
+  checkGraphConArcList(G, 2 * redNum * blueNum);
+  checkGraphConEdgeList(G, redNum * blueNum);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkRedNodeIds(G);
+  checkBlueNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+
+  checkGraphNodeMap(G);
+  checkGraphRedNodeMap(G);
+  checkGraphBlueNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+  for (int i = 0; i < G.redNum(); ++i) {
+    check(G.red(G.redNode(i)), "Wrong node");
+    check(G.index(G.redNode(i)) == i, "Wrong index");
+  }
+
+  for (int i = 0; i < G.blueNum(); ++i) {
+    check(G.blue(G.blueNode(i)), "Wrong node");
+    check(G.index(G.blueNode(i)) == i, "Wrong index");
+  }
+
+  for (NodeIt u(G); u != INVALID; ++u) {
+    for (NodeIt v(G); v != INVALID; ++v) {
+      Edge e = G.edge(u, v);
+      Arc a = G.arc(u, v);
+      if (G.red(u) == G.red(v)) {
+        check(e == INVALID, "Wrong edge lookup");
+        check(a == INVALID, "Wrong arc lookup");
+      } else {
+        check((G.u(e) == u && G.v(e) == v) ||
+              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
+        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
+      }
+    }
+  }
+
+}
+
+void checkGraphs() {
+  { // Checking ListGraph
+    checkBpGraphBuild<ListBpGraph>();
+    checkBpGraphErase<ListBpGraph>();
+    checkBpGraphAlter<ListBpGraph>();
+    checkBpGraphSnapshot<ListBpGraph>();
+    checkBpGraphValidity<ListBpGraph>();
+  }
+  { // Checking SmartGraph
+    checkBpGraphBuild<SmartBpGraph>();
+    checkBpGraphSnapshot<SmartBpGraph>();
+    checkBpGraphValidity<SmartBpGraph>();
+  }
+  { // Checking FullBpGraph
+    checkFullBpGraph(6, 8);
+    checkFullBpGraph(7, 4);
+  }
+}
+
+int main() {
+  checkConcepts();
+  checkGraphs();
+  return 0;
+}
diff --git a/test/circulation_test.cc b/test/circulation_test.cc
new file mode 100644
index 0000000..3b3a4a9
--- /dev/null
+++ b/test/circulation_test.cc
@@ -0,0 +1,169 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/list_graph.h>
+#include <lemon/circulation.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@arcs\n"
+  "     lcap  ucap\n"
+  "0 1  2  10\n"
+  "0 2  2  6\n"
+  "1 3  4  7\n"
+  "1 4  0  5\n"
+  "2 4  1  3\n"
+  "3 5  3  8\n"
+  "4 5  3  7\n"
+  "@attributes\n"
+  "source 0\n"
+  "sink   5\n";
+
+void checkCirculationCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc,VType> CapMap;
+  typedef concepts::ReadMap<Node,VType> SupplyMap;
+  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
+  typedef concepts::WriteMap<Node,bool> BarrierMap;
+
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Node n;
+  Arc a;
+  CapMap lcap, ucap;
+  SupplyMap supply;
+  FlowMap flow;
+  BarrierMap bar;
+  VType v;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(v,b);
+
+  typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
+            ::SetFlowMap<FlowMap>
+            ::SetElevator<Elev>
+            ::SetStandardElevator<LinkedElev>
+            ::Create CirculationType;
+  CirculationType circ_test(g, lcap, ucap, supply);
+  const CirculationType& const_circ_test = circ_test;
+
+  circ_test
+    .lowerMap(lcap)
+    .upperMap(ucap)
+    .supplyMap(supply)
+    .flowMap(flow);
+
+  const CirculationType::Elevator& elev = const_circ_test.elevator();
+  circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
+  CirculationType::Tolerance tol = const_circ_test.tolerance();
+  circ_test.tolerance(tol);
+
+  circ_test.init();
+  circ_test.greedyInit();
+  circ_test.start();
+  circ_test.run();
+
+  v = const_circ_test.flow(a);
+  const FlowMap& fm = const_circ_test.flowMap();
+  b = const_circ_test.barrier(n);
+  const_circ_test.barrierMap(bar);
+
+  ::lemon::ignore_unused_variable_warning(fm);
+}
+
+template <class G, class LM, class UM, class DM>
+void checkCirculation(const G& g, const LM& lm, const UM& um,
+                      const DM& dm, bool find)
+{
+  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
+  bool ret = circ.run();
+  if (find) {
+    check(ret, "A feasible solution should have been found.");
+    check(circ.checkFlow(), "The found flow is corrupt.");
+    check(!circ.checkBarrier(), "A barrier should not have been found.");
+  } else {
+    check(!ret, "A feasible solution should not have been found.");
+    check(circ.checkBarrier(), "The found barrier is corrupt.");
+  }
+}
+
+int main (int, char*[])
+{
+  typedef ListDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph g;
+  IntArcMap lo(g), up(g);
+  IntNodeMap delta(g, 0);
+  Node s, t;
+
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(g,input).
+    arcMap("lcap", lo).
+    arcMap("ucap", up).
+    node("source",s).
+    node("sink",t).
+    run();
+
+  delta[s] = 7; delta[t] = -7;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 13; delta[t] = -13;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 6; delta[t] = -6;
+  checkCirculation(g, lo, up, delta, false);
+
+  delta[s] = 14; delta[t] = -14;
+  checkCirculation(g, lo, up, delta, false);
+
+  delta[s] = 7; delta[t] = -13;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 5; delta[t] = -15;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 10; delta[t] = -11;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 11; delta[t] = -10;
+  checkCirculation(g, lo, up, delta, false);
+
+  return 0;
+}
diff --git a/test/connectivity_test.cc b/test/connectivity_test.cc
new file mode 100644
index 0000000..4ab343e
--- /dev/null
+++ b/test/connectivity_test.cc
@@ -0,0 +1,316 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/connectivity.h>
+#include <lemon/list_graph.h>
+#include <lemon/adaptors.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+
+int main()
+{
+  typedef ListDigraph Digraph;
+  typedef Undirector<Digraph> Graph;
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+
+    check(stronglyConnected(d), "The empty digraph is strongly connected");
+    check(countStronglyConnectedComponents(d) == 0,
+          "The empty digraph has 0 strongly connected component");
+    check(connected(g), "The empty graph is connected");
+    check(countConnectedComponents(g) == 0,
+          "The empty graph has 0 connected component");
+
+    check(biNodeConnected(g), "The empty graph is bi-node-connected");
+    check(countBiNodeConnectedComponents(g) == 0,
+          "The empty graph has 0 bi-node-connected component");
+    check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
+    check(countBiEdgeConnectedComponents(g) == 0,
+          "The empty graph has 0 bi-edge-connected component");
+
+    check(dag(d), "The empty digraph is DAG.");
+    check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
+    check(loopFree(d), "The empty digraph is loop-free.");
+    check(parallelFree(d), "The empty digraph is parallel-free.");
+    check(simpleGraph(d), "The empty digraph is simple.");
+
+    check(acyclic(g), "The empty graph is acyclic.");
+    check(tree(g), "The empty graph is tree.");
+    check(bipartite(g), "The empty graph is bipartite.");
+    check(loopFree(g), "The empty graph is loop-free.");
+    check(parallelFree(g), "The empty graph is parallel-free.");
+    check(simpleGraph(g), "The empty graph is simple.");
+  }
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+    ::lemon::ignore_unused_variable_warning(n);
+
+    check(stronglyConnected(d), "This digraph is strongly connected");
+    check(countStronglyConnectedComponents(d) == 1,
+          "This digraph has 1 strongly connected component");
+    check(connected(g), "This graph is connected");
+    check(countConnectedComponents(g) == 1,
+          "This graph has 1 connected component");
+
+    check(biNodeConnected(g), "This graph is bi-node-connected");
+    check(countBiNodeConnectedComponents(g) == 0,
+          "This graph has 0 bi-node-connected component");
+    check(biEdgeConnected(g), "This graph is bi-edge-connected");
+    check(countBiEdgeConnectedComponents(g) == 1,
+          "This graph has 1 bi-edge-connected component");
+
+    check(dag(d), "This digraph is DAG.");
+    check(checkedTopologicalSort(d, order), "This digraph is DAG.");
+    check(loopFree(d), "This digraph is loop-free.");
+    check(parallelFree(d), "This digraph is parallel-free.");
+    check(simpleGraph(d), "This digraph is simple.");
+
+    check(acyclic(g), "This graph is acyclic.");
+    check(tree(g), "This graph is tree.");
+    check(bipartite(g), "This graph is bipartite.");
+    check(loopFree(g), "This graph is loop-free.");
+    check(parallelFree(g), "This graph is parallel-free.");
+    check(simpleGraph(g), "This graph is simple.");
+  }
+
+  {
+    ListGraph g;
+    ListGraph::NodeMap<bool> map(g);
+
+    ListGraph::Node n1 = g.addNode();
+    ListGraph::Node n2 = g.addNode();
+
+    ListGraph::Edge e1 = g.addEdge(n1, n2);
+    ::lemon::ignore_unused_variable_warning(e1);
+    check(biNodeConnected(g), "Graph is bi-node-connected");
+
+    ListGraph::Node n3 = g.addNode();
+    ::lemon::ignore_unused_variable_warning(n3);
+    check(!biNodeConnected(g), "Graph is not bi-node-connected");
+  }
+
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+
+    d.addArc(n1, n3);
+    d.addArc(n3, n2);
+    d.addArc(n2, n1);
+    d.addArc(n4, n2);
+    d.addArc(n4, n3);
+    d.addArc(n5, n6);
+    d.addArc(n6, n5);
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    check(!connected(g), "This graph is not connected");
+    check(countConnectedComponents(g) == 2,
+          "This graph has 2 connected components");
+
+    check(!dag(d), "This digraph is not DAG.");
+    check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
+    check(loopFree(d), "This digraph is loop-free.");
+    check(parallelFree(d), "This digraph is parallel-free.");
+    check(simpleGraph(d), "This digraph is simple.");
+
+    check(!acyclic(g), "This graph is not acyclic.");
+    check(!tree(g), "This graph is not tree.");
+    check(!bipartite(g), "This graph is not bipartite.");
+    check(loopFree(g), "This graph is loop-free.");
+    check(!parallelFree(g), "This graph is not parallel-free.");
+    check(!simpleGraph(g), "This graph is not simple.");
+
+    d.addArc(n3, n3);
+
+    check(!loopFree(d), "This digraph is not loop-free.");
+    check(!loopFree(g), "This graph is not loop-free.");
+    check(!simpleGraph(d), "This digraph is not simple.");
+
+    d.addArc(n3, n2);
+
+    check(!parallelFree(d), "This digraph is not parallel-free.");
+  }
+
+  {
+    Digraph d;
+    Digraph::ArcMap<bool> cutarcs(d, false);
+    Graph g(d);
+
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+    Digraph::Node n7 = d.addNode();
+    Digraph::Node n8 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n5, n1);
+    d.addArc(n2, n8);
+    d.addArc(n8, n5);
+    d.addArc(n6, n4);
+    d.addArc(n4, n6);
+    d.addArc(n2, n5);
+    d.addArc(n1, n8);
+    d.addArc(n6, n7);
+    d.addArc(n7, n6);
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    Digraph::NodeMap<int> scomp1(d);
+    check(stronglyConnectedComponents(d, scomp1) == 3,
+          "This digraph has 3 strongly connected components");
+    check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
+          scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
+    check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
+          scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
+    check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
+          "Wrong stronglyConnectedComponents()");
+    Digraph::ArcMap<bool> scut1(d, false);
+    check(stronglyConnectedCutArcs(d, scut1) == 0,
+          "This digraph has 0 strongly connected cut arc.");
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
+    }
+
+    check(!connected(g), "This graph is not connected");
+    check(countConnectedComponents(g) == 3,
+          "This graph has 3 connected components");
+    Graph::NodeMap<int> comp(g);
+    check(connectedComponents(g, comp) == 3,
+          "This graph has 3 connected components");
+    check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
+          comp[n3] != comp[n4], "Wrong connectedComponents()");
+    check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
+          comp[n1] == comp[n8], "Wrong connectedComponents()");
+    check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
+          "Wrong connectedComponents()");
+
+    cutarcs[d.addArc(n3, n1)] = true;
+    cutarcs[d.addArc(n3, n5)] = true;
+    cutarcs[d.addArc(n3, n8)] = true;
+    cutarcs[d.addArc(n8, n6)] = true;
+    cutarcs[d.addArc(n8, n7)] = true;
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    Digraph::NodeMap<int> scomp2(d);
+    check(stronglyConnectedComponents(d, scomp2) == 3,
+          "This digraph has 3 strongly connected components");
+    check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
+    check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
+          scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
+    check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
+          "Wrong stronglyConnectedComponents()");
+    Digraph::ArcMap<bool> scut2(d, false);
+    check(stronglyConnectedCutArcs(d, scut2) == 5,
+          "This digraph has 5 strongly connected cut arcs.");
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
+    }
+  }
+
+  {
+    // DAG example for topological sort from the book New Algorithms
+    // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+
+    Digraph::Node belt = d.addNode();
+    Digraph::Node trousers = d.addNode();
+    Digraph::Node necktie = d.addNode();
+    Digraph::Node coat = d.addNode();
+    Digraph::Node socks = d.addNode();
+    Digraph::Node shirt = d.addNode();
+    Digraph::Node shoe = d.addNode();
+    Digraph::Node watch = d.addNode();
+    Digraph::Node pants = d.addNode();
+    ::lemon::ignore_unused_variable_warning(watch);
+
+    d.addArc(socks, shoe);
+    d.addArc(pants, shoe);
+    d.addArc(pants, trousers);
+    d.addArc(trousers, shoe);
+    d.addArc(trousers, belt);
+    d.addArc(belt, coat);
+    d.addArc(shirt, belt);
+    d.addArc(shirt, necktie);
+    d.addArc(necktie, coat);
+
+    check(dag(d), "This digraph is DAG.");
+    topologicalSort(d, order);
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(order[d.source(a)] < order[d.target(a)],
+            "Wrong topologicalSort()");
+    }
+  }
+
+  {
+    ListGraph g;
+    ListGraph::NodeMap<bool> map(g);
+
+    ListGraph::Node n1 = g.addNode();
+    ListGraph::Node n2 = g.addNode();
+    ListGraph::Node n3 = g.addNode();
+    ListGraph::Node n4 = g.addNode();
+    ListGraph::Node n5 = g.addNode();
+    ListGraph::Node n6 = g.addNode();
+    ListGraph::Node n7 = g.addNode();
+
+    g.addEdge(n1, n3);
+    g.addEdge(n1, n4);
+    g.addEdge(n2, n5);
+    g.addEdge(n3, n6);
+    g.addEdge(n4, n6);
+    g.addEdge(n4, n7);
+    g.addEdge(n5, n7);
+
+    check(bipartite(g), "This graph is bipartite");
+    check(bipartitePartitions(g, map), "This graph is bipartite");
+
+    check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
+          "Wrong bipartitePartitions()");
+    check(map[n3] == map[n4] && map[n3] == map[n5],
+          "Wrong bipartitePartitions()");
+  }
+
+  return 0;
+}
diff --git a/test/counter_test.cc b/test/counter_test.cc
new file mode 100644
index 0000000..df31dd4
--- /dev/null
+++ b/test/counter_test.cc
@@ -0,0 +1,118 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/counter.h>
+#include <vector>
+#include <sstream>
+
+#include "test/test_tools.h"
+
+using namespace lemon;
+
+template <typename T>
+void bubbleSort(std::vector<T>& v) {
+  std::stringstream s1, s2, s3;
+  {
+    Counter op("Bubble Sort - Operations: ", s1);
+    Counter::SubCounter as(op, "Assignments: ", s2);
+    Counter::SubCounter co(op, "Comparisons: ", s3);
+    for (int i = v.size()-1; i > 0; --i) {
+      for (int j = 0; j < i; ++j) {
+        if (v[j] > v[j+1]) {
+          T tmp = v[j];
+          v[j] = v[j+1];
+          v[j+1] = tmp;
+          as += 3;
+        }
+        ++co;
+      }
+    }
+  }
+  check(s1.str() == "Bubble Sort - Operations: 102\n", "Wrong counter");
+  check(s2.str() == "Assignments: 57\n", "Wrong subcounter");
+  check(s3.str() == "Comparisons: 45\n", "Wrong subcounter");
+}
+
+template <typename T>
+void insertionSort(std::vector<T>& v) {
+  std::stringstream s1, s2, s3;
+  {
+    Counter op("Insertion Sort - Operations: ", s1);
+    Counter::SubCounter as(op, "Assignments: ", s2);
+    Counter::SubCounter co(op, "Comparisons: ", s3);
+    for (int i = 1; i < int(v.size()); ++i) {
+      T value = v[i];
+      ++as;
+      int j = i;
+      while (j > 0 && v[j-1] > value) {
+        v[j] = v[j-1];
+        --j;
+        ++co; ++as;
+      }
+      v[j] = value;
+      ++as;
+    }
+  }
+  check(s1.str() == "Insertion Sort - Operations: 56\n", "Wrong counter");
+  check(s2.str() == "Assignments: 37\n", "Wrong subcounter");
+  check(s3.str() == "Comparisons: 19\n", "Wrong subcounter");
+}
+
+template <typename MyCounter>
+void counterTest(bool output) {
+  std::stringstream s1, s2, s3;
+  {
+    MyCounter c("Main Counter: ", s1);
+    c++;
+    typename MyCounter::SubCounter d(c, "SubCounter: ", s2);
+    d++;
+    typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ", s3);
+    e++;
+    d+=3;
+    c-=4;
+    e-=2;
+    c.reset(2);
+    c.reset();
+  }
+  if (output) {
+    check(s1.str() == "Main Counter: 3\n", "Wrong Counter");
+    check(s2.str() == "SubCounter: 3\n", "Wrong SubCounter");
+    check(s3.str() == "", "Wrong NoSubCounter");
+  } else {
+    check(s1.str() == "", "Wrong NoCounter");
+    check(s2.str() == "", "Wrong SubCounter");
+    check(s3.str() == "", "Wrong NoSubCounter");
+  }
+}
+
+void init(std::vector<int>& v) {
+  v[0] = 10; v[1] = 60; v[2] = 20; v[3] = 90; v[4] = 100;
+  v[5] = 80; v[6] = 40; v[7] = 30; v[8] = 50; v[9] = 70;
+}
+
+int main()
+{
+  counterTest<Counter>(true);
+  counterTest<NoCounter>(false);
+
+  std::vector<int> x(10);
+  init(x); bubbleSort(x);
+  init(x); insertionSort(x);
+
+  return 0;
+}
diff --git a/test/dfs_test.cc b/test/dfs_test.cc
new file mode 100644
index 0000000..ef5049a
--- /dev/null
+++ b/test/dfs_test.cc
@@ -0,0 +1,238 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/dfs.h>
+#include <lemon/path.h>
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "@arcs\n"
+  "     label\n"
+  "0 1  0\n"
+  "1 2  1\n"
+  "2 3  2\n"
+  "1 4  3\n"
+  "4 2  4\n"
+  "4 5  5\n"
+  "5 0  6\n"
+  "6 3  7\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 5\n"
+  "source1 6\n"
+  "target1 3\n";
+
+
+void checkDfsCompile()
+{
+  typedef concepts::Digraph Digraph;
+  typedef Dfs<Digraph> DType;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+
+  Digraph G;
+  Node s, t;
+  Arc e;
+  int l, i;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(l,i,b);
+
+  DType::DistMap d(G);
+  DType::PredMap p(G);
+  Path<Digraph> pp;
+  concepts::ReadMap<Arc,bool> am;
+
+  {
+    DType dfs_test(G);
+    const DType& const_dfs_test = dfs_test;
+
+    dfs_test.run(s);
+    dfs_test.run(s,t);
+    dfs_test.run();
+
+    dfs_test.init();
+    dfs_test.addSource(s);
+    e = dfs_test.processNextArc();
+    e = const_dfs_test.nextArc();
+    b = const_dfs_test.emptyQueue();
+    i = const_dfs_test.queueSize();
+
+    dfs_test.start();
+    dfs_test.start(t);
+    dfs_test.start(am);
+
+    l  = const_dfs_test.dist(t);
+    e  = const_dfs_test.predArc(t);
+    s  = const_dfs_test.predNode(t);
+    b  = const_dfs_test.reached(t);
+    d  = const_dfs_test.distMap();
+    p  = const_dfs_test.predMap();
+    pp = const_dfs_test.path(t);
+  }
+  {
+    DType
+      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
+      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
+      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
+      ::SetStandardProcessedMap
+      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
+      ::Create dfs_test(G);
+
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,int> dist_map;
+    concepts::ReadWriteMap<Node,bool> reached_map;
+    concepts::WriteMap<Node,bool> processed_map;
+
+    dfs_test
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .reachedMap(reached_map)
+      .processedMap(processed_map);
+
+    dfs_test.run(s);
+    dfs_test.run(s,t);
+    dfs_test.run();
+    dfs_test.init();
+
+    dfs_test.addSource(s);
+    e = dfs_test.processNextArc();
+    e = dfs_test.nextArc();
+    b = dfs_test.emptyQueue();
+    i = dfs_test.queueSize();
+
+    dfs_test.start();
+    dfs_test.start(t);
+    dfs_test.start(am);
+
+    l  = dfs_test.dist(t);
+    e  = dfs_test.predArc(t);
+    s  = dfs_test.predNode(t);
+    b  = dfs_test.reached(t);
+    pp = dfs_test.path(t);
+  }
+}
+
+void checkDfsFunctionCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+  typedef Digraph::Arc Arc;
+  typedef Digraph::Node Node;
+
+  Digraph g;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+
+  dfs(g).run(Node());
+  b=dfs(g).run(Node(),Node());
+  dfs(g).run();
+  dfs(g)
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,VType>())
+    .reachedMap(concepts::ReadWriteMap<Node,bool>())
+    .processedMap(concepts::WriteMap<Node,bool>())
+    .run(Node());
+  b=dfs(g)
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,VType>())
+    .reachedMap(concepts::ReadWriteMap<Node,bool>())
+    .processedMap(concepts::WriteMap<Node,bool>())
+    .path(concepts::Path<Digraph>())
+    .dist(VType())
+    .run(Node(),Node());
+  dfs(g)
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,VType>())
+    .reachedMap(concepts::ReadWriteMap<Node,bool>())
+    .processedMap(concepts::WriteMap<Node,bool>())
+    .run();
+}
+
+template <class Digraph>
+void checkDfs() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node s, t;
+  Node s1, t1;
+
+  std::istringstream input(test_lgf);
+  digraphReader(G, input).
+    node("source", s).
+    node("target", t).
+    node("source1", s1).
+    node("target1", t1).
+    run();
+
+  Dfs<Digraph> dfs_test(G);
+  dfs_test.run(s);
+
+  Path<Digraph> p = dfs_test.path(t);
+  check(p.length() == dfs_test.dist(t),"path() found a wrong path.");
+  check(checkPath(G, p),"path() found a wrong path.");
+  check(pathSource(G, p) == s,"path() found a wrong path.");
+  check(pathTarget(G, p) == t,"path() found a wrong path.");
+
+  for(NodeIt v(G); v!=INVALID; ++v) {
+    if (dfs_test.reached(v)) {
+      check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree.");
+      if (dfs_test.predArc(v)!=INVALID ) {
+        Arc e=dfs_test.predArc(v);
+        Node u=G.source(e);
+        check(u==dfs_test.predNode(v),"Wrong tree.");
+        check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
+              "Wrong distance. (" << dfs_test.dist(u) << "->"
+              << dfs_test.dist(v) << ")");
+      }
+    }
+  }
+
+  {
+  Dfs<Digraph> dfs(G);
+  check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
+  }
+
+  {
+    NullMap<Node,Arc> myPredMap;
+    dfs(G).predMap(myPredMap).run(s);
+  }
+}
+
+int main()
+{
+  checkDfs<ListDigraph>();
+  checkDfs<SmartDigraph>();
+  return 0;
+}
diff --git a/test/digraph_test.cc b/test/digraph_test.cc
new file mode 100644
index 0000000..e3ff545
--- /dev/null
+++ b/test/digraph_test.cc
@@ -0,0 +1,569 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/static_graph.h>
+#include <lemon/full_graph.h>
+
+#include "test_tools.h"
+#include "graph_test.h"
+
+using namespace lemon;
+using namespace lemon::concepts;
+
+template <class Digraph>
+void checkDigraphBuild() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  Digraph G;
+
+  checkGraphNodeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  G.reserveNode(3);
+  G.reserveArc(4);
+
+  Node
+    n1 = G.addNode(),
+    n2 = G.addNode(),
+    n3 = G.addNode();
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 0);
+
+  Arc a1 = G.addArc(n1, n2);
+  check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc");
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 1);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 0);
+  checkGraphOutArcList(G, n3, 0);
+
+  checkGraphInArcList(G, n1, 0);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 0);
+
+  checkGraphConArcList(G, 1);
+
+  Arc a2 = G.addArc(n2, n1),
+      a3 = G.addArc(n2, n3),
+      a4 = G.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 4);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 3);
+  checkGraphOutArcList(G, n3, 0);
+
+  checkGraphInArcList(G, n1, 1);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 2);
+
+  checkGraphConArcList(G, 4);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+}
+
+template <class Digraph>
+void checkDigraphSplit() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
+  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
+      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a4);
+
+  Node n4 = G.split(n2);
+
+  check(G.target(OutArcIt(G, n2)) == n4 &&
+        G.source(InArcIt(G, n4)) == n2,
+        "Wrong split.");
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 5);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 1);
+  checkGraphOutArcList(G, n3, 0);
+  checkGraphOutArcList(G, n4, 3);
+
+  checkGraphInArcList(G, n1, 1);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 2);
+  checkGraphInArcList(G, n4, 1);
+
+  checkGraphConArcList(G, 5);
+}
+
+template <class Digraph>
+void checkDigraphAlter() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node n1 = G.addNode(), n2 = G.addNode(),
+       n3 = G.addNode(), n4 = G.addNode();
+  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
+      a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
+      a5 = G.addArc(n2, n4);
+  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a5);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 5);
+
+  // Check changeSource() and changeTarget()
+  G.changeTarget(a4, n1);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 5);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 1);
+  checkGraphOutArcList(G, n3, 0);
+  checkGraphOutArcList(G, n4, 3);
+
+  checkGraphInArcList(G, n1, 2);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 1);
+  checkGraphInArcList(G, n4, 1);
+
+  checkGraphConArcList(G, 5);
+
+  G.changeSource(a4, n3);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 5);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 1);
+  checkGraphOutArcList(G, n3, 1);
+  checkGraphOutArcList(G, n4, 2);
+
+  checkGraphInArcList(G, n1, 2);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 1);
+  checkGraphInArcList(G, n4, 1);
+
+  checkGraphConArcList(G, 5);
+
+  // Check contract()
+  G.contract(n2, n4, false);
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 5);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 3);
+  checkGraphOutArcList(G, n3, 1);
+
+  checkGraphInArcList(G, n1, 2);
+  checkGraphInArcList(G, n2, 2);
+  checkGraphInArcList(G, n3, 1);
+
+  checkGraphConArcList(G, 5);
+
+  G.contract(n2, n1);
+
+  checkGraphNodeList(G, 2);
+  checkGraphArcList(G, 3);
+
+  checkGraphOutArcList(G, n2, 2);
+  checkGraphOutArcList(G, n3, 1);
+
+  checkGraphInArcList(G, n2, 2);
+  checkGraphInArcList(G, n3, 1);
+
+  checkGraphConArcList(G, 3);
+}
+
+template <class Digraph>
+void checkDigraphErase() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node n1 = G.addNode(), n2 = G.addNode(),
+       n3 = G.addNode(), n4 = G.addNode();
+  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
+      a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
+      a5 = G.addArc(n2, n4);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4,a5);
+
+  // Check arc deletion
+  G.erase(a1);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 4);
+
+  checkGraphOutArcList(G, n1, 0);
+  checkGraphOutArcList(G, n2, 1);
+  checkGraphOutArcList(G, n3, 1);
+  checkGraphOutArcList(G, n4, 2);
+
+  checkGraphInArcList(G, n1, 2);
+  checkGraphInArcList(G, n2, 0);
+  checkGraphInArcList(G, n3, 1);
+  checkGraphInArcList(G, n4, 1);
+
+  checkGraphConArcList(G, 4);
+
+  // Check node deletion
+  G.erase(n4);
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 1);
+
+  checkGraphOutArcList(G, n1, 0);
+  checkGraphOutArcList(G, n2, 0);
+  checkGraphOutArcList(G, n3, 1);
+  checkGraphOutArcList(G, n4, 0);
+
+  checkGraphInArcList(G, n1, 1);
+  checkGraphInArcList(G, n2, 0);
+  checkGraphInArcList(G, n3, 0);
+  checkGraphInArcList(G, n4, 0);
+
+  checkGraphConArcList(G, 1);
+}
+
+
+template <class Digraph>
+void checkDigraphSnapshot() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
+  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
+      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a4);
+
+  typename Digraph::Snapshot snapshot(G);
+
+  Node n = G.addNode();
+  G.addArc(n3, n);
+  G.addArc(n, n3);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 6);
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 4);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 3);
+  checkGraphOutArcList(G, n3, 0);
+
+  checkGraphInArcList(G, n1, 1);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 2);
+
+  checkGraphConArcList(G, 4);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+
+  G.addNode();
+  snapshot.save(G);
+
+  G.addArc(G.addNode(), G.addNode());
+
+  snapshot.restore();
+  snapshot.save(G);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 4);
+
+  G.addArc(G.addNode(), G.addNode());
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 4);
+}
+
+void checkConcepts() {
+  { // Checking digraph components
+    checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
+
+    checkConcept<IDableDigraphComponent<>,
+      IDableDigraphComponent<> >();
+
+    checkConcept<IterableDigraphComponent<>,
+      IterableDigraphComponent<> >();
+
+    checkConcept<MappableDigraphComponent<>,
+      MappableDigraphComponent<> >();
+  }
+  { // Checking skeleton digraph
+    checkConcept<Digraph, Digraph>();
+  }
+  { // Checking ListDigraph
+    checkConcept<Digraph, ListDigraph>();
+    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
+    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
+    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
+    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
+  }
+  { // Checking SmartDigraph
+    checkConcept<Digraph, SmartDigraph>();
+    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
+    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
+    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
+  }
+  { // Checking StaticDigraph
+    checkConcept<Digraph, StaticDigraph>();
+    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
+  }
+  { // Checking FullDigraph
+    checkConcept<Digraph, FullDigraph>();
+  }
+}
+
+template <typename Digraph>
+void checkDigraphValidity() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  Digraph g;
+
+  Node
+    n1 = g.addNode(),
+    n2 = g.addNode(),
+    n3 = g.addNode();
+
+  Arc
+    e1 = g.addArc(n1, n2),
+    e2 = g.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2);
+
+  check(g.valid(n1), "Wrong validity check");
+  check(g.valid(e1), "Wrong validity check");
+
+  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
+}
+
+template <typename Digraph>
+void checkDigraphValidityErase() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  Digraph g;
+
+  Node
+    n1 = g.addNode(),
+    n2 = g.addNode(),
+    n3 = g.addNode();
+
+  Arc
+    e1 = g.addArc(n1, n2),
+    e2 = g.addArc(n2, n3);
+
+  check(g.valid(n1), "Wrong validity check");
+  check(g.valid(e1), "Wrong validity check");
+
+  g.erase(n1);
+
+  check(!g.valid(n1), "Wrong validity check");
+  check(g.valid(n2), "Wrong validity check");
+  check(g.valid(n3), "Wrong validity check");
+  check(!g.valid(e1), "Wrong validity check");
+  check(g.valid(e2), "Wrong validity check");
+
+  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
+}
+
+void checkStaticDigraph() {
+  SmartDigraph g;
+  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
+  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
+
+  StaticDigraph G;
+
+  checkGraphNodeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  G.build(g, nref, aref);
+
+  checkGraphNodeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  SmartDigraph::Node
+    n1 = g.addNode(),
+    n2 = g.addNode(),
+    n3 = g.addNode();
+
+  G.build(g, nref, aref);
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 0);
+
+  SmartDigraph::Arc a1 = g.addArc(n1, n2);
+
+  G.build(g, nref, aref);
+
+  check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
+        "Wrong arc or wrong references");
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 1);
+
+  checkGraphOutArcList(G, nref[n1], 1);
+  checkGraphOutArcList(G, nref[n2], 0);
+  checkGraphOutArcList(G, nref[n3], 0);
+
+  checkGraphInArcList(G, nref[n1], 0);
+  checkGraphInArcList(G, nref[n2], 1);
+  checkGraphInArcList(G, nref[n3], 0);
+
+  checkGraphConArcList(G, 1);
+
+  SmartDigraph::Arc
+    a2 = g.addArc(n2, n1),
+    a3 = g.addArc(n2, n3),
+    a4 = g.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
+
+  digraphCopy(g, G).nodeRef(nref).run();
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 4);
+
+  checkGraphOutArcList(G, nref[n1], 1);
+  checkGraphOutArcList(G, nref[n2], 3);
+  checkGraphOutArcList(G, nref[n3], 0);
+
+  checkGraphInArcList(G, nref[n1], 1);
+  checkGraphInArcList(G, nref[n2], 1);
+  checkGraphInArcList(G, nref[n3], 2);
+
+  checkGraphConArcList(G, 4);
+
+  std::vector<std::pair<int,int> > arcs;
+  arcs.push_back(std::make_pair(0,1));
+  arcs.push_back(std::make_pair(0,2));
+  arcs.push_back(std::make_pair(1,3));
+  arcs.push_back(std::make_pair(1,2));
+  arcs.push_back(std::make_pair(3,0));
+  arcs.push_back(std::make_pair(3,3));
+  arcs.push_back(std::make_pair(4,2));
+  arcs.push_back(std::make_pair(4,3));
+  arcs.push_back(std::make_pair(4,1));
+
+  G.build(6, arcs.begin(), arcs.end());
+
+  checkGraphNodeList(G, 6);
+  checkGraphArcList(G, 9);
+
+  checkGraphOutArcList(G, G.node(0), 2);
+  checkGraphOutArcList(G, G.node(1), 2);
+  checkGraphOutArcList(G, G.node(2), 0);
+  checkGraphOutArcList(G, G.node(3), 2);
+  checkGraphOutArcList(G, G.node(4), 3);
+  checkGraphOutArcList(G, G.node(5), 0);
+
+  checkGraphInArcList(G, G.node(0), 1);
+  checkGraphInArcList(G, G.node(1), 2);
+  checkGraphInArcList(G, G.node(2), 3);
+  checkGraphInArcList(G, G.node(3), 3);
+  checkGraphInArcList(G, G.node(4), 0);
+  checkGraphInArcList(G, G.node(5), 0);
+
+  checkGraphConArcList(G, 9);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+
+  int n = G.nodeNum();
+  int m = G.arcNum();
+  check(G.index(G.node(n-1)) == n-1, "Wrong index.");
+  check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
+}
+
+void checkFullDigraph(int num) {
+  typedef FullDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G(num);
+  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
+
+  G.resize(num);
+  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
+
+  checkGraphNodeList(G, num);
+  checkGraphArcList(G, num * num);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, num);
+    checkGraphInArcList(G, n, num);
+  }
+
+  checkGraphConArcList(G, num * num);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+
+  for (int i = 0; i < G.nodeNum(); ++i) {
+    check(G.index(G(i)) == i, "Wrong index");
+  }
+
+  for (NodeIt s(G); s != INVALID; ++s) {
+    for (NodeIt t(G); t != INVALID; ++t) {
+      Arc a = G.arc(s, t);
+      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
+    }
+  }
+}
+
+void checkDigraphs() {
+  { // Checking ListDigraph
+    checkDigraphBuild<ListDigraph>();
+    checkDigraphSplit<ListDigraph>();
+    checkDigraphAlter<ListDigraph>();
+    checkDigraphErase<ListDigraph>();
+    checkDigraphSnapshot<ListDigraph>();
+    checkDigraphValidityErase<ListDigraph>();
+  }
+  { // Checking SmartDigraph
+    checkDigraphBuild<SmartDigraph>();
+    checkDigraphSplit<SmartDigraph>();
+    checkDigraphSnapshot<SmartDigraph>();
+    checkDigraphValidity<SmartDigraph>();
+  }
+  { // Checking StaticDigraph
+    checkStaticDigraph();
+  }
+  { // Checking FullDigraph
+    checkFullDigraph(8);
+  }
+}
+
+int main() {
+  checkDigraphs();
+  checkConcepts();
+  return 0;
+}
diff --git a/test/dijkstra_test.cc b/test/dijkstra_test.cc
new file mode 100644
index 0000000..20cc76b
--- /dev/null
+++ b/test/dijkstra_test.cc
@@ -0,0 +1,246 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/dijkstra.h>
+#include <lemon/path.h>
+#include <lemon/bin_heap.h>
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "@arcs\n"
+  "     label length\n"
+  "0 1  0     1\n"
+  "1 2  1     1\n"
+  "2 3  2     1\n"
+  "0 3  4     5\n"
+  "0 3  5     10\n"
+  "0 3  6     7\n"
+  "4 2  7     1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 3\n";
+
+void checkDijkstraCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
+  typedef Dijkstra<Digraph, LengthMap> DType;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+
+  Digraph G;
+  Node s, t, n;
+  Arc e;
+  VType l;
+  int i;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(l,i,b);
+
+  DType::DistMap d(G);
+  DType::PredMap p(G);
+  LengthMap length;
+  Path<Digraph> pp;
+  concepts::ReadMap<Node,bool> nm;
+
+  {
+    DType dijkstra_test(G,length);
+    const DType& const_dijkstra_test = dijkstra_test;
+
+    dijkstra_test.run(s);
+    dijkstra_test.run(s,t);
+
+    dijkstra_test.init();
+    dijkstra_test.addSource(s);
+    dijkstra_test.addSource(s, 1);
+    n = dijkstra_test.processNextNode();
+    n = const_dijkstra_test.nextNode();
+    b = const_dijkstra_test.emptyQueue();
+    i = const_dijkstra_test.queueSize();
+
+    dijkstra_test.start();
+    dijkstra_test.start(t);
+    dijkstra_test.start(nm);
+
+    l  = const_dijkstra_test.dist(t);
+    e  = const_dijkstra_test.predArc(t);
+    s  = const_dijkstra_test.predNode(t);
+    b  = const_dijkstra_test.reached(t);
+    b  = const_dijkstra_test.processed(t);
+    d  = const_dijkstra_test.distMap();
+    p  = const_dijkstra_test.predMap();
+    pp = const_dijkstra_test.path(t);
+    l  = const_dijkstra_test.currentDist(t);
+  }
+  {
+    DType
+      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
+      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
+      ::SetStandardProcessedMap
+      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
+      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
+      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
+      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
+      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
+                concepts::ReadWriteMap<Node,int> >
+      ::Create dijkstra_test(G,length);
+
+    LengthMap length_map;
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,VType> dist_map;
+    concepts::WriteMap<Node,bool> processed_map;
+    concepts::ReadWriteMap<Node,int> heap_cross_ref;
+    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
+
+    dijkstra_test
+      .lengthMap(length_map)
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .processedMap(processed_map)
+      .heap(heap, heap_cross_ref);
+
+    dijkstra_test.run(s);
+    dijkstra_test.run(s,t);
+
+    dijkstra_test.addSource(s);
+    dijkstra_test.addSource(s, 1);
+    n = dijkstra_test.processNextNode();
+    n = dijkstra_test.nextNode();
+    b = dijkstra_test.emptyQueue();
+    i = dijkstra_test.queueSize();
+
+    dijkstra_test.start();
+    dijkstra_test.start(t);
+    dijkstra_test.start(nm);
+
+    l  = dijkstra_test.dist(t);
+    e  = dijkstra_test.predArc(t);
+    s  = dijkstra_test.predNode(t);
+    b  = dijkstra_test.reached(t);
+    b  = dijkstra_test.processed(t);
+    pp = dijkstra_test.path(t);
+    l  = dijkstra_test.currentDist(t);
+  }
+
+}
+
+void checkDijkstraFunctionCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+  typedef Digraph::Arc Arc;
+  typedef Digraph::Node Node;
+  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
+
+  Digraph g;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+
+  dijkstra(g,LengthMap()).run(Node());
+  b=dijkstra(g,LengthMap()).run(Node(),Node());
+  dijkstra(g,LengthMap())
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,VType>())
+    .processedMap(concepts::WriteMap<Node,bool>())
+    .run(Node());
+  b=dijkstra(g,LengthMap())
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,VType>())
+    .processedMap(concepts::WriteMap<Node,bool>())
+    .path(concepts::Path<Digraph>())
+    .dist(VType())
+    .run(Node(),Node());
+}
+
+template <class Digraph>
+void checkDijkstra() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  typedef typename Digraph::template ArcMap<int> LengthMap;
+
+  Digraph G;
+  Node s, t;
+  LengthMap length(G);
+
+  std::istringstream input(test_lgf);
+  digraphReader(G, input).
+    arcMap("length", length).
+    node("source", s).
+    node("target", t).
+    run();
+
+  Dijkstra<Digraph, LengthMap>
+        dijkstra_test(G, length);
+  dijkstra_test.run(s);
+
+  check(dijkstra_test.dist(t)==3,"Dijkstra found a wrong path.");
+
+  Path<Digraph> p = dijkstra_test.path(t);
+  check(p.length()==3,"path() found a wrong path.");
+  check(checkPath(G, p),"path() found a wrong path.");
+  check(pathSource(G, p) == s,"path() found a wrong path.");
+  check(pathTarget(G, p) == t,"path() found a wrong path.");
+
+  for(ArcIt e(G); e!=INVALID; ++e) {
+    Node u=G.source(e);
+    Node v=G.target(e);
+    check( !dijkstra_test.reached(u) ||
+           (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= length[e]),
+           "Wrong output. dist(target)-dist(source)-arc_length=" <<
+           dijkstra_test.dist(v) - dijkstra_test.dist(u) - length[e]);
+  }
+
+  for(NodeIt v(G); v!=INVALID; ++v) {
+    if (dijkstra_test.reached(v)) {
+      check(v==s || dijkstra_test.predArc(v)!=INVALID, "Wrong tree.");
+      if (dijkstra_test.predArc(v)!=INVALID ) {
+        Arc e=dijkstra_test.predArc(v);
+        Node u=G.source(e);
+        check(u==dijkstra_test.predNode(v),"Wrong tree.");
+        check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == length[e],
+              "Wrong distance! Difference: " <<
+              std::abs(dijkstra_test.dist(v)-dijkstra_test.dist(u)-length[e]));
+      }
+    }
+  }
+
+  {
+    NullMap<Node,Arc> myPredMap;
+    dijkstra(G,length).predMap(myPredMap).run(s);
+  }
+}
+
+int main() {
+  checkDijkstra<ListDigraph>();
+  checkDijkstra<SmartDigraph>();
+  return 0;
+}
diff --git a/test/dim_test.cc b/test/dim_test.cc
new file mode 100644
index 0000000..0b2b925
--- /dev/null
+++ b/test/dim_test.cc
@@ -0,0 +1,87 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/dim2.h>
+#include <iostream>
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+int main()
+{
+  typedef dim2::Point<int> Point;
+
+  Point p;
+  check(p.size()==2, "Wrong dim2::Point initialization.");
+
+  Point a(1,2);
+  Point b(3,4);
+  check(a[0]==1 && a[1]==2, "Wrong dim2::Point initialization.");
+
+  p = a+b;
+  check(p.x==4 && p.y==6, "Wrong dim2::Point addition.");
+
+  p = a-b;
+  check(p.x==-2 && p.y==-2, "Wrong dim2::Point subtraction.");
+
+  check(a.normSquare()==5,"Wrong dim2::Point norm calculation.");
+  check(a*b==11, "Wrong dim2::Point scalar product.");
+
+  int l=2;
+  p = a*l;
+  check(p.x==2 && p.y==4, "Wrong dim2::Point multiplication by a scalar.");
+
+  p = b/l;
+  check(p.x==1 && p.y==2, "Wrong dim2::Point division by a scalar.");
+
+  typedef dim2::Box<int> Box;
+  Box box1;
+  check(box1.empty(), "Wrong empty() in dim2::Box.");
+
+  box1.add(a);
+  check(!box1.empty(), "Wrong empty() in dim2::Box.");
+  box1.add(b);
+
+  check(box1.left()==1 && box1.bottom()==2 &&
+        box1.right()==3 && box1.top()==4,
+        "Wrong addition of points to dim2::Box.");
+
+  check(box1.inside(Point(2,3)), "Wrong inside() in dim2::Box.");
+  check(box1.inside(Point(1,3)), "Wrong inside() in dim2::Box.");
+  check(!box1.inside(Point(0,3)), "Wrong inside() in dim2::Box.");
+
+  Box box2(Point(2,2));
+  check(!box2.empty(), "Wrong empty() in dim2::Box.");
+
+  box2.bottomLeft(Point(2,0));
+  box2.topRight(Point(5,3));
+  Box box3 = box1 & box2;
+  check(!box3.empty() &&
+        box3.left()==2 && box3.bottom()==2 &&
+        box3.right()==3 && box3.top()==3,
+        "Wrong intersection of two dim2::Box objects.");
+
+  box1.add(box2);
+  check(!box1.empty() &&
+        box1.left()==1 && box1.bottom()==0 &&
+        box1.right()==5 && box1.top()==4,
+        "Wrong addition of two dim2::Box objects.");
+
+  return 0;
+}
diff --git a/test/edge_set_test.cc b/test/edge_set_test.cc
new file mode 100644
index 0000000..dbe74a9
--- /dev/null
+++ b/test/edge_set_test.cc
@@ -0,0 +1,396 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <vector>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concept_check.h>
+
+#include <lemon/list_graph.h>
+
+#include <lemon/edge_set.h>
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+using namespace lemon;
+
+void checkSmartArcSet() {
+  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef SmartArcSet<Digraph> ArcSet;
+
+  Digraph digraph;
+  Digraph::Node
+    n1 = digraph.addNode(),
+    n2 = digraph.addNode();
+
+  Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(ga1);
+
+  ArcSet arc_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ::lemon::ignore_unused_variable_warning(ga2);
+
+  checkGraphNodeList(arc_set, 2);
+  checkGraphArcList(arc_set, 0);
+
+  Digraph::Node
+    n3 = digraph.addNode();
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 0);
+
+  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
+  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 1);
+
+  checkGraphOutArcList(arc_set, n1, 1);
+  checkGraphOutArcList(arc_set, n2, 0);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n1, 0);
+  checkGraphInArcList(arc_set, n2, 1);
+  checkGraphInArcList(arc_set, n3, 0);
+
+  checkGraphConArcList(arc_set, 1);
+
+  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
+    a3 = arc_set.addArc(n2, n3),
+    a4 = arc_set.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
+
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 4);
+
+  checkGraphOutArcList(arc_set, n1, 1);
+  checkGraphOutArcList(arc_set, n2, 3);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n1, 1);
+  checkGraphInArcList(arc_set, n2, 1);
+  checkGraphInArcList(arc_set, n3, 2);
+
+  checkGraphConArcList(arc_set, 4);
+
+  checkNodeIds(arc_set);
+  checkArcIds(arc_set);
+  checkGraphNodeMap(arc_set);
+  checkGraphArcMap(arc_set);
+
+  check(arc_set.valid(), "Wrong validity");
+  digraph.erase(n1);
+  check(!arc_set.valid(), "Wrong validity");
+}
+
+void checkListArcSet() {
+  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef ListArcSet<Digraph> ArcSet;
+
+  Digraph digraph;
+  Digraph::Node
+    n1 = digraph.addNode(),
+    n2 = digraph.addNode();
+
+  Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(ga1);
+
+  ArcSet arc_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ::lemon::ignore_unused_variable_warning(ga2);
+
+  checkGraphNodeList(arc_set, 2);
+  checkGraphArcList(arc_set, 0);
+
+  Digraph::Node
+    n3 = digraph.addNode();
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 0);
+
+  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
+  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 1);
+
+  checkGraphOutArcList(arc_set, n1, 1);
+  checkGraphOutArcList(arc_set, n2, 0);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n1, 0);
+  checkGraphInArcList(arc_set, n2, 1);
+  checkGraphInArcList(arc_set, n3, 0);
+
+  checkGraphConArcList(arc_set, 1);
+
+  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
+    a3 = arc_set.addArc(n2, n3),
+    a4 = arc_set.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
+
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 4);
+
+  checkGraphOutArcList(arc_set, n1, 1);
+  checkGraphOutArcList(arc_set, n2, 3);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n1, 1);
+  checkGraphInArcList(arc_set, n2, 1);
+  checkGraphInArcList(arc_set, n3, 2);
+
+  checkGraphConArcList(arc_set, 4);
+
+  checkNodeIds(arc_set);
+  checkArcIds(arc_set);
+  checkGraphNodeMap(arc_set);
+  checkGraphArcMap(arc_set);
+
+  digraph.erase(n1);
+
+  checkGraphNodeList(arc_set, 2);
+  checkGraphArcList(arc_set, 2);
+
+  checkGraphOutArcList(arc_set, n2, 2);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n2, 0);
+  checkGraphInArcList(arc_set, n3, 2);
+
+  checkNodeIds(arc_set);
+  checkArcIds(arc_set);
+  checkGraphNodeMap(arc_set);
+  checkGraphArcMap(arc_set);
+
+  checkGraphConArcList(arc_set, 2);
+}
+
+void checkSmartEdgeSet() {
+  checkConcept<concepts::Digraph, SmartEdgeSet<ListDigraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef SmartEdgeSet<Digraph> EdgeSet;
+
+  Digraph digraph;
+  Digraph::Node
+    n1 = digraph.addNode(),
+    n2 = digraph.addNode();
+
+  Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(ga1);
+
+  EdgeSet edge_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ::lemon::ignore_unused_variable_warning(ga2);
+
+  checkGraphNodeList(edge_set, 2);
+  checkGraphArcList(edge_set, 0);
+  checkGraphEdgeList(edge_set, 0);
+
+  Digraph::Node
+    n3 = digraph.addNode();
+  checkGraphNodeList(edge_set, 3);
+  checkGraphArcList(edge_set, 0);
+  checkGraphEdgeList(edge_set, 0);
+
+  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
+  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
+        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
+  checkGraphNodeList(edge_set, 3);
+  checkGraphArcList(edge_set, 2);
+  checkGraphEdgeList(edge_set, 1);
+
+  checkGraphOutArcList(edge_set, n1, 1);
+  checkGraphOutArcList(edge_set, n2, 1);
+  checkGraphOutArcList(edge_set, n3, 0);
+
+  checkGraphInArcList(edge_set, n1, 1);
+  checkGraphInArcList(edge_set, n2, 1);
+  checkGraphInArcList(edge_set, n3, 0);
+
+  checkGraphIncEdgeList(edge_set, n1, 1);
+  checkGraphIncEdgeList(edge_set, n2, 1);
+  checkGraphIncEdgeList(edge_set, n3, 0);
+
+  checkGraphConEdgeList(edge_set, 1);
+  checkGraphConArcList(edge_set, 2);
+
+  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
+    e3 = edge_set.addEdge(n2, n3),
+    e4 = edge_set.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2,e3,e4);
+
+  checkGraphNodeList(edge_set, 3);
+  checkGraphEdgeList(edge_set, 4);
+
+  checkGraphOutArcList(edge_set, n1, 2);
+  checkGraphOutArcList(edge_set, n2, 4);
+  checkGraphOutArcList(edge_set, n3, 2);
+
+  checkGraphInArcList(edge_set, n1, 2);
+  checkGraphInArcList(edge_set, n2, 4);
+  checkGraphInArcList(edge_set, n3, 2);
+
+  checkGraphIncEdgeList(edge_set, n1, 2);
+  checkGraphIncEdgeList(edge_set, n2, 4);
+  checkGraphIncEdgeList(edge_set, n3, 2);
+
+  checkGraphConEdgeList(edge_set, 4);
+  checkGraphConArcList(edge_set, 8);
+
+  checkArcDirections(edge_set);
+
+  checkNodeIds(edge_set);
+  checkArcIds(edge_set);
+  checkEdgeIds(edge_set);
+  checkGraphNodeMap(edge_set);
+  checkGraphArcMap(edge_set);
+  checkGraphEdgeMap(edge_set);
+
+  check(edge_set.valid(), "Wrong validity");
+  digraph.erase(n1);
+  check(!edge_set.valid(), "Wrong validity");
+}
+
+void checkListEdgeSet() {
+  checkConcept<concepts::Digraph, ListEdgeSet<ListDigraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef ListEdgeSet<Digraph> EdgeSet;
+
+  Digraph digraph;
+  Digraph::Node
+    n1 = digraph.addNode(),
+    n2 = digraph.addNode();
+
+  Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(ga1);
+
+  EdgeSet edge_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ::lemon::ignore_unused_variable_warning(ga2);
+
+  checkGraphNodeList(edge_set, 2);
+  checkGraphArcList(edge_set, 0);
+  checkGraphEdgeList(edge_set, 0);
+
+  Digraph::Node
+    n3 = digraph.addNode();
+  checkGraphNodeList(edge_set, 3);
+  checkGraphArcList(edge_set, 0);
+  checkGraphEdgeList(edge_set, 0);
+
+  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
+  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
+        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
+  checkGraphNodeList(edge_set, 3);
+  checkGraphArcList(edge_set, 2);
+  checkGraphEdgeList(edge_set, 1);
+
+  checkGraphOutArcList(edge_set, n1, 1);
+  checkGraphOutArcList(edge_set, n2, 1);
+  checkGraphOutArcList(edge_set, n3, 0);
+
+  checkGraphInArcList(edge_set, n1, 1);
+  checkGraphInArcList(edge_set, n2, 1);
+  checkGraphInArcList(edge_set, n3, 0);
+
+  checkGraphIncEdgeList(edge_set, n1, 1);
+  checkGraphIncEdgeList(edge_set, n2, 1);
+  checkGraphIncEdgeList(edge_set, n3, 0);
+
+  checkGraphConEdgeList(edge_set, 1);
+  checkGraphConArcList(edge_set, 2);
+
+  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
+    e3 = edge_set.addEdge(n2, n3),
+    e4 = edge_set.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2,e3,e4);
+
+  checkGraphNodeList(edge_set, 3);
+  checkGraphEdgeList(edge_set, 4);
+
+  checkGraphOutArcList(edge_set, n1, 2);
+  checkGraphOutArcList(edge_set, n2, 4);
+  checkGraphOutArcList(edge_set, n3, 2);
+
+  checkGraphInArcList(edge_set, n1, 2);
+  checkGraphInArcList(edge_set, n2, 4);
+  checkGraphInArcList(edge_set, n3, 2);
+
+  checkGraphIncEdgeList(edge_set, n1, 2);
+  checkGraphIncEdgeList(edge_set, n2, 4);
+  checkGraphIncEdgeList(edge_set, n3, 2);
+
+  checkGraphConEdgeList(edge_set, 4);
+  checkGraphConArcList(edge_set, 8);
+
+  checkArcDirections(edge_set);
+
+  checkNodeIds(edge_set);
+  checkArcIds(edge_set);
+  checkEdgeIds(edge_set);
+  checkGraphNodeMap(edge_set);
+  checkGraphArcMap(edge_set);
+  checkGraphEdgeMap(edge_set);
+
+  digraph.erase(n1);
+
+  checkGraphNodeList(edge_set, 2);
+  checkGraphArcList(edge_set, 4);
+  checkGraphEdgeList(edge_set, 2);
+
+  checkGraphOutArcList(edge_set, n2, 2);
+  checkGraphOutArcList(edge_set, n3, 2);
+
+  checkGraphInArcList(edge_set, n2, 2);
+  checkGraphInArcList(edge_set, n3, 2);
+
+  checkGraphIncEdgeList(edge_set, n2, 2);
+  checkGraphIncEdgeList(edge_set, n3, 2);
+
+  checkNodeIds(edge_set);
+  checkArcIds(edge_set);
+  checkEdgeIds(edge_set);
+  checkGraphNodeMap(edge_set);
+  checkGraphArcMap(edge_set);
+  checkGraphEdgeMap(edge_set);
+
+  checkGraphConEdgeList(edge_set, 2);
+  checkGraphConArcList(edge_set, 4);
+
+}
+
+
+int main() {
+
+  checkSmartArcSet();
+  checkListArcSet();
+  checkSmartEdgeSet();
+  checkListEdgeSet();
+
+  return 0;
+}
diff --git a/test/error_test.cc b/test/error_test.cc
new file mode 100644
index 0000000..1527519
--- /dev/null
+++ b/test/error_test.cc
@@ -0,0 +1,90 @@
+/* -*- 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/error.h>
+#include "test_tools.h"
+
+using namespace lemon;
+
+#ifdef LEMON_ENABLE_ASSERTS
+#undef LEMON_ENABLE_ASSERTS
+#endif
+
+#ifdef LEMON_DISABLE_ASSERTS
+#undef LEMON_DISABLE_ASSERTS
+#endif
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+//checking disabled asserts
+#define LEMON_DISABLE_ASSERTS
+#include <lemon/assert.h>
+
+void no_assertion_text_disable() {
+  LEMON_ASSERT(true, "This is a fault message");
+}
+
+void assertion_text_disable() {
+  LEMON_ASSERT(false, "This is a fault message");
+}
+
+void check_assertion_disable() {
+  no_assertion_text_disable();
+  assertion_text_disable();
+}
+#undef LEMON_DISABLE_ASSERTS
+
+//checking custom assert handler
+#define LEMON_ASSERT_CUSTOM
+
+static int cnt = 0;
+void my_assert_handler(const char*, int, const char*,
+                       const char*, const char*) {
+  ++cnt;
+}
+
+#define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
+#include <lemon/assert.h>
+
+void no_assertion_text_custom() {
+  LEMON_ASSERT(true, "This is a fault message");
+}
+
+void assertion_text_custom() {
+  LEMON_ASSERT(false, "This is a fault message");
+}
+
+void check_assertion_custom() {
+  no_assertion_text_custom();
+  assertion_text_custom();
+  check(cnt == 1, "The custom assert handler does not work");
+}
+
+#undef LEMON_ASSERT_CUSTOM
+
+
+int main() {
+  check_assertion_disable();
+  check_assertion_custom();
+
+  return 0;
+}
diff --git a/test/euler_test.cc b/test/euler_test.cc
new file mode 100644
index 0000000..11a39e4
--- /dev/null
+++ b/test/euler_test.cc
@@ -0,0 +1,225 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/euler.h>
+#include <lemon/list_graph.h>
+#include <lemon/adaptors.h>
+#include "test_tools.h"
+
+using namespace lemon;
+
+template <typename Digraph>
+void checkDiEulerIt(const Digraph& g,
+                    const typename Digraph::Node& start = INVALID)
+{
+  typename Digraph::template ArcMap<int> visitationNumber(g, 0);
+
+  DiEulerIt<Digraph> e(g, start);
+  if (e == INVALID) return;
+  typename Digraph::Node firstNode = g.source(e);
+  typename Digraph::Node lastNode = g.target(e);
+  if (start != INVALID) {
+    check(firstNode == start, "checkDiEulerIt: Wrong first node");
+  }
+
+  for (; e != INVALID; ++e) {
+    if (e != INVALID) lastNode = g.target(e);
+    ++visitationNumber[e];
+  }
+
+  check(firstNode == lastNode,
+      "checkDiEulerIt: First and last nodes are not the same");
+
+  for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
+  {
+    check(visitationNumber[a] == 1,
+        "checkDiEulerIt: Not visited or multiple times visited arc found");
+  }
+}
+
+template <typename Graph>
+void checkEulerIt(const Graph& g,
+                  const typename Graph::Node& start = INVALID)
+{
+  typename Graph::template EdgeMap<int> visitationNumber(g, 0);
+
+  EulerIt<Graph> e(g, start);
+  if (e == INVALID) return;
+  typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
+  typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
+  if (start != INVALID) {
+    check(firstNode == start, "checkEulerIt: Wrong first node");
+  }
+
+  for (; e != INVALID; ++e) {
+    if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
+    ++visitationNumber[e];
+  }
+
+  check(firstNode == lastNode,
+      "checkEulerIt: First and last nodes are not the same");
+
+  for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
+  {
+    check(visitationNumber[e] == 1,
+        "checkEulerIt: Not visited or multiple times visited edge found");
+  }
+}
+
+int main()
+{
+  typedef ListDigraph Digraph;
+  typedef Undirector<Digraph> Graph;
+
+  {
+    Digraph d;
+    Graph g(d);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+    ::lemon::ignore_unused_variable_warning(n);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+    d.addArc(n, n);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n1);
+    d.addArc(n2, n3);
+    d.addArc(n3, n2);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n2);
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n2);
+    checkEulerIt(g);
+    checkEulerIt(g, n2);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n4);
+    d.addArc(n1, n3);
+    d.addArc(n3, n4);
+    d.addArc(n4, n1);
+    d.addArc(n3, n5);
+    d.addArc(n5, n2);
+    d.addArc(n4, n6);
+    d.addArc(n2, n6);
+    d.addArc(n6, n1);
+    d.addArc(n6, n3);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n1);
+    checkDiEulerIt(d, n5);
+
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n1);
+    checkDiEulerIt(g, n5);
+    checkEulerIt(g);
+    checkEulerIt(g, n1);
+    checkEulerIt(g, n5);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n0 = d.addNode();
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    ::lemon::ignore_unused_variable_warning(n0,n4,n5);
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n3);
+    d.addArc(n3, n1);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n2);
+
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n2);
+    checkEulerIt(g);
+    checkEulerIt(g, n2);
+
+    check(!eulerian(d), "This graph is not Eulerian");
+    check(!eulerian(g), "This graph is not Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n3);
+
+    check(!eulerian(d), "This graph is not Eulerian");
+    check(!eulerian(g), "This graph is not Eulerian");
+  }
+
+  return 0;
+}
diff --git a/test/fractional_matching_test.cc b/test/fractional_matching_test.cc
new file mode 100644
index 0000000..bee866c
--- /dev/null
+++ b/test/fractional_matching_test.cc
@@ -0,0 +1,527 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <queue>
+#include <cstdlib>
+
+#include <lemon/fractional_matching.h>
+#include <lemon/smart_graph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+GRAPH_TYPEDEFS(SmartGraph);
+
+
+const int lgfn = 4;
+const std::string lgf[lgfn] = {
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "7 4  0      984\n"
+  "0 7  1      73\n"
+  "7 1  2      204\n"
+  "2 3  3      583\n"
+  "2 7  4      565\n"
+  "2 1  5      582\n"
+  "0 4  6      551\n"
+  "2 5  7      385\n"
+  "1 5  8      561\n"
+  "5 3  9      484\n"
+  "7 5  10     904\n"
+  "3 6  11     47\n"
+  "7 6  12     888\n"
+  "3 0  13     747\n"
+  "6 1  14     310\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "2 5  0      710\n"
+  "0 5  1      241\n"
+  "2 4  2      856\n"
+  "2 6  3      762\n"
+  "4 1  4      747\n"
+  "6 1  5      962\n"
+  "4 7  6      723\n"
+  "1 7  7      661\n"
+  "2 3  8      376\n"
+  "1 0  9      416\n"
+  "6 7  10     391\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "6 2  0      553\n"
+  "0 7  1      653\n"
+  "6 3  2      22\n"
+  "4 7  3      846\n"
+  "7 2  4      981\n"
+  "7 6  5      250\n"
+  "5 2  6      539\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "@edges\n"
+  "     label  weight\n"
+  "0 0  0      100\n"
+};
+
+void checkMaxFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+
+  Graph g;
+  Node n;
+  Edge e;
+
+  MaxFractionalMatching<Graph> mat_test(g);
+  const MaxFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.start(true);
+  mat_test.startPerfect();
+  mat_test.startPerfect(true);
+  mat_test.run();
+  mat_test.run(true);
+  mat_test.runPerfect();
+  mat_test.runPerfect(true);
+
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.barrier(n);
+}
+
+void checkMaxWeightedFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedFractionalMatching<Graph> mat_test(g, w);
+  const MaxWeightedFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+}
+
+void checkMaxWeightedPerfectFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
+  const MaxWeightedPerfectFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+}
+
+void checkFractionalMatching(const SmartGraph& graph,
+                             const MaxFractionalMatching<SmartGraph>& mfm,
+                             bool allow_loops = true) {
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    if (mfm.matching(n) != INVALID) {
+      check(indeg == 1, "Invalid matching");
+      ++pv;
+    } else {
+      check(indeg == 0, "Invalid matching");
+    }
+  }
+  check(pv == mfm.matchingSize(), "Wrong matching size");
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
+          mfm.matching(e), "Invalid matching");
+  }
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  int anum = 0, bnum = 0;
+  SmartGraph::NodeMap<bool> neighbours(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (!mfm.barrier(n)) continue;
+    ++anum;
+    for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
+      Node u = graph.source(a);
+      if (!allow_loops && u == n) continue;
+      if (!neighbours[u]) {
+        neighbours[u] = true;
+        ++bnum;
+      }
+    }
+  }
+  check(anum - bnum + mfm.matchingSize() == countNodes(graph),
+        "Wrong barrier");
+}
+
+void checkPerfectFractionalMatching(const SmartGraph& graph,
+                             const MaxFractionalMatching<SmartGraph>& mfm,
+                             bool perfect, bool allow_loops = true) {
+  if (perfect) {
+    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+      int indeg = 0;
+      for (InArcIt a(graph, n); a != INVALID; ++a) {
+        if (mfm.matching(graph.source(a)) == a) {
+          ++indeg;
+        }
+      }
+      check(mfm.matching(n) != INVALID, "Invalid matching");
+      check(indeg == 1, "Invalid matching");
+    }
+    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+      check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
+            (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
+            mfm.matching(e), "Invalid matching");
+    }
+  } else {
+    int anum = 0, bnum = 0;
+    SmartGraph::NodeMap<bool> neighbours(graph, false);
+    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+      if (!mfm.barrier(n)) continue;
+      ++anum;
+      for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
+        Node u = graph.source(a);
+        if (!allow_loops && u == n) continue;
+        if (!neighbours[u]) {
+          neighbours[u] = true;
+          ++bnum;
+        }
+      }
+    }
+    check(anum - bnum > 0, "Wrong barrier");
+  }
+}
+
+void checkWeightedFractionalMatching(const SmartGraph& graph,
+                   const SmartGraph::EdgeMap<int>& weight,
+                   const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
+                   bool allow_loops = true) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
+    int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
+      - weight[e] * mwfm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwfm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mwfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    check(indeg <= 1, "Invalid matching");
+    if (mwfm.matching(n) != INVALID) {
+      check(mwfm.nodeValue(n) >= 0, "Invalid node value");
+      check(indeg == 1, "Invalid matching");
+      pv += weight[mwfm.matching(n)];
+      SmartGraph::Node o = graph.target(mwfm.matching(n));
+      ::lemon::ignore_unused_variable_warning(o);
+    } else {
+      check(mwfm.nodeValue(n) == 0, "Invalid matching");
+      check(indeg == 0, "Invalid matching");
+    }
+  }
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mwfm.matching(graph.v(e)) ? 1 : 0) ==
+          mwfm.matching(e), "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwfm.nodeValue(n);
+  }
+
+  check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mwfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mwfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mwfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  return;
+}
+
+void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
+                const SmartGraph::EdgeMap<int>& weight,
+                const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
+                bool allow_loops = true) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
+    int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
+      - weight[e] * mwpfm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwpfm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mwpfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
+    check(indeg == 1, "Invalid perfect matching");
+    pv += weight[mwpfm.matching(n)];
+    SmartGraph::Node o = graph.target(mwpfm.matching(n));
+    ::lemon::ignore_unused_variable_warning(o);
+  }
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mwpfm.matching(graph.v(e)) ? 1 : 0) ==
+          mwpfm.matching(e), "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwpfm.nodeValue(n);
+  }
+
+  check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mwpfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mwpfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mwpfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  return;
+}
+
+
+int main() {
+
+  for (int i = 0; i < lgfn; ++i) {
+    SmartGraph graph;
+    SmartGraph::EdgeMap<int> weight(graph);
+
+    istringstream lgfs(lgf[i]);
+    graphReader(graph, lgfs).
+      edgeMap("weight", weight).run();
+
+    bool perfect_with_loops;
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, true);
+      mfm.run();
+      checkFractionalMatching(graph, mfm, true);
+      perfect_with_loops = mfm.matchingSize() == countNodes(graph);
+    }
+
+    bool perfect_without_loops;
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, false);
+      mfm.run();
+      checkFractionalMatching(graph, mfm, false);
+      perfect_without_loops = mfm.matchingSize() == countNodes(graph);
+    }
+
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, true);
+      bool result = mfm.runPerfect();
+      checkPerfectFractionalMatching(graph, mfm, result, true);
+      check(result == perfect_with_loops, "Wrong perfect matching");
+    }
+
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, false);
+      bool result = mfm.runPerfect();
+      checkPerfectFractionalMatching(graph, mfm, result, false);
+      check(result == perfect_without_loops, "Wrong perfect matching");
+    }
+
+    {
+      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
+      mwfm.run();
+      checkWeightedFractionalMatching(graph, weight, mwfm, true);
+    }
+
+    {
+      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
+      mwfm.run();
+      checkWeightedFractionalMatching(graph, weight, mwfm, false);
+    }
+
+    {
+      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
+                                                             true);
+      bool perfect = mwpfm.run();
+      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
+            "Perfect matching found");
+      check(perfect == perfect_with_loops, "Wrong perfect matching");
+
+      if (perfect) {
+        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
+      }
+    }
+
+    {
+      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
+                                                             false);
+      bool perfect = mwpfm.run();
+      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
+            "Perfect matching found");
+      check(perfect == perfect_without_loops, "Wrong perfect matching");
+
+      if (perfect) {
+        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
+      }
+    }
+
+  }
+
+  return 0;
+}
diff --git a/test/gomory_hu_test.cc b/test/gomory_hu_test.cc
new file mode 100644
index 0000000..178f21f
--- /dev/null
+++ b/test/gomory_hu_test.cc
@@ -0,0 +1,142 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/gomory_hu.h>
+#include <cstdlib>
+
+using namespace std;
+using namespace lemon;
+
+typedef SmartGraph Graph;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "@arcs\n"
+  "     label capacity\n"
+  "0 1  0     1\n"
+  "1 2  1     1\n"
+  "2 3  2     1\n"
+  "0 3  4     5\n"
+  "0 3  5     10\n"
+  "0 3  6     7\n"
+  "4 2  7     1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 3\n";
+
+void checkGomoryHuCompile()
+{
+  typedef int Value;
+  typedef concepts::Graph Graph;
+
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef concepts::ReadMap<Edge, Value> CapMap;
+  typedef concepts::ReadWriteMap<Node, bool> CutMap;
+
+  Graph g;
+  Node n;
+  CapMap cap;
+  CutMap cut;
+  Value v;
+  int d;
+  ::lemon::ignore_unused_variable_warning(v,d);
+
+  GomoryHu<Graph, CapMap> gh_test(g, cap);
+  const GomoryHu<Graph, CapMap>&
+    const_gh_test = gh_test;
+
+  gh_test.run();
+
+  n = const_gh_test.predNode(n);
+  v = const_gh_test.predValue(n);
+  d = const_gh_test.rootDist(n);
+  v = const_gh_test.minCutValue(n, n);
+  v = const_gh_test.minCutMap(n, n, cut);
+}
+
+GRAPH_TYPEDEFS(Graph);
+typedef Graph::EdgeMap<int> IntEdgeMap;
+typedef Graph::NodeMap<bool> BoolNodeMap;
+
+int cutValue(const Graph& graph, const BoolNodeMap& cut,
+             const IntEdgeMap& capacity) {
+
+  int sum = 0;
+  for (EdgeIt e(graph); e != INVALID; ++e) {
+    Node s = graph.u(e);
+    Node t = graph.v(e);
+
+    if (cut[s] != cut[t]) {
+      sum += capacity[e];
+    }
+  }
+  return sum;
+}
+
+
+int main() {
+  Graph graph;
+  IntEdgeMap capacity(graph);
+
+  std::istringstream input(test_lgf);
+  GraphReader<Graph>(graph, input).
+    edgeMap("capacity", capacity).run();
+
+  GomoryHu<Graph> ght(graph, capacity);
+  ght.run();
+
+  for (NodeIt u(graph); u != INVALID; ++u) {
+    for (NodeIt v(graph); v != u; ++v) {
+      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
+      pf.runMinCut();
+      BoolNodeMap cm(graph);
+      ght.minCutMap(u, v, cm);
+      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
+      check(cm[u] != cm[v], "Wrong cut 2");
+      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
+
+      int sum=0;
+      for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
+        sum+=capacity[a];
+      check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
+
+      sum=0;
+      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
+        sum++;
+      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
+        sum++;
+      check(sum == countNodes(graph), "Problem with MinCutNodeIt");
+    }
+  }
+
+  return 0;
+}
diff --git a/test/graph_copy_test.cc b/test/graph_copy_test.cc
new file mode 100644
index 0000000..9a7d815
--- /dev/null
+++ b/test/graph_copy_test.cc
@@ -0,0 +1,388 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/smart_graph.h>
+#include <lemon/list_graph.h>
+#include <lemon/static_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/error.h>
+
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+template <typename GR>
+void digraph_copy_test() {
+  const int nn = 10;
+
+  // Build a digraph
+  SmartDigraph from;
+  SmartDigraph::NodeMap<int> fnm(from);
+  SmartDigraph::ArcMap<int> fam(from);
+  SmartDigraph::Node fn = INVALID;
+  SmartDigraph::Arc fa = INVALID;
+
+  std::vector<SmartDigraph::Node> fnv;
+  for (int i = 0; i < nn; ++i) {
+    SmartDigraph::Node node = from.addNode();
+    fnv.push_back(node);
+    fnm[node] = i * i;
+    if (i == 0) fn = node;
+  }
+
+  for (int i = 0; i < nn; ++i) {
+    for (int j = 0; j < nn; ++j) {
+      SmartDigraph::Arc arc = from.addArc(fnv[i], fnv[j]);
+      fam[arc] = i + j * j;
+      if (i == 0 && j == 0) fa = arc;
+    }
+  }
+
+  // Test digraph copy
+  GR to;
+  typename GR::template NodeMap<int> tnm(to);
+  typename GR::template ArcMap<int> tam(to);
+  typename GR::Node tn;
+  typename GR::Arc ta;
+
+  SmartDigraph::NodeMap<typename GR::Node> nr(from);
+  SmartDigraph::ArcMap<typename GR::Arc> er(from);
+
+  typename GR::template NodeMap<SmartDigraph::Node> ncr(to);
+  typename GR::template ArcMap<SmartDigraph::Arc> ecr(to);
+
+  digraphCopy(from, to).
+    nodeMap(fnm, tnm).arcMap(fam, tam).
+    nodeRef(nr).arcRef(er).
+    nodeCrossRef(ncr).arcCrossRef(ecr).
+    node(fn, tn).arc(fa, ta).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+
+  for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) {
+    check(ncr[nr[it]] == it, "Wrong copy.");
+    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
+  }
+
+  for (SmartDigraph::ArcIt it(from); it != INVALID; ++it) {
+    check(ecr[er[it]] == it, "Wrong copy.");
+    check(fam[it] == tam[er[it]], "Wrong copy.");
+    check(nr[from.source(it)] == to.source(er[it]), "Wrong copy.");
+    check(nr[from.target(it)] == to.target(er[it]), "Wrong copy.");
+  }
+
+  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
+    check(nr[ncr[it]] == it, "Wrong copy.");
+  }
+
+  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
+    check(er[ecr[it]] == it, "Wrong copy.");
+  }
+  check(tn == nr[fn], "Wrong copy.");
+  check(ta == er[fa], "Wrong copy.");
+
+  // Test repeated copy
+  digraphCopy(from, to).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+}
+
+template <typename GR>
+void graph_copy_test() {
+  const int nn = 10;
+
+  // Build a graph
+  SmartGraph from;
+  SmartGraph::NodeMap<int> fnm(from);
+  SmartGraph::ArcMap<int> fam(from);
+  SmartGraph::EdgeMap<int> fem(from);
+  SmartGraph::Node fn = INVALID;
+  SmartGraph::Arc fa = INVALID;
+  SmartGraph::Edge fe = INVALID;
+
+  std::vector<SmartGraph::Node> fnv;
+  for (int i = 0; i < nn; ++i) {
+    SmartGraph::Node node = from.addNode();
+    fnv.push_back(node);
+    fnm[node] = i * i;
+    if (i == 0) fn = node;
+  }
+
+  for (int i = 0; i < nn; ++i) {
+    for (int j = 0; j < nn; ++j) {
+      SmartGraph::Edge edge = from.addEdge(fnv[i], fnv[j]);
+      fem[edge] = i * i + j * j;
+      fam[from.direct(edge, true)] = i + j * j;
+      fam[from.direct(edge, false)] = i * i + j;
+      if (i == 0 && j == 0) fa = from.direct(edge, true);
+      if (i == 0 && j == 0) fe = edge;
+    }
+  }
+
+  // Test graph copy
+  GR to;
+  typename GR::template NodeMap<int> tnm(to);
+  typename GR::template ArcMap<int> tam(to);
+  typename GR::template EdgeMap<int> tem(to);
+  typename GR::Node tn;
+  typename GR::Arc ta;
+  typename GR::Edge te;
+
+  SmartGraph::NodeMap<typename GR::Node> nr(from);
+  SmartGraph::ArcMap<typename GR::Arc> ar(from);
+  SmartGraph::EdgeMap<typename GR::Edge> er(from);
+
+  typename GR::template NodeMap<SmartGraph::Node> ncr(to);
+  typename GR::template ArcMap<SmartGraph::Arc> acr(to);
+  typename GR::template EdgeMap<SmartGraph::Edge> ecr(to);
+
+  graphCopy(from, to).
+    nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem).
+    nodeRef(nr).arcRef(ar).edgeRef(er).
+    nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr).
+    node(fn, tn).arc(fa, ta).edge(fe, te).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countEdges(from) == countEdges(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+
+  for (SmartGraph::NodeIt it(from); it != INVALID; ++it) {
+    check(ncr[nr[it]] == it, "Wrong copy.");
+    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
+  }
+
+  for (SmartGraph::ArcIt it(from); it != INVALID; ++it) {
+    check(acr[ar[it]] == it, "Wrong copy.");
+    check(fam[it] == tam[ar[it]], "Wrong copy.");
+    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
+    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
+  }
+
+  for (SmartGraph::EdgeIt it(from); it != INVALID; ++it) {
+    check(ecr[er[it]] == it, "Wrong copy.");
+    check(fem[it] == tem[er[it]], "Wrong copy.");
+    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
+          "Wrong copy.");
+    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
+          "Wrong copy.");
+    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
+          "Wrong copy.");
+  }
+
+  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
+    check(nr[ncr[it]] == it, "Wrong copy.");
+  }
+
+  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
+    check(ar[acr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::EdgeIt it(to); it != INVALID; ++it) {
+    check(er[ecr[it]] == it, "Wrong copy.");
+  }
+  check(tn == nr[fn], "Wrong copy.");
+  check(ta == ar[fa], "Wrong copy.");
+  check(te == er[fe], "Wrong copy.");
+
+  // Test repeated copy
+  graphCopy(from, to).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countEdges(from) == countEdges(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+}
+
+template <typename GR>
+void bpgraph_copy_test() {
+  const int nn = 10;
+
+  // Build a graph
+  SmartBpGraph from;
+  SmartBpGraph::NodeMap<int> fnm(from);
+  SmartBpGraph::RedNodeMap<int> frnm(from);
+  SmartBpGraph::BlueNodeMap<int> fbnm(from);
+  SmartBpGraph::ArcMap<int> fam(from);
+  SmartBpGraph::EdgeMap<int> fem(from);
+  SmartBpGraph::Node fn = INVALID;
+  SmartBpGraph::RedNode frn = INVALID;
+  SmartBpGraph::BlueNode fbn = INVALID;
+  SmartBpGraph::Arc fa = INVALID;
+  SmartBpGraph::Edge fe = INVALID;
+
+  std::vector<SmartBpGraph::RedNode> frnv;
+  for (int i = 0; i < nn; ++i) {
+    SmartBpGraph::RedNode node = from.addRedNode();
+    frnv.push_back(node);
+    fnm[node] = i * i;
+    frnm[node] = i + i;
+    if (i == 0) {
+      fn = node;
+      frn = node;
+    }
+  }
+
+  std::vector<SmartBpGraph::BlueNode> fbnv;
+  for (int i = 0; i < nn; ++i) {
+    SmartBpGraph::BlueNode node = from.addBlueNode();
+    fbnv.push_back(node);
+    fnm[node] = i * i;
+    fbnm[node] = i + i;
+    if (i == 0) fbn = node;
+  }
+
+  for (int i = 0; i < nn; ++i) {
+    for (int j = 0; j < nn; ++j) {
+      SmartBpGraph::Edge edge = from.addEdge(frnv[i], fbnv[j]);
+      fem[edge] = i * i + j * j;
+      fam[from.direct(edge, true)] = i + j * j;
+      fam[from.direct(edge, false)] = i * i + j;
+      if (i == 0 && j == 0) fa = from.direct(edge, true);
+      if (i == 0 && j == 0) fe = edge;
+    }
+  }
+
+  // Test graph copy
+  GR to;
+  typename GR::template NodeMap<int> tnm(to);
+  typename GR::template RedNodeMap<int> trnm(to);
+  typename GR::template BlueNodeMap<int> tbnm(to);
+  typename GR::template ArcMap<int> tam(to);
+  typename GR::template EdgeMap<int> tem(to);
+  typename GR::Node tn;
+  typename GR::RedNode trn;
+  typename GR::BlueNode tbn;
+  typename GR::Arc ta;
+  typename GR::Edge te;
+
+  SmartBpGraph::NodeMap<typename GR::Node> nr(from);
+  SmartBpGraph::RedNodeMap<typename GR::RedNode> rnr(from);
+  SmartBpGraph::BlueNodeMap<typename GR::BlueNode> bnr(from);
+  SmartBpGraph::ArcMap<typename GR::Arc> ar(from);
+  SmartBpGraph::EdgeMap<typename GR::Edge> er(from);
+
+  typename GR::template NodeMap<SmartBpGraph::Node> ncr(to);
+  typename GR::template RedNodeMap<SmartBpGraph::RedNode> rncr(to);
+  typename GR::template BlueNodeMap<SmartBpGraph::BlueNode> bncr(to);
+  typename GR::template ArcMap<SmartBpGraph::Arc> acr(to);
+  typename GR::template EdgeMap<SmartBpGraph::Edge> ecr(to);
+
+  bpGraphCopy(from, to).
+    nodeMap(fnm, tnm).
+    redNodeMap(frnm, trnm).blueNodeMap(fbnm, tbnm).
+    arcMap(fam, tam).edgeMap(fem, tem).
+    nodeRef(nr).redRef(rnr).blueRef(bnr).
+    arcRef(ar).edgeRef(er).
+    nodeCrossRef(ncr).redCrossRef(rncr).blueCrossRef(bncr).
+    arcCrossRef(acr).edgeCrossRef(ecr).
+    node(fn, tn).redNode(frn, trn).blueNode(fbn, tbn).
+    arc(fa, ta).edge(fe, te).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countRedNodes(from) == countRedNodes(to), "Wrong copy.");
+  check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy.");
+  check(countEdges(from) == countEdges(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+
+  for (SmartBpGraph::NodeIt it(from); it != INVALID; ++it) {
+    check(ncr[nr[it]] == it, "Wrong copy.");
+    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
+  }
+
+  for (SmartBpGraph::RedNodeIt it(from); it != INVALID; ++it) {
+    check(ncr[nr[it]] == it, "Wrong copy.");
+    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
+    check(rnr[it] == nr[it], "Wrong copy.");
+    check(rncr[rnr[it]] == it, "Wrong copy.");
+    check(frnm[it] == trnm[rnr[it]], "Wrong copy.");
+    check(to.red(rnr[it]), "Wrong copy.");
+  }
+
+  for (SmartBpGraph::BlueNodeIt it(from); it != INVALID; ++it) {
+    check(ncr[nr[it]] == it, "Wrong copy.");
+    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
+    check(bnr[it] == nr[it], "Wrong copy.");
+    check(bncr[bnr[it]] == it, "Wrong copy.");
+    check(fbnm[it] == tbnm[bnr[it]], "Wrong copy.");
+    check(to.blue(bnr[it]), "Wrong copy.");
+  }
+
+  for (SmartBpGraph::ArcIt it(from); it != INVALID; ++it) {
+    check(acr[ar[it]] == it, "Wrong copy.");
+    check(fam[it] == tam[ar[it]], "Wrong copy.");
+    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
+    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
+  }
+
+  for (SmartBpGraph::EdgeIt it(from); it != INVALID; ++it) {
+    check(ecr[er[it]] == it, "Wrong copy.");
+    check(fem[it] == tem[er[it]], "Wrong copy.");
+    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
+          "Wrong copy.");
+    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
+          "Wrong copy.");
+    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
+          "Wrong copy.");
+  }
+
+  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
+    check(nr[ncr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::RedNodeIt it(to); it != INVALID; ++it) {
+    check(rncr[it] == ncr[it], "Wrong copy.");
+    check(rnr[rncr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::BlueNodeIt it(to); it != INVALID; ++it) {
+    check(bncr[it] == ncr[it], "Wrong copy.");
+    check(bnr[bncr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
+    check(ar[acr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::EdgeIt it(to); it != INVALID; ++it) {
+    check(er[ecr[it]] == it, "Wrong copy.");
+  }
+  check(tn == nr[fn], "Wrong copy.");
+  check(trn == rnr[frn], "Wrong copy.");
+  check(tbn == bnr[fbn], "Wrong copy.");
+  check(ta == ar[fa], "Wrong copy.");
+  check(te == er[fe], "Wrong copy.");
+
+  // Test repeated copy
+  bpGraphCopy(from, to).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countRedNodes(from) == countRedNodes(to), "Wrong copy.");
+  check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy.");
+  check(countEdges(from) == countEdges(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+}
+
+
+int main() {
+  digraph_copy_test<SmartDigraph>();
+  digraph_copy_test<ListDigraph>();
+  digraph_copy_test<StaticDigraph>();
+  graph_copy_test<SmartGraph>();
+  graph_copy_test<ListGraph>();
+  bpgraph_copy_test<SmartBpGraph>();
+  bpgraph_copy_test<ListBpGraph>();
+
+  return 0;
+}
diff --git a/test/graph_test.cc b/test/graph_test.cc
new file mode 100644
index 0000000..283b02e
--- /dev/null
+++ b/test/graph_test.cc
@@ -0,0 +1,603 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/graph.h>
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/full_graph.h>
+#include <lemon/grid_graph.h>
+#include <lemon/hypercube_graph.h>
+
+#include "test_tools.h"
+#include "graph_test.h"
+
+using namespace lemon;
+using namespace lemon::concepts;
+
+template <class Graph>
+void checkGraphBuild() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+  Graph G;
+  checkGraphNodeList(G, 0);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  G.reserveNode(3);
+  G.reserveEdge(3);
+
+  Node
+    n1 = G.addNode(),
+    n2 = G.addNode(),
+    n3 = G.addNode();
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  Edge e1 = G.addEdge(n1, n2);
+  check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
+        "Wrong edge");
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 1);
+  checkGraphArcList(G, 2);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 1);
+  checkGraphIncEdgeArcLists(G, n3, 0);
+
+  checkGraphConEdgeList(G, 1);
+  checkGraphConArcList(G, 2);
+
+  Edge e2 = G.addEdge(n2, n1),
+       e3 = G.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2,e3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+}
+
+template <class Graph>
+void checkGraphAlter() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+  Graph G;
+  Node n1 = G.addNode(), n2 = G.addNode(),
+       n3 = G.addNode(), n4 = G.addNode();
+  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
+       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
+       e5 = G.addEdge(n4, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e3,e4,e5);
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 5);
+  checkGraphArcList(G, 10);
+
+  // Check changeU() and changeV()
+  if (G.u(e2) == n2) {
+    G.changeU(e2, n3);
+  } else {
+    G.changeV(e2, n3);
+  }
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 5);
+  checkGraphArcList(G, 10);
+
+  checkGraphIncEdgeArcLists(G, n1, 3);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n3, 3);
+  checkGraphIncEdgeArcLists(G, n4, 2);
+
+  checkGraphConEdgeList(G, 5);
+  checkGraphConArcList(G, 10);
+
+  if (G.u(e2) == n1) {
+    G.changeU(e2, n2);
+  } else {
+    G.changeV(e2, n2);
+  }
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 5);
+  checkGraphArcList(G, 10);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 3);
+  checkGraphIncEdgeArcLists(G, n4, 2);
+
+  checkGraphConEdgeList(G, 5);
+  checkGraphConArcList(G, 10);
+
+  // Check contract()
+  G.contract(n1, n4, false);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 5);
+  checkGraphArcList(G, 10);
+
+  checkGraphIncEdgeArcLists(G, n1, 4);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 3);
+
+  checkGraphConEdgeList(G, 5);
+  checkGraphConArcList(G, 10);
+
+  G.contract(n2, n3);
+
+  checkGraphNodeList(G, 2);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, n1, 4);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+}
+
+template <class Graph>
+void checkGraphErase() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+  Graph G;
+  Node n1 = G.addNode(), n2 = G.addNode(),
+       n3 = G.addNode(), n4 = G.addNode();
+  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
+       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
+       e5 = G.addEdge(n4, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e3,e4,e5);
+
+  // Check edge deletion
+  G.erase(e2);
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n3, 2);
+  checkGraphIncEdgeArcLists(G, n4, 2);
+
+  checkGraphConEdgeList(G, 4);
+  checkGraphConArcList(G, 8);
+
+  // Check node deletion
+  G.erase(n3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 1);
+  checkGraphIncEdgeArcLists(G, n4, 1);
+
+  checkGraphConEdgeList(G, 2);
+  checkGraphConArcList(G, 4);
+}
+
+
+template <class Graph>
+void checkGraphSnapshot() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+  Graph G;
+  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
+  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
+       e3 = G.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e2,e3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  typename Graph::Snapshot snapshot(G);
+
+  Node n = G.addNode();
+  G.addEdge(n3, n);
+  G.addEdge(n, n3);
+  G.addEdge(n3, n2);
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 6);
+  checkGraphArcList(G, 12);
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+
+  checkNodeIds(G);
+  checkEdgeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphEdgeMap(G);
+  checkGraphArcMap(G);
+
+  G.addNode();
+  snapshot.save(G);
+
+  G.addEdge(G.addNode(), G.addNode());
+
+  snapshot.restore();
+  snapshot.save(G);
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  G.addEdge(G.addNode(), G.addNode());
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+}
+
+void checkFullGraph(int num) {
+  typedef FullGraph Graph;
+  GRAPH_TYPEDEFS(Graph);
+
+  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);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, num - 1);
+    checkGraphInArcList(G, n, num - 1);
+    checkGraphIncEdgeList(G, n, num - 1);
+  }
+
+  checkGraphConArcList(G, num * (num - 1));
+  checkGraphConEdgeList(G, num * (num - 1) / 2);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+
+  for (int i = 0; i < G.nodeNum(); ++i) {
+    check(G.index(G(i)) == i, "Wrong index");
+  }
+
+  for (NodeIt u(G); u != INVALID; ++u) {
+    for (NodeIt v(G); v != INVALID; ++v) {
+      Edge e = G.edge(u, v);
+      Arc a = G.arc(u, v);
+      if (u == v) {
+        check(e == INVALID, "Wrong edge lookup");
+        check(a == INVALID, "Wrong arc lookup");
+      } else {
+        check((G.u(e) == u && G.v(e) == v) ||
+              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
+        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
+      }
+    }
+  }
+}
+
+void checkConcepts() {
+  { // Checking graph components
+    checkConcept<BaseGraphComponent, BaseGraphComponent >();
+
+    checkConcept<IDableGraphComponent<>,
+      IDableGraphComponent<> >();
+
+    checkConcept<IterableGraphComponent<>,
+      IterableGraphComponent<> >();
+
+    checkConcept<MappableGraphComponent<>,
+      MappableGraphComponent<> >();
+  }
+  { // Checking skeleton graph
+    checkConcept<Graph, Graph>();
+  }
+  { // Checking ListGraph
+    checkConcept<Graph, ListGraph>();
+    checkConcept<AlterableGraphComponent<>, ListGraph>();
+    checkConcept<ExtendableGraphComponent<>, ListGraph>();
+    checkConcept<ClearableGraphComponent<>, ListGraph>();
+    checkConcept<ErasableGraphComponent<>, ListGraph>();
+  }
+  { // Checking SmartGraph
+    checkConcept<Graph, SmartGraph>();
+    checkConcept<AlterableGraphComponent<>, SmartGraph>();
+    checkConcept<ExtendableGraphComponent<>, SmartGraph>();
+    checkConcept<ClearableGraphComponent<>, SmartGraph>();
+  }
+  { // Checking FullGraph
+    checkConcept<Graph, FullGraph>();
+  }
+  { // Checking GridGraph
+    checkConcept<Graph, GridGraph>();
+  }
+  { // Checking HypercubeGraph
+    checkConcept<Graph, HypercubeGraph>();
+  }
+}
+
+template <typename Graph>
+void checkGraphValidity() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+  Graph g;
+
+  Node
+    n1 = g.addNode(),
+    n2 = g.addNode(),
+    n3 = g.addNode();
+
+  Edge
+    e1 = g.addEdge(n1, n2),
+    e2 = g.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2);
+
+  check(g.valid(n1), "Wrong validity check");
+  check(g.valid(e1), "Wrong validity check");
+  check(g.valid(g.direct(e1, true)), "Wrong validity check");
+
+  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
+}
+
+template <typename Graph>
+void checkGraphValidityErase() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+  Graph g;
+
+  Node
+    n1 = g.addNode(),
+    n2 = g.addNode(),
+    n3 = g.addNode();
+
+  Edge
+    e1 = g.addEdge(n1, n2),
+    e2 = g.addEdge(n2, n3);
+
+  check(g.valid(n1), "Wrong validity check");
+  check(g.valid(e1), "Wrong validity check");
+  check(g.valid(g.direct(e1, true)), "Wrong validity check");
+
+  g.erase(n1);
+
+  check(!g.valid(n1), "Wrong validity check");
+  check(g.valid(n2), "Wrong validity check");
+  check(g.valid(n3), "Wrong validity check");
+  check(!g.valid(e1), "Wrong validity check");
+  check(g.valid(e2), "Wrong validity check");
+
+  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
+}
+
+void checkGridGraph(int width, int height) {
+  typedef GridGraph Graph;
+  GRAPH_TYPEDEFS(Graph);
+  Graph G(width, height);
+
+  check(G.width() == width, "Wrong column number");
+  check(G.height() == height, "Wrong row number");
+
+  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) {
+      check(G.col(G(i, j)) == i, "Wrong column");
+      check(G.row(G(i, j)) == j, "Wrong row");
+      check(G.pos(G(i, j)).x == i, "Wrong column");
+      check(G.pos(G(i, j)).y == j, "Wrong row");
+    }
+  }
+
+  for (int j = 0; j < height; ++j) {
+    for (int i = 0; i < width - 1; ++i) {
+      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
+      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
+    }
+    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
+  }
+
+  for (int j = 0; j < height; ++j) {
+    for (int i = 1; i < width; ++i) {
+      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
+      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
+    }
+    check(G.left(G(0, j)) == INVALID, "Wrong left");
+  }
+
+  for (int i = 0; i < width; ++i) {
+    for (int j = 0; j < height - 1; ++j) {
+      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
+      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
+    }
+    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
+  }
+
+  for (int i = 0; i < width; ++i) {
+    for (int j = 1; j < height; ++j) {
+      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
+      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
+    }
+    check(G.down(G(i, 0)) == INVALID, "Wrong down");
+  }
+
+  checkGraphNodeList(G, width * height);
+  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
+  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    int nb = 4;
+    if (G.col(n) == 0) --nb;
+    if (G.col(n) == width - 1) --nb;
+    if (G.row(n) == 0) --nb;
+    if (G.row(n) == height - 1) --nb;
+
+    checkGraphOutArcList(G, n, nb);
+    checkGraphInArcList(G, n, nb);
+    checkGraphIncEdgeList(G, n, nb);
+  }
+
+  checkArcDirections(G);
+
+  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
+  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+}
+
+void checkHypercubeGraph(int dim) {
+  GRAPH_TYPEDEFS(HypercubeGraph);
+
+  HypercubeGraph G(dim);
+  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)));
+  checkGraphArcList(G, dim * (1 << dim));
+
+  Node n = G.nodeFromId(dim);
+  ::lemon::ignore_unused_variable_warning(n);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphIncEdgeList(G, n, dim);
+    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
+      check( (G.u(e) == n &&
+              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
+             (G.v(e) == n &&
+              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
+             "Wrong edge or wrong dimension");
+    }
+
+    checkGraphOutArcList(G, n, dim);
+    for (OutArcIt a(G, n); a != INVALID; ++a) {
+      check(G.source(a) == n &&
+            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
+            "Wrong arc or wrong dimension");
+    }
+
+    checkGraphInArcList(G, n, dim);
+    for (InArcIt a(G, n); a != INVALID; ++a) {
+      check(G.target(a) == n &&
+            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
+            "Wrong arc or wrong dimension");
+    }
+  }
+
+  checkGraphConArcList(G, (1 << dim) * dim);
+  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+}
+
+void checkGraphs() {
+  { // Checking ListGraph
+    checkGraphBuild<ListGraph>();
+    checkGraphAlter<ListGraph>();
+    checkGraphErase<ListGraph>();
+    checkGraphSnapshot<ListGraph>();
+    checkGraphValidityErase<ListGraph>();
+  }
+  { // Checking SmartGraph
+    checkGraphBuild<SmartGraph>();
+    checkGraphSnapshot<SmartGraph>();
+    checkGraphValidity<SmartGraph>();
+  }
+  { // Checking FullGraph
+    checkFullGraph(7);
+    checkFullGraph(8);
+  }
+  { // Checking GridGraph
+    checkGridGraph(5, 8);
+    checkGridGraph(8, 5);
+    checkGridGraph(5, 5);
+    checkGridGraph(0, 0);
+    checkGridGraph(1, 1);
+  }
+  { // Checking HypercubeGraph
+    checkHypercubeGraph(1);
+    checkHypercubeGraph(2);
+    checkHypercubeGraph(3);
+    checkHypercubeGraph(4);
+  }
+}
+
+int main() {
+  checkConcepts();
+  checkGraphs();
+  return 0;
+}
diff --git a/test/graph_test.h b/test/graph_test.h
new file mode 100644
index 0000000..70558b7
--- /dev/null
+++ b/test/graph_test.h
@@ -0,0 +1,421 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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_TEST_GRAPH_TEST_H
+#define LEMON_TEST_GRAPH_TEST_H
+
+#include <set>
+
+#include <lemon/core.h>
+#include <lemon/maps.h>
+
+#include "test_tools.h"
+
+namespace lemon {
+
+  template<class Graph>
+  void checkGraphNodeList(const Graph &G, int cnt)
+  {
+    typename Graph::NodeIt n(G);
+    for(int i=0;i<cnt;i++) {
+      check(n!=INVALID,"Wrong Node list linking.");
+      ++n;
+    }
+    check(n==INVALID,"Wrong Node list linking.");
+    check(countNodes(G)==cnt,"Wrong Node number.");
+  }
+
+  template<class Graph>
+  void checkGraphRedNodeList(const Graph &G, int cnt)
+  {
+    typename Graph::RedNodeIt n(G);
+    for(int i=0;i<cnt;i++) {
+      check(n!=INVALID,"Wrong red Node list linking.");
+      check(G.red(n),"Wrong node set check.");
+      check(!G.blue(n),"Wrong node set check.");
+      typename Graph::Node nn = n;
+      check(G.asRedNodeUnsafe(nn) == n,"Wrong node conversion.");
+      check(G.asRedNode(nn) == n,"Wrong node conversion.");
+      check(G.asBlueNode(nn) == INVALID,"Wrong node conversion.");
+      ++n;
+    }
+    check(n==INVALID,"Wrong red Node list linking.");
+    check(countRedNodes(G)==cnt,"Wrong red Node number.");
+  }
+
+  template<class Graph>
+  void checkGraphBlueNodeList(const Graph &G, int cnt)
+  {
+    typename Graph::BlueNodeIt n(G);
+    for(int i=0;i<cnt;i++) {
+      check(n!=INVALID,"Wrong blue Node list linking.");
+      check(G.blue(n),"Wrong node set check.");
+      check(!G.red(n),"Wrong node set check.");
+      typename Graph::Node nn = n;
+      check(G.asBlueNodeUnsafe(nn) == n,"Wrong node conversion.");
+      check(G.asBlueNode(nn) == n,"Wrong node conversion.");
+      check(G.asRedNode(nn) == INVALID,"Wrong node conversion.");
+      ++n;
+    }
+    check(n==INVALID,"Wrong blue Node list linking.");
+    check(countBlueNodes(G)==cnt,"Wrong blue Node number.");
+  }
+
+  template<class Graph>
+  void checkGraphArcList(const Graph &G, int cnt)
+  {
+    typename Graph::ArcIt e(G);
+    for(int i=0;i<cnt;i++) {
+      check(e!=INVALID,"Wrong Arc list linking.");
+      check(G.oppositeNode(G.source(e), e) == G.target(e),
+            "Wrong opposite node");
+      check(G.oppositeNode(G.target(e), e) == G.source(e),
+            "Wrong opposite node");
+      ++e;
+    }
+    check(e==INVALID,"Wrong Arc list linking.");
+    check(countArcs(G)==cnt,"Wrong Arc number.");
+  }
+
+  template<class Graph>
+  void checkGraphOutArcList(const Graph &G, typename Graph::Node n, int cnt)
+  {
+    typename Graph::OutArcIt e(G,n);
+    for(int i=0;i<cnt;i++) {
+      check(e!=INVALID,"Wrong OutArc list linking.");
+      check(n==G.source(e),"Wrong OutArc list linking.");
+      check(n==G.baseNode(e),"Wrong OutArc list linking.");
+      check(G.target(e)==G.runningNode(e),"Wrong OutArc list linking.");
+      ++e;
+    }
+    check(e==INVALID,"Wrong OutArc list linking.");
+    check(countOutArcs(G,n)==cnt,"Wrong OutArc number.");
+  }
+
+  template<class Graph>
+  void checkGraphInArcList(const Graph &G, typename Graph::Node n, int cnt)
+  {
+    typename Graph::InArcIt e(G,n);
+    for(int i=0;i<cnt;i++) {
+      check(e!=INVALID,"Wrong InArc list linking.");
+      check(n==G.target(e),"Wrong InArc list linking.");
+      check(n==G.baseNode(e),"Wrong OutArc list linking.");
+      check(G.source(e)==G.runningNode(e),"Wrong OutArc list linking.");
+      ++e;
+    }
+    check(e==INVALID,"Wrong InArc list linking.");
+    check(countInArcs(G,n)==cnt,"Wrong InArc number.");
+  }
+
+  template<class Graph>
+  void checkGraphEdgeList(const Graph &G, int cnt)
+  {
+    typename Graph::EdgeIt e(G);
+    for(int i=0;i<cnt;i++) {
+      check(e!=INVALID,"Wrong Edge list linking.");
+      check(G.oppositeNode(G.u(e), e) == G.v(e), "Wrong opposite node");
+      check(G.oppositeNode(G.v(e), e) == G.u(e), "Wrong opposite node");
+      ++e;
+    }
+    check(e==INVALID,"Wrong Edge list linking.");
+    check(countEdges(G)==cnt,"Wrong Edge number.");
+  }
+
+  template<class Graph>
+  void checkGraphIncEdgeList(const Graph &G, typename Graph::Node n, int cnt)
+  {
+    typename Graph::IncEdgeIt e(G,n);
+    for(int i=0;i<cnt;i++) {
+      check(e!=INVALID,"Wrong IncEdge list linking.");
+      check(n==G.u(e) || n==G.v(e),"Wrong IncEdge list linking.");
+      check(n==G.baseNode(e),"Wrong OutArc list linking.");
+      check(G.u(e)==G.runningNode(e) || G.v(e)==G.runningNode(e),
+            "Wrong OutArc list linking.");
+      ++e;
+    }
+    check(e==INVALID,"Wrong IncEdge list linking.");
+    check(countIncEdges(G,n)==cnt,"Wrong IncEdge number.");
+  }
+
+  template <class Graph>
+  void checkGraphIncEdgeArcLists(const Graph &G, typename Graph::Node n,
+                                 int cnt)
+  {
+    checkGraphIncEdgeList(G, n, cnt);
+    checkGraphOutArcList(G, n, cnt);
+    checkGraphInArcList(G, n, cnt);
+  }
+
+  template <class Graph>
+  void checkGraphConArcList(const Graph &G, int cnt) {
+    int i = 0;
+    for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
+      for (typename Graph::NodeIt v(G); v != INVALID; ++v) {
+        for (ConArcIt<Graph> a(G, u, v); a != INVALID; ++a) {
+          check(G.source(a) == u, "Wrong iterator.");
+          check(G.target(a) == v, "Wrong iterator.");
+          ++i;
+        }
+      }
+    }
+    check(cnt == i, "Wrong iterator.");
+  }
+
+  template <class Graph>
+  void checkGraphConEdgeList(const Graph &G, int cnt) {
+    int i = 0;
+    for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
+      for (typename Graph::NodeIt v(G); v != INVALID; ++v) {
+        for (ConEdgeIt<Graph> e(G, u, v); e != INVALID; ++e) {
+          check((G.u(e) == u && G.v(e) == v) ||
+                (G.u(e) == v && G.v(e) == u), "Wrong iterator.");
+          i += u == v ? 2 : 1;
+        }
+      }
+    }
+    check(2 * cnt == i, "Wrong iterator.");
+  }
+
+  template <typename Graph>
+  void checkArcDirections(const Graph& G) {
+    for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
+      check(G.source(a) == G.target(G.oppositeArc(a)), "Wrong direction");
+      check(G.target(a) == G.source(G.oppositeArc(a)), "Wrong direction");
+      check(G.direct(a, G.direction(a)) == a, "Wrong direction");
+    }
+  }
+
+  template <typename Graph>
+  void checkNodeIds(const Graph& G) {
+    typedef typename Graph::Node Node;
+    std::set<int> values;
+    for (typename Graph::NodeIt n(G); n != INVALID; ++n) {
+      check(G.nodeFromId(G.id(n)) == n, "Wrong id");
+      check(values.find(G.id(n)) == values.end(), "Wrong id");
+      check(G.id(n) <= G.maxNodeId(), "Wrong maximum id");
+      values.insert(G.id(n));
+    }
+    check(G.maxId(Node()) <= G.maxNodeId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkRedNodeIds(const Graph& G) {
+    typedef typename Graph::RedNode RedNode;
+    std::set<int> values;
+    for (typename Graph::RedNodeIt n(G); n != INVALID; ++n) {
+      check(G.red(n), "Wrong partition");
+      check(values.find(G.id(n)) == values.end(), "Wrong id");
+      check(G.id(n) <= G.maxRedId(), "Wrong maximum id");
+      values.insert(G.id(n));
+    }
+    check(G.maxId(RedNode()) == G.maxRedId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkBlueNodeIds(const Graph& G) {
+    typedef typename Graph::BlueNode BlueNode;
+    std::set<int> values;
+    for (typename Graph::BlueNodeIt n(G); n != INVALID; ++n) {
+      check(G.blue(n), "Wrong partition");
+      check(values.find(G.id(n)) == values.end(), "Wrong id");
+      check(G.id(n) <= G.maxBlueId(), "Wrong maximum id");
+      values.insert(G.id(n));
+    }
+    check(G.maxId(BlueNode()) == G.maxBlueId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkArcIds(const Graph& G) {
+    typedef typename Graph::Arc Arc;
+    std::set<int> values;
+    for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
+      check(G.arcFromId(G.id(a)) == a, "Wrong id");
+      check(values.find(G.id(a)) == values.end(), "Wrong id");
+      check(G.id(a) <= G.maxArcId(), "Wrong maximum id");
+      values.insert(G.id(a));
+    }
+    check(G.maxId(Arc()) <= G.maxArcId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkEdgeIds(const Graph& G) {
+    typedef typename Graph::Edge Edge;
+    std::set<int> values;
+    for (typename Graph::EdgeIt e(G); e != INVALID; ++e) {
+      check(G.edgeFromId(G.id(e)) == e, "Wrong id");
+      check(values.find(G.id(e)) == values.end(), "Wrong id");
+      check(G.id(e) <= G.maxEdgeId(), "Wrong maximum id");
+      values.insert(G.id(e));
+    }
+    check(G.maxId(Edge()) <= G.maxEdgeId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkGraphNodeMap(const Graph& G) {
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+
+    typedef typename Graph::template NodeMap<int> IntNodeMap;
+    IntNodeMap map(G, 42);
+    for (NodeIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (NodeIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (NodeIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Node>(12);
+    // for (NodeIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+  template <typename Graph>
+  void checkGraphRedNodeMap(const Graph& G) {
+    typedef typename Graph::Node Node;
+    typedef typename Graph::RedNodeIt RedNodeIt;
+
+    typedef typename Graph::template RedNodeMap<int> IntRedNodeMap;
+    IntRedNodeMap map(G, 42);
+    for (RedNodeIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (RedNodeIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (RedNodeIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Node>(12);
+    // for (NodeIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+  template <typename Graph>
+  void checkGraphBlueNodeMap(const Graph& G) {
+    typedef typename Graph::Node Node;
+    typedef typename Graph::BlueNodeIt BlueNodeIt;
+
+    typedef typename Graph::template BlueNodeMap<int> IntBlueNodeMap;
+    IntBlueNodeMap map(G, 42);
+    for (BlueNodeIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (BlueNodeIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (BlueNodeIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Node>(12);
+    // for (NodeIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+  template <typename Graph>
+  void checkGraphArcMap(const Graph& G) {
+    typedef typename Graph::Arc Arc;
+    typedef typename Graph::ArcIt ArcIt;
+
+    typedef typename Graph::template ArcMap<int> IntArcMap;
+    IntArcMap map(G, 42);
+    for (ArcIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (ArcIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (ArcIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Arc>(12);
+    // for (ArcIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+  template <typename Graph>
+  void checkGraphEdgeMap(const Graph& G) {
+    typedef typename Graph::Edge Edge;
+    typedef typename Graph::EdgeIt EdgeIt;
+
+    typedef typename Graph::template EdgeMap<int> IntEdgeMap;
+    IntEdgeMap map(G, 42);
+    for (EdgeIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (EdgeIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (EdgeIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Edge>(12);
+    // for (EdgeIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+
+} //namespace lemon
+
+#endif
diff --git a/test/graph_utils_test.cc b/test/graph_utils_test.cc
new file mode 100644
index 0000000..19a934a
--- /dev/null
+++ b/test/graph_utils_test.cc
@@ -0,0 +1,217 @@
+/* -*- 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 <cstdlib>
+#include <ctime>
+
+#include <lemon/random.h>
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/maps.h>
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+using namespace lemon;
+
+template <typename Digraph>
+void checkFindArcs() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  {
+    Digraph digraph;
+    for (int i = 0; i < 10; ++i) {
+      digraph.addNode();
+    }
+    RangeIdMap<Digraph, Node> nodes(digraph);
+    typename RangeIdMap<Digraph, Node>::InverseMap invNodes(nodes);
+    for (int i = 0; i < 100; ++i) {
+      int src = rnd[invNodes.size()];
+      int trg = rnd[invNodes.size()];
+      digraph.addArc(invNodes[src], invNodes[trg]);
+    }
+    typename Digraph::template ArcMap<bool> found(digraph, false);
+    RangeIdMap<Digraph, Arc> arcs(digraph);
+    for (NodeIt src(digraph); src != INVALID; ++src) {
+      for (NodeIt trg(digraph); trg != INVALID; ++trg) {
+        for (ConArcIt<Digraph> con(digraph, src, trg); con != INVALID; ++con) {
+          check(digraph.source(con) == src, "Wrong source.");
+          check(digraph.target(con) == trg, "Wrong target.");
+          check(found[con] == false, "The arc found already.");
+          found[con] = true;
+        }
+      }
+    }
+    for (ArcIt it(digraph); it != INVALID; ++it) {
+      check(found[it] == true, "The arc is not found.");
+    }
+  }
+
+  {
+    int num = 5;
+    Digraph fg;
+    std::vector<Node> nodes;
+    for (int i = 0; i < num; ++i) {
+      nodes.push_back(fg.addNode());
+    }
+    for (int i = 0; i < num * num; ++i) {
+      fg.addArc(nodes[i / num], nodes[i % num]);
+    }
+    check(countNodes(fg) == num, "Wrong node number.");
+    check(countArcs(fg) == num*num, "Wrong arc number.");
+    for (NodeIt src(fg); src != INVALID; ++src) {
+      for (NodeIt trg(fg); trg != INVALID; ++trg) {
+        ConArcIt<Digraph> con(fg, src, trg);
+        check(con != INVALID, "There is no connecting arc.");
+        check(fg.source(con) == src, "Wrong source.");
+        check(fg.target(con) == trg, "Wrong target.");
+        check(++con == INVALID, "There is more connecting arc.");
+      }
+    }
+    ArcLookUp<Digraph> al1(fg);
+    DynArcLookUp<Digraph> al2(fg);
+    AllArcLookUp<Digraph> al3(fg);
+    for (NodeIt src(fg); src != INVALID; ++src) {
+      for (NodeIt trg(fg); trg != INVALID; ++trg) {
+        Arc con1 = al1(src, trg);
+        Arc con2 = al2(src, trg);
+        Arc con3 = al3(src, trg);
+        Arc con4 = findArc(fg, src, trg);
+        check(con1 == con2 && con2 == con3 && con3 == con4,
+              "Different results.")
+        check(con1 != INVALID, "There is no connecting arc.");
+        check(fg.source(con1) == src, "Wrong source.");
+        check(fg.target(con1) == trg, "Wrong target.");
+        check(al3(src, trg, con3) == INVALID,
+              "There is more connecting arc.");
+        check(findArc(fg, src, trg, con4) == INVALID,
+              "There is more connecting arc.");
+      }
+    }
+  }
+}
+
+template <typename Graph>
+void checkFindEdges() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+  Graph graph;
+  for (int i = 0; i < 10; ++i) {
+    graph.addNode();
+  }
+  RangeIdMap<Graph, Node> nodes(graph);
+  typename RangeIdMap<Graph, Node>::InverseMap invNodes(nodes);
+  for (int i = 0; i < 100; ++i) {
+    int src = rnd[invNodes.size()];
+    int trg = rnd[invNodes.size()];
+    graph.addEdge(invNodes[src], invNodes[trg]);
+  }
+  typename Graph::template EdgeMap<int> found(graph, 0);
+  RangeIdMap<Graph, Edge> edges(graph);
+  for (NodeIt src(graph); src != INVALID; ++src) {
+    for (NodeIt trg(graph); trg != INVALID; ++trg) {
+      for (ConEdgeIt<Graph> con(graph, src, trg); con != INVALID; ++con) {
+        check( (graph.u(con) == src && graph.v(con) == trg) ||
+               (graph.v(con) == src && graph.u(con) == trg),
+               "Wrong end nodes.");
+        ++found[con];
+        check(found[con] <= 2, "The edge found more than twice.");
+      }
+    }
+  }
+  for (EdgeIt it(graph); it != INVALID; ++it) {
+    check( (graph.u(it) != graph.v(it) && found[it] == 2) ||
+           (graph.u(it) == graph.v(it) && found[it] == 1),
+           "The edge is not found correctly.");
+  }
+}
+
+template <class Digraph>
+void checkDeg()
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  const int nodeNum = 10;
+  const int arcNum = 100;
+  Digraph digraph;
+  InDegMap<Digraph> inDeg(digraph);
+  OutDegMap<Digraph> outDeg(digraph);
+  std::vector<Node> nodes(nodeNum);
+  for (int i = 0; i < nodeNum; ++i) {
+    nodes[i] = digraph.addNode();
+  }
+  std::vector<Arc> arcs(arcNum);
+  for (int i = 0; i < arcNum; ++i) {
+    arcs[i] = digraph.addArc(nodes[rnd[nodeNum]], nodes[rnd[nodeNum]]);
+  }
+  for (int i = 0; i < nodeNum; ++i) {
+    check(inDeg[nodes[i]] == countInArcs(digraph, nodes[i]),
+          "Wrong in degree map");
+  }
+  for (int i = 0; i < nodeNum; ++i) {
+    check(outDeg[nodes[i]] == countOutArcs(digraph, nodes[i]),
+          "Wrong out degree map");
+  }
+}
+
+template <class Digraph>
+void checkSnapDeg()
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph g;
+  Node n1=g.addNode();
+  Node n2=g.addNode();
+
+  InDegMap<Digraph> ind(g);
+
+  g.addArc(n1,n2);
+
+  typename Digraph::Snapshot snap(g);
+
+  OutDegMap<Digraph> outd(g);
+
+  check(ind[n1]==0 && ind[n2]==1, "Wrong InDegMap value.");
+  check(outd[n1]==1 && outd[n2]==0, "Wrong OutDegMap value.");
+
+  g.addArc(n1,n2);
+  g.addArc(n2,n1);
+
+  check(ind[n1]==1 && ind[n2]==2, "Wrong InDegMap value.");
+  check(outd[n1]==2 && outd[n2]==1, "Wrong OutDegMap value.");
+
+  snap.restore();
+
+  check(ind[n1]==0 && ind[n2]==1, "Wrong InDegMap value.");
+  check(outd[n1]==1 && outd[n2]==0, "Wrong OutDegMap value.");
+}
+
+int main() {
+  // Checking ConArcIt, ConEdgeIt, ArcLookUp, AllArcLookUp, and DynArcLookUp
+  checkFindArcs<ListDigraph>();
+  checkFindArcs<SmartDigraph>();
+  checkFindEdges<ListGraph>();
+  checkFindEdges<SmartGraph>();
+
+  // Checking In/OutDegMap (and Snapshot feature)
+  checkDeg<ListDigraph>();
+  checkDeg<SmartDigraph>();
+  checkSnapDeg<ListDigraph>();
+  checkSnapDeg<SmartDigraph>();
+
+  return 0;
+}
diff --git a/test/hao_orlin_test.cc b/test/hao_orlin_test.cc
new file mode 100644
index 0000000..c245cb7
--- /dev/null
+++ b/test/hao_orlin_test.cc
@@ -0,0 +1,164 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <sstream>
+
+#include <lemon/smart_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/hao_orlin.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace std;
+
+const std::string lgf =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@edges\n"
+  "     cap1 cap2 cap3\n"
+  "0 1  1    1    1   \n"
+  "0 2  2    2    4   \n"
+  "1 2  4    4    4   \n"
+  "3 4  1    1    1   \n"
+  "3 5  2    2    4   \n"
+  "4 5  4    4    4   \n"
+  "5 4  4    4    4   \n"
+  "2 3  1    6    6   \n"
+  "4 0  1    6    6   \n";
+
+void checkHaoOrlinCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc, Value> CapMap;
+  typedef concepts::WriteMap<Node, bool> CutMap;
+
+  Digraph g;
+  Node n;
+  CapMap cap;
+  CutMap cut;
+  Value v;
+  ::lemon::ignore_unused_variable_warning(v);
+
+  HaoOrlin<Digraph, CapMap> ho_test(g, cap);
+  const HaoOrlin<Digraph, CapMap>&
+    const_ho_test = ho_test;
+
+  ho_test.init();
+  ho_test.init(n);
+  ho_test.calculateOut();
+  ho_test.calculateIn();
+  ho_test.run();
+  ho_test.run(n);
+
+  v = const_ho_test.minCutValue();
+  v = const_ho_test.minCutMap(cut);
+}
+
+template <typename Graph, typename CapMap, typename CutMap>
+typename CapMap::Value
+  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
+{
+  typename CapMap::Value sum = 0;
+  for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
+    if (cut[graph.source(a)] && !cut[graph.target(a)])
+      sum += cap[a];
+  }
+  return sum;
+}
+
+int main() {
+  SmartDigraph graph;
+  SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
+  SmartDigraph::NodeMap<bool> cut(graph);
+
+  istringstream input(lgf);
+  digraphReader(graph, input)
+    .arcMap("cap1", cap1)
+    .arcMap("cap2", cap2)
+    .arcMap("cap3", cap3)
+    .run();
+
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap1);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap2);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap3);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
+  }
+
+  typedef Undirector<SmartDigraph> UGraph;
+  UGraph ugraph(graph);
+
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 2, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 5, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 5, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
+  }
+
+  return 0;
+}
diff --git a/test/heap_test.cc b/test/heap_test.cc
new file mode 100644
index 0000000..38e1577
--- /dev/null
+++ b/test/heap_test.cc
@@ -0,0 +1,310 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include <lemon/concept_check.h>
+#include <lemon/concepts/heap.h>
+
+#include <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/dijkstra.h>
+#include <lemon/maps.h>
+
+#include <lemon/bin_heap.h>
+#include <lemon/quad_heap.h>
+#include <lemon/dheap.h>
+#include <lemon/fib_heap.h>
+#include <lemon/pairing_heap.h>
+#include <lemon/radix_heap.h>
+#include <lemon/binomial_heap.h>
+#include <lemon/bucket_heap.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace lemon::concepts;
+
+typedef ListDigraph Digraph;
+DIGRAPH_TYPEDEFS(Digraph);
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "                label   capacity\n"
+  "0       5       0       94\n"
+  "3       9       1       11\n"
+  "8       7       2       83\n"
+  "1       2       3       94\n"
+  "5       7       4       35\n"
+  "7       4       5       84\n"
+  "9       5       6       38\n"
+  "0       4       7       96\n"
+  "6       7       8       6\n"
+  "3       1       9       27\n"
+  "5       2       10      77\n"
+  "5       6       11      69\n"
+  "6       5       12      41\n"
+  "4       6       13      70\n"
+  "3       2       14      45\n"
+  "7       9       15      93\n"
+  "5       9       16      50\n"
+  "9       0       17      94\n"
+  "9       6       18      67\n"
+  "0       9       19      86\n"
+  "@attributes\n"
+  "source 3\n";
+
+int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
+int test_inc[] = {20, 28, 34, 16,  0, 46, 44,  0, 42, 32, 14,  8,  6, 37};
+
+int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
+
+template <typename Heap>
+void heapSortTest() {
+  RangeMap<int> map(test_len, -1);
+  Heap heap(map);
+
+  std::vector<int> v(test_len);
+  for (int i = 0; i < test_len; ++i) {
+    v[i] = test_seq[i];
+    heap.push(i, v[i]);
+  }
+  std::sort(v.begin(), v.end());
+  for (int i = 0; i < test_len; ++i) {
+    check(v[i] == heap.prio(), "Wrong order in heap sort.");
+    heap.pop();
+  }
+}
+
+template <typename Heap>
+void heapIncreaseTest() {
+  RangeMap<int> map(test_len, -1);
+
+  Heap heap(map);
+
+  std::vector<int> v(test_len);
+  for (int i = 0; i < test_len; ++i) {
+    v[i] = test_seq[i];
+    heap.push(i, v[i]);
+  }
+  for (int i = 0; i < test_len; ++i) {
+    v[i] += test_inc[i];
+    heap.increase(i, v[i]);
+  }
+  std::sort(v.begin(), v.end());
+  for (int i = 0; i < test_len; ++i) {
+    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
+    heap.pop();
+  }
+}
+
+template <typename Heap>
+void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
+                      Node source) {
+
+  typename Dijkstra<Digraph, IntArcMap>::template SetStandardHeap<Heap>::
+    Create dijkstra(digraph, length);
+
+  dijkstra.run(source);
+
+  for(ArcIt a(digraph); a != INVALID; ++a) {
+    Node s = digraph.source(a);
+    Node t = digraph.target(a);
+    if (dijkstra.reached(s)) {
+      check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
+             "Error in shortest path tree.");
+    }
+  }
+
+  for(NodeIt n(digraph); n != INVALID; ++n) {
+    if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) {
+      Arc a = dijkstra.predArc(n);
+      Node s = digraph.source(a);
+      check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
+             "Error in shortest path tree.");
+    }
+  }
+
+}
+
+int main() {
+
+  typedef int Item;
+  typedef int Prio;
+  typedef RangeMap<int> ItemIntMap;
+
+  Digraph digraph;
+  IntArcMap length(digraph);
+  Node source;
+
+  std::istringstream input(test_lgf);
+  digraphReader(digraph, input).
+    arcMap("capacity", length).
+    node("source", source).
+    run();
+
+  // BinHeap
+  {
+    typedef BinHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BinHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // QuadHeap
+  {
+    typedef QuadHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // DHeap
+  {
+    typedef DHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef DHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // FibHeap
+  {
+    typedef FibHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // PairingHeap
+  {
+    typedef PairingHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // RadixHeap
+  {
+    typedef RadixHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef RadixHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // BinomialHeap
+  {
+    typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // BucketHeap, SimpleBucketHeap
+  {
+    typedef BucketHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BucketHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+
+    typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
+    heapSortTest<SimpleIntHeap>();
+  }
+
+  {
+    typedef FibHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  {
+    typedef RadixHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef RadixHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  {
+    typedef BucketHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BucketHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+
+  return 0;
+}
diff --git a/test/kruskal_test.cc b/test/kruskal_test.cc
new file mode 100644
index 0000000..af36c72
--- /dev/null
+++ b/test/kruskal_test.cc
@@ -0,0 +1,147 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <vector>
+
+#include "test_tools.h"
+#include <lemon/maps.h>
+#include <lemon/kruskal.h>
+#include <lemon/list_graph.h>
+
+#include <lemon/concepts/maps.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+
+using namespace std;
+using namespace lemon;
+
+void checkCompileKruskal()
+{
+  concepts::WriteMap<concepts::Digraph::Arc,bool> w;
+  concepts::WriteMap<concepts::Graph::Edge,bool> uw;
+
+  concepts::ReadMap<concepts::Digraph::Arc,int> r;
+  concepts::ReadMap<concepts::Graph::Edge,int> ur;
+
+  concepts::Digraph g;
+  concepts::Graph ug;
+
+  kruskal(g, r, w);
+  kruskal(ug, ur, uw);
+
+  std::vector<std::pair<concepts::Digraph::Arc, int> > rs;
+  std::vector<std::pair<concepts::Graph::Edge, int> > urs;
+
+  kruskal(g, rs, w);
+  kruskal(ug, urs, uw);
+
+  std::vector<concepts::Digraph::Arc> ws;
+  std::vector<concepts::Graph::Edge> uws;
+
+  kruskal(g, r, ws.begin());
+  kruskal(ug, ur, uws.begin());
+}
+
+int main() {
+
+  typedef ListGraph::Node Node;
+  typedef ListGraph::Edge Edge;
+  typedef ListGraph::NodeIt NodeIt;
+  typedef ListGraph::ArcIt ArcIt;
+
+  ListGraph G;
+
+  Node s=G.addNode();
+  Node v1=G.addNode();
+  Node v2=G.addNode();
+  Node v3=G.addNode();
+  Node v4=G.addNode();
+  Node t=G.addNode();
+
+  Edge e1 = G.addEdge(s, v1);
+  Edge e2 = G.addEdge(s, v2);
+  Edge e3 = G.addEdge(v1, v2);
+  Edge e4 = G.addEdge(v2, v1);
+  Edge e5 = G.addEdge(v1, v3);
+  Edge e6 = G.addEdge(v3, v2);
+  Edge e7 = G.addEdge(v2, v4);
+  Edge e8 = G.addEdge(v4, v3);
+  Edge e9 = G.addEdge(v3, t);
+  Edge e10 = G.addEdge(v4, t);
+
+  typedef ListGraph::EdgeMap<int> ECostMap;
+  typedef ListGraph::EdgeMap<bool> EBoolMap;
+
+  ECostMap edge_cost_map(G, 2);
+  EBoolMap tree_map(G);
+
+
+  //Test with const map.
+  check(kruskal(G, ConstMap<ListGraph::Edge,int>(2), tree_map)==10,
+        "Total cost should be 10");
+  //Test with an edge map (filled with uniform costs).
+  check(kruskal(G, edge_cost_map, tree_map)==10,
+        "Total cost should be 10");
+
+  edge_cost_map[e1] = -10;
+  edge_cost_map[e2] = -9;
+  edge_cost_map[e3] = -8;
+  edge_cost_map[e4] = -7;
+  edge_cost_map[e5] = -6;
+  edge_cost_map[e6] = -5;
+  edge_cost_map[e7] = -4;
+  edge_cost_map[e8] = -3;
+  edge_cost_map[e9] = -2;
+  edge_cost_map[e10] = -1;
+
+  vector<Edge> tree_edge_vec(5);
+
+  //Test with a edge map and inserter.
+  check(kruskal(G, edge_cost_map,
+                 tree_edge_vec.begin())
+        ==-31,
+        "Total cost should be -31.");
+
+  tree_edge_vec.clear();
+
+  check(kruskal(G, edge_cost_map,
+                back_inserter(tree_edge_vec))
+        ==-31,
+        "Total cost should be -31.");
+
+//   tree_edge_vec.clear();
+
+//   //The above test could also be coded like this:
+//   check(kruskal(G,
+//                 makeKruskalMapInput(G, edge_cost_map),
+//                 makeKruskalSequenceOutput(back_inserter(tree_edge_vec)))
+//         ==-31,
+//         "Total cost should be -31.");
+
+  check(tree_edge_vec.size()==5,"The tree should have 5 edges.");
+
+  check(tree_edge_vec[0]==e1 &&
+        tree_edge_vec[1]==e2 &&
+        tree_edge_vec[2]==e5 &&
+        tree_edge_vec[3]==e7 &&
+        tree_edge_vec[4]==e9,
+        "Wrong tree.");
+
+  return 0;
+}
diff --git a/test/lgf_reader_writer_test.cc b/test/lgf_reader_writer_test.cc
new file mode 100644
index 0000000..25d9423
--- /dev/null
+++ b/test/lgf_reader_writer_test.cc
@@ -0,0 +1,578 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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 <string>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/bpgraph.h>
+
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+
+#include "test_tools.h"
+
+struct ReaderConverter {
+  int operator()(const std::string& str) const {
+    return str.length();
+  }
+};
+
+struct WriterConverter {
+  std::string operator()(int value) const {
+    return std::string(value, '*');
+  }
+};
+
+void checkDigraphReaderCompile() {
+  typedef lemon::concepts::ExtendableDigraphComponent<
+    lemon::concepts::Digraph> Digraph;
+  Digraph digraph;
+  Digraph::NodeMap<int> node_map(digraph);
+  Digraph::ArcMap<int> arc_map(digraph);
+  Digraph::Node node;
+  Digraph::Arc arc;
+  int attr;
+
+  lemon::DigraphReader<Digraph> reader(digraph, "filename");
+  reader.nodeMap("node_map", node_map);
+  reader.nodeMap("node_map", node_map, ReaderConverter());
+  reader.arcMap("arc_map", arc_map);
+  reader.arcMap("arc_map", arc_map, ReaderConverter());
+  reader.attribute("attr", attr);
+  reader.attribute("attr", attr, ReaderConverter());
+  reader.node("node", node);
+  reader.arc("arc", arc);
+
+  reader.nodes("alt_nodes_caption");
+  reader.arcs("alt_arcs_caption");
+  reader.attributes("alt_attrs_caption");
+
+  reader.useNodes(node_map);
+  reader.useNodes(node_map, WriterConverter());
+  reader.useArcs(arc_map);
+  reader.useArcs(arc_map, WriterConverter());
+
+  reader.skipNodes();
+  reader.skipArcs();
+
+  reader.run();
+
+  lemon::DigraphReader<Digraph> reader2(digraph, std::cin);
+}
+
+void checkDigraphWriterCompile() {
+  typedef lemon::concepts::Digraph Digraph;
+  Digraph digraph;
+  Digraph::NodeMap<int> node_map(digraph);
+  Digraph::ArcMap<int> arc_map(digraph);
+  Digraph::Node node;
+  Digraph::Arc arc;
+  int attr;
+
+  lemon::DigraphWriter<Digraph> writer(digraph, "filename");
+  writer.nodeMap("node_map", node_map);
+  writer.nodeMap("node_map", node_map, WriterConverter());
+  writer.arcMap("arc_map", arc_map);
+  writer.arcMap("arc_map", arc_map, WriterConverter());
+  writer.attribute("attr", attr);
+  writer.attribute("attr", attr, WriterConverter());
+  writer.node("node", node);
+  writer.arc("arc", arc);
+
+  writer.nodes("alt_nodes_caption");
+  writer.arcs("alt_arcs_caption");
+  writer.attributes("alt_attrs_caption");
+
+  writer.skipNodes();
+  writer.skipArcs();
+
+  writer.run();
+}
+
+void checkGraphReaderCompile() {
+  typedef lemon::concepts::ExtendableGraphComponent<
+    lemon::concepts::Graph> Graph;
+  Graph graph;
+  Graph::NodeMap<int> node_map(graph);
+  Graph::ArcMap<int> arc_map(graph);
+  Graph::EdgeMap<int> edge_map(graph);
+  Graph::Node node;
+  Graph::Arc arc;
+  Graph::Edge edge;
+  int attr;
+
+  lemon::GraphReader<Graph> reader(graph, "filename");
+  reader.nodeMap("node_map", node_map);
+  reader.nodeMap("node_map", node_map, ReaderConverter());
+  reader.arcMap("arc_map", arc_map);
+  reader.arcMap("arc_map", arc_map, ReaderConverter());
+  reader.edgeMap("edge_map", edge_map);
+  reader.edgeMap("edge_map", edge_map, ReaderConverter());
+  reader.attribute("attr", attr);
+  reader.attribute("attr", attr, ReaderConverter());
+  reader.node("node", node);
+  reader.arc("arc", arc);
+
+  reader.nodes("alt_nodes_caption");
+  reader.edges("alt_edges_caption");
+  reader.attributes("alt_attrs_caption");
+
+  reader.useNodes(node_map);
+  reader.useNodes(node_map, WriterConverter());
+  reader.useEdges(edge_map);
+  reader.useEdges(edge_map, WriterConverter());
+
+  reader.skipNodes();
+  reader.skipEdges();
+
+  reader.run();
+
+  lemon::GraphReader<Graph> reader2(graph, std::cin);
+}
+
+void checkGraphWriterCompile() {
+  typedef lemon::concepts::Graph Graph;
+  Graph graph;
+  Graph::NodeMap<int> node_map(graph);
+  Graph::ArcMap<int> arc_map(graph);
+  Graph::EdgeMap<int> edge_map(graph);
+  Graph::Node node;
+  Graph::Arc arc;
+  Graph::Edge edge;
+  int attr;
+
+  lemon::GraphWriter<Graph> writer(graph, "filename");
+  writer.nodeMap("node_map", node_map);
+  writer.nodeMap("node_map", node_map, WriterConverter());
+  writer.arcMap("arc_map", arc_map);
+  writer.arcMap("arc_map", arc_map, WriterConverter());
+  writer.edgeMap("edge_map", edge_map);
+  writer.edgeMap("edge_map", edge_map, WriterConverter());
+  writer.attribute("attr", attr);
+  writer.attribute("attr", attr, WriterConverter());
+  writer.node("node", node);
+  writer.arc("arc", arc);
+  writer.edge("edge", edge);
+
+  writer.nodes("alt_nodes_caption");
+  writer.edges("alt_edges_caption");
+  writer.attributes("alt_attrs_caption");
+
+  writer.skipNodes();
+  writer.skipEdges();
+
+  writer.run();
+
+  lemon::GraphWriter<Graph> writer2(graph, std::cout);
+}
+
+void checkBpGraphReaderCompile() {
+  typedef lemon::concepts::ExtendableBpGraphComponent<
+    lemon::concepts::BpGraph> BpGraph;
+  BpGraph graph;
+  BpGraph::NodeMap<int> node_map(graph);
+  BpGraph::RedNodeMap<int> red_node_map(graph);
+  BpGraph::BlueNodeMap<int> blue_node_map(graph);
+  BpGraph::ArcMap<int> arc_map(graph);
+  BpGraph::EdgeMap<int> edge_map(graph);
+  BpGraph::Node node;
+  BpGraph::RedNode red_node;
+  BpGraph::BlueNode blue_node;
+  BpGraph::Arc arc;
+  BpGraph::Edge edge;
+  int attr;
+
+  lemon::BpGraphReader<BpGraph> reader(graph, "filename");
+  reader.nodeMap("node_map", node_map);
+  reader.nodeMap("node_map", node_map, ReaderConverter());
+  reader.redNodeMap("red_node_map", red_node_map);
+  reader.redNodeMap("red_node_map", red_node_map, ReaderConverter());
+  reader.blueNodeMap("blue_node_map", blue_node_map);
+  reader.blueNodeMap("blue_node_map", blue_node_map, ReaderConverter());
+  reader.arcMap("arc_map", arc_map);
+  reader.arcMap("arc_map", arc_map, ReaderConverter());
+  reader.edgeMap("edge_map", edge_map);
+  reader.edgeMap("edge_map", edge_map, ReaderConverter());
+  reader.attribute("attr", attr);
+  reader.attribute("attr", attr, ReaderConverter());
+  reader.node("node", node);
+  reader.redNode("red_node", red_node);
+  reader.blueNode("blue_node", blue_node);
+  reader.arc("arc", arc);
+
+  reader.nodes("alt_nodes_caption");
+  reader.edges("alt_edges_caption");
+  reader.attributes("alt_attrs_caption");
+
+  reader.useNodes(node_map);
+  reader.useNodes(node_map, WriterConverter());
+  reader.useEdges(edge_map);
+  reader.useEdges(edge_map, WriterConverter());
+
+  reader.skipNodes();
+  reader.skipEdges();
+
+  reader.run();
+
+  lemon::BpGraphReader<BpGraph> reader2(graph, std::cin);
+}
+
+void checkBpGraphWriterCompile() {
+  typedef lemon::concepts::BpGraph BpGraph;
+  BpGraph graph;
+  BpGraph::NodeMap<int> node_map(graph);
+  BpGraph::RedNodeMap<int> red_node_map(graph);
+  BpGraph::BlueNodeMap<int> blue_node_map(graph);
+  BpGraph::ArcMap<int> arc_map(graph);
+  BpGraph::EdgeMap<int> edge_map(graph);
+  BpGraph::Node node;
+  BpGraph::RedNode red_node;
+  BpGraph::BlueNode blue_node;
+  BpGraph::Arc arc;
+  BpGraph::Edge edge;
+  int attr;
+
+  lemon::BpGraphWriter<BpGraph> writer(graph, "filename");
+  writer.nodeMap("node_map", node_map);
+  writer.nodeMap("node_map", node_map, WriterConverter());
+  writer.redNodeMap("red_node_map", red_node_map);
+  writer.redNodeMap("red_node_map", red_node_map, WriterConverter());
+  writer.blueNodeMap("blue_node_map", blue_node_map);
+  writer.blueNodeMap("blue_node_map", blue_node_map, WriterConverter());
+  writer.arcMap("arc_map", arc_map);
+  writer.arcMap("arc_map", arc_map, WriterConverter());
+  writer.edgeMap("edge_map", edge_map);
+  writer.edgeMap("edge_map", edge_map, WriterConverter());
+  writer.attribute("attr", attr);
+  writer.attribute("attr", attr, WriterConverter());
+  writer.node("node", node);
+  writer.redNode("red_node", red_node);
+  writer.blueNode("blue_node", blue_node);
+  writer.arc("arc", arc);
+
+  writer.nodes("alt_nodes_caption");
+  writer.edges("alt_edges_caption");
+  writer.attributes("alt_attrs_caption");
+
+  writer.skipNodes();
+  writer.skipEdges();
+
+  writer.run();
+
+  lemon::BpGraphWriter<BpGraph> writer2(graph, std::cout);
+}
+
+void checkDigraphReaderWriter() {
+  typedef lemon::SmartDigraph Digraph;
+  Digraph digraph;
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n2, n3);
+
+  Digraph::NodeMap<int> node_map(digraph);
+  node_map[n1] = 11;
+  node_map[n2] = 12;
+  node_map[n3] = 13;
+
+  Digraph::ArcMap<int> arc_map(digraph);
+  arc_map[a1] = 21;
+  arc_map[a2] = 22;
+
+  int attr = 100;
+
+  std::ostringstream os;
+  lemon::DigraphWriter<Digraph> writer(digraph, os);
+
+  writer.nodeMap("node_map1", node_map);
+  writer.nodeMap("node_map2", node_map, WriterConverter());
+  writer.arcMap("arc_map1", arc_map);
+  writer.arcMap("arc_map2", arc_map, WriterConverter());
+  writer.node("node", n2);
+  writer.arc("arc", a1);
+  writer.attribute("attr1", attr);
+  writer.attribute("attr2", attr, WriterConverter());
+
+  writer.run();
+
+  typedef lemon::ListDigraph ExpDigraph;
+  ExpDigraph exp_digraph;
+  ExpDigraph::NodeMap<int> exp_node_map1(exp_digraph);
+  ExpDigraph::NodeMap<int> exp_node_map2(exp_digraph);
+  ExpDigraph::ArcMap<int> exp_arc_map1(exp_digraph);
+  ExpDigraph::ArcMap<int> exp_arc_map2(exp_digraph);
+  ExpDigraph::Node exp_n2;
+  ExpDigraph::Arc exp_a1;
+  int exp_attr1;
+  int exp_attr2;
+
+  std::istringstream is(os.str());
+  lemon::DigraphReader<ExpDigraph> reader(exp_digraph, is);
+
+  reader.nodeMap("node_map1", exp_node_map1);
+  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
+  reader.arcMap("arc_map1", exp_arc_map1);
+  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
+  reader.node("node", exp_n2);
+  reader.arc("arc", exp_a1);
+  reader.attribute("attr1", exp_attr1);
+  reader.attribute("attr2", exp_attr2, ReaderConverter());
+
+  reader.run();
+
+  check(lemon::countNodes(exp_digraph) == 3, "Wrong number of nodes");
+  check(lemon::countArcs(exp_digraph) == 2, "Wrong number of arcs");
+  check(exp_node_map1[exp_n2] == 12, "Wrong map value");
+  check(exp_node_map2[exp_n2] == 12, "Wrong map value");
+  check(exp_arc_map1[exp_a1] == 21, "Wrong map value");
+  check(exp_arc_map2[exp_a1] == 21, "Wrong map value");
+  check(exp_attr1 == 100, "Wrong attr value");
+  check(exp_attr2 == 100, "Wrong attr value");
+}
+
+void checkGraphReaderWriter() {
+  typedef lemon::SmartGraph Graph;
+  Graph graph;
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Graph::Node n3 = graph.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n2, n3);
+
+  Graph::NodeMap<int> node_map(graph);
+  node_map[n1] = 11;
+  node_map[n2] = 12;
+  node_map[n3] = 13;
+
+  Graph::EdgeMap<int> edge_map(graph);
+  edge_map[e1] = 21;
+  edge_map[e2] = 22;
+
+  Graph::ArcMap<int> arc_map(graph);
+  arc_map[graph.direct(e1, true)] = 211;
+  arc_map[graph.direct(e1, false)] = 212;
+  arc_map[graph.direct(e2, true)] = 221;
+  arc_map[graph.direct(e2, false)] = 222;
+
+  int attr = 100;
+
+  std::ostringstream os;
+  lemon::GraphWriter<Graph> writer(graph, os);
+
+  writer.nodeMap("node_map1", node_map);
+  writer.nodeMap("node_map2", node_map, WriterConverter());
+  writer.edgeMap("edge_map1", edge_map);
+  writer.edgeMap("edge_map2", edge_map, WriterConverter());
+  writer.arcMap("arc_map1", arc_map);
+  writer.arcMap("arc_map2", arc_map, WriterConverter());
+  writer.node("node", n2);
+  writer.edge("edge", e1);
+  writer.arc("arc", graph.direct(e1, false));
+  writer.attribute("attr1", attr);
+  writer.attribute("attr2", attr, WriterConverter());
+
+  writer.run();
+
+  typedef lemon::ListGraph ExpGraph;
+  ExpGraph exp_graph;
+  ExpGraph::NodeMap<int> exp_node_map1(exp_graph);
+  ExpGraph::NodeMap<int> exp_node_map2(exp_graph);
+  ExpGraph::EdgeMap<int> exp_edge_map1(exp_graph);
+  ExpGraph::EdgeMap<int> exp_edge_map2(exp_graph);
+  ExpGraph::ArcMap<int> exp_arc_map1(exp_graph);
+  ExpGraph::ArcMap<int> exp_arc_map2(exp_graph);
+  ExpGraph::Node exp_n2;
+  ExpGraph::Edge exp_e1;
+  ExpGraph::Arc exp_a1;
+  int exp_attr1;
+  int exp_attr2;
+
+  std::istringstream is(os.str());
+  lemon::GraphReader<ExpGraph> reader(exp_graph, is);
+
+  reader.nodeMap("node_map1", exp_node_map1);
+  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
+  reader.edgeMap("edge_map1", exp_edge_map1);
+  reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter());
+  reader.arcMap("arc_map1", exp_arc_map1);
+  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
+  reader.node("node", exp_n2);
+  reader.edge("edge", exp_e1);
+  reader.arc("arc", exp_a1);
+  reader.attribute("attr1", exp_attr1);
+  reader.attribute("attr2", exp_attr2, ReaderConverter());
+
+  reader.run();
+
+  check(lemon::countNodes(exp_graph) == 3, "Wrong number of nodes");
+  check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges");
+  check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs");
+  check(exp_node_map1[exp_n2] == 12, "Wrong map value");
+  check(exp_node_map2[exp_n2] == 12, "Wrong map value");
+  check(exp_edge_map1[exp_e1] == 21, "Wrong map value");
+  check(exp_edge_map2[exp_e1] == 21, "Wrong map value");
+  check(exp_arc_map1[exp_a1] == 212, "Wrong map value");
+  check(exp_arc_map2[exp_a1] == 212, "Wrong map value");
+  check(exp_attr1 == 100, "Wrong attr value");
+  check(exp_attr2 == 100, "Wrong attr value");
+}
+
+void checkBpGraphReaderWriter() {
+  typedef lemon::SmartBpGraph Graph;
+  Graph graph;
+  Graph::RedNode rn1 = graph.addRedNode();
+  Graph::RedNode rn2 = graph.addRedNode();
+  Graph::RedNode rn3 = graph.addRedNode();
+  Graph::BlueNode bn1 = graph.addBlueNode();
+  Graph::BlueNode bn2 = graph.addBlueNode();
+  Graph::Node n = bn1;
+
+  Graph::Edge e1 = graph.addEdge(rn1, bn1);
+  Graph::Edge e2 = graph.addEdge(rn2, bn1);
+
+  Graph::NodeMap<int> node_map(graph);
+  node_map[rn1] = 11;
+  node_map[rn2] = 12;
+  node_map[rn3] = 13;
+  node_map[bn1] = 14;
+  node_map[bn2] = 15;
+
+  Graph::NodeMap<int> red_node_map(graph);
+  red_node_map[rn1] = 411;
+  red_node_map[rn2] = 412;
+  red_node_map[rn3] = 413;
+
+  Graph::NodeMap<int> blue_node_map(graph);
+  blue_node_map[bn1] = 414;
+  blue_node_map[bn2] = 415;
+
+  Graph::EdgeMap<int> edge_map(graph);
+  edge_map[e1] = 21;
+  edge_map[e2] = 22;
+
+  Graph::ArcMap<int> arc_map(graph);
+  arc_map[graph.direct(e1, true)] = 211;
+  arc_map[graph.direct(e1, false)] = 212;
+  arc_map[graph.direct(e2, true)] = 221;
+  arc_map[graph.direct(e2, false)] = 222;
+
+  int attr = 100;
+
+  std::ostringstream os;
+  lemon::BpGraphWriter<Graph> writer(graph, os);
+
+  writer.nodeMap("node_map1", node_map);
+  writer.nodeMap("node_map2", node_map, WriterConverter());
+  writer.nodeMap("red_node_map1", red_node_map);
+  writer.nodeMap("red_node_map2", red_node_map, WriterConverter());
+  writer.nodeMap("blue_node_map1", blue_node_map);
+  writer.nodeMap("blue_node_map2", blue_node_map, WriterConverter());
+  writer.edgeMap("edge_map1", edge_map);
+  writer.edgeMap("edge_map2", edge_map, WriterConverter());
+  writer.arcMap("arc_map1", arc_map);
+  writer.arcMap("arc_map2", arc_map, WriterConverter());
+  writer.node("node", n);
+  writer.redNode("red_node", rn1);
+  writer.blueNode("blue_node", bn2);
+  writer.edge("edge", e1);
+  writer.arc("arc", graph.direct(e1, false));
+  writer.attribute("attr1", attr);
+  writer.attribute("attr2", attr, WriterConverter());
+
+  writer.run();
+
+  typedef lemon::ListBpGraph ExpGraph;
+  ExpGraph exp_graph;
+  ExpGraph::NodeMap<int> exp_node_map1(exp_graph);
+  ExpGraph::NodeMap<int> exp_node_map2(exp_graph);
+  ExpGraph::RedNodeMap<int> exp_red_node_map1(exp_graph);
+  ExpGraph::RedNodeMap<int> exp_red_node_map2(exp_graph);
+  ExpGraph::BlueNodeMap<int> exp_blue_node_map1(exp_graph);
+  ExpGraph::BlueNodeMap<int> exp_blue_node_map2(exp_graph);
+  ExpGraph::EdgeMap<int> exp_edge_map1(exp_graph);
+  ExpGraph::EdgeMap<int> exp_edge_map2(exp_graph);
+  ExpGraph::ArcMap<int> exp_arc_map1(exp_graph);
+  ExpGraph::ArcMap<int> exp_arc_map2(exp_graph);
+  ExpGraph::Node exp_n;
+  ExpGraph::RedNode exp_rn1;
+  ExpGraph::BlueNode exp_bn2;
+  ExpGraph::Edge exp_e1;
+  ExpGraph::Arc exp_a1;
+  int exp_attr1;
+  int exp_attr2;
+
+  std::istringstream is(os.str());
+  lemon::BpGraphReader<ExpGraph> reader(exp_graph, is);
+
+  reader.nodeMap("node_map1", exp_node_map1);
+  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
+  reader.redNodeMap("red_node_map1", exp_red_node_map1);
+  reader.redNodeMap("red_node_map2", exp_red_node_map2, ReaderConverter());
+  reader.blueNodeMap("blue_node_map1", exp_blue_node_map1);
+  reader.blueNodeMap("blue_node_map2", exp_blue_node_map2, ReaderConverter());
+  reader.edgeMap("edge_map1", exp_edge_map1);
+  reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter());
+  reader.arcMap("arc_map1", exp_arc_map1);
+  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
+  reader.node("node", exp_n);
+  reader.redNode("red_node", exp_rn1);
+  reader.blueNode("blue_node", exp_bn2);
+  reader.edge("edge", exp_e1);
+  reader.arc("arc", exp_a1);
+  reader.attribute("attr1", exp_attr1);
+  reader.attribute("attr2", exp_attr2, ReaderConverter());
+
+  reader.run();
+
+  check(lemon::countNodes(exp_graph) == 5, "Wrong number of nodes");
+  check(lemon::countRedNodes(exp_graph) == 3, "Wrong number of red nodes");
+  check(lemon::countBlueNodes(exp_graph) == 2, "Wrong number of blue nodes");
+  check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges");
+  check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs");
+  check(exp_node_map1[exp_n] == 14, "Wrong map value");
+  check(exp_node_map2[exp_n] == 14, "Wrong map value");
+  check(exp_red_node_map1[exp_rn1] == 411, "Wrong map value");
+  check(exp_red_node_map2[exp_rn1] == 411, "Wrong map value");
+  check(exp_blue_node_map1[exp_bn2] == 415, "Wrong map value");
+  check(exp_blue_node_map2[exp_bn2] == 415, "Wrong map value");
+  check(exp_edge_map1[exp_e1] == 21, "Wrong map value");
+  check(exp_edge_map2[exp_e1] == 21, "Wrong map value");
+  check(exp_arc_map1[exp_a1] == 212, "Wrong map value");
+  check(exp_arc_map2[exp_a1] == 212, "Wrong map value");
+  check(exp_attr1 == 100, "Wrong attr value");
+  check(exp_attr2 == 100, "Wrong attr value");
+}
+
+
+int main() {
+  { // Check digrpah
+    checkDigraphReaderWriter();
+  }
+  { // Check graph
+    checkGraphReaderWriter();
+  }
+  { // Check bipartite graph
+    checkBpGraphReaderWriter();
+  }
+  return 0;
+}
diff --git a/test/lgf_test.cc b/test/lgf_test.cc
new file mode 100644
index 0000000..839afb1
--- /dev/null
+++ b/test/lgf_test.cc
@@ -0,0 +1,169 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     label\n"
+  "0 1  0\n"
+  "1 0  1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 1\n";
+
+char test_lgf_nomap[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     -\n"
+  "0 1\n";
+
+char test_lgf_bad1[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     - another\n"
+  "0 1\n";
+
+char test_lgf_bad2[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     label -\n"
+  "0 1\n";
+
+
+int main()
+{
+  {
+    ListDigraph d;
+    ListDigraph::Node s,t;
+    ListDigraph::ArcMap<int> label(d);
+    std::istringstream input(test_lgf);
+    digraphReader(d, input).
+      node("source", s).
+      node("target", t).
+      arcMap("label", label).
+      run();
+    check(countNodes(d) == 2,"There should be 2 nodes");
+    check(countArcs(d) == 2,"There should be 2 arcs");
+  }
+  {
+    ListGraph g;
+    ListGraph::Node s,t;
+    ListGraph::EdgeMap<int> label(g);
+    std::istringstream input(test_lgf);
+    graphReader(g, input).
+      node("source", s).
+      node("target", t).
+      edgeMap("label", label).
+      run();
+    check(countNodes(g) == 2,"There should be 2 nodes");
+    check(countEdges(g) == 2,"There should be 2 arcs");
+  }
+
+  {
+    ListDigraph d;
+    std::istringstream input(test_lgf_nomap);
+    digraphReader(d, input).
+      run();
+    check(countNodes(d) == 2,"There should be 2 nodes");
+    check(countArcs(d) == 1,"There should be 1 arc");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_nomap);
+    graphReader(g, input).
+      run();
+    check(countNodes(g) == 2,"There should be 2 nodes");
+    check(countEdges(g) == 1,"There should be 1 edge");
+  }
+
+  {
+    ListDigraph d;
+    std::istringstream input(test_lgf_bad1);
+    bool ok=false;
+    try {
+      digraphReader(d, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_bad1);
+    bool ok=false;
+    try {
+      graphReader(g, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+
+  {
+    ListDigraph d;
+    std::istringstream input(test_lgf_bad2);
+    bool ok=false;
+    try {
+      digraphReader(d, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_bad2);
+    bool ok=false;
+    try {
+      graphReader(g, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+}
diff --git a/test/lp_test.cc b/test/lp_test.cc
new file mode 100644
index 0000000..914a376
--- /dev/null
+++ b/test/lp_test.cc
@@ -0,0 +1,470 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <sstream>
+#include <lemon/lp_skeleton.h>
+#include "test_tools.h"
+#include <lemon/tolerance.h>
+
+#include <lemon/config.h>
+
+#ifdef LEMON_HAVE_GLPK
+#include <lemon/glpk.h>
+#endif
+
+#ifdef LEMON_HAVE_CPLEX
+#include <lemon/cplex.h>
+#endif
+
+#ifdef LEMON_HAVE_SOPLEX
+#include <lemon/soplex.h>
+#endif
+
+#ifdef LEMON_HAVE_CLP
+#include <lemon/clp.h>
+#endif
+
+#ifdef LEMON_HAVE_LP
+#include <lemon/lp.h>
+#endif
+using namespace lemon;
+
+int countCols(LpBase & lp) {
+  int count=0;
+  for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
+  return count;
+}
+
+int countRows(LpBase & lp) {
+  int count=0;
+  for (LpBase::RowIt r(lp); r!=INVALID; ++r) ++count;
+  return count;
+}
+
+
+void lpTest(LpSolver& lp)
+{
+
+  typedef LpSolver LP;
+
+  // Test LpBase::clear()
+  check(countRows(lp)==0, "Wrong number of rows");
+  check(countCols(lp)==0, "Wrong number of cols");
+  lp.addCol(); lp.addRow(); lp.addRow();
+  check(countRows(lp)==2, "Wrong number of rows");
+  check(countCols(lp)==1, "Wrong number of cols");
+  lp.clear();
+  check(countRows(lp)==0, "Wrong number of rows");
+  check(countCols(lp)==0, "Wrong number of cols");
+  lp.addCol(); lp.addCol(); lp.addCol(); lp.addRow();
+  check(countRows(lp)==1, "Wrong number of rows");
+  check(countCols(lp)==3, "Wrong number of cols");
+  lp.clear();
+
+  std::vector<LP::Col> x(10);
+  //  for(int i=0;i<10;i++) x.push_back(lp.addCol());
+  lp.addColSet(x);
+  lp.colLowerBound(x,1);
+  lp.colUpperBound(x,1);
+  lp.colBounds(x,1,2);
+
+  std::vector<LP::Col> y(10);
+  lp.addColSet(y);
+
+  lp.colLowerBound(y,1);
+  lp.colUpperBound(y,1);
+  lp.colBounds(y,1,2);
+
+  std::map<int,LP::Col> z;
+
+  z.insert(std::make_pair(12,INVALID));
+  z.insert(std::make_pair(2,INVALID));
+  z.insert(std::make_pair(7,INVALID));
+  z.insert(std::make_pair(5,INVALID));
+
+  lp.addColSet(z);
+
+  lp.colLowerBound(z,1);
+  lp.colUpperBound(z,1);
+  lp.colBounds(z,1,2);
+
+  {
+    LP::Expr e,f,g;
+    LP::Col p1,p2,p3,p4,p5;
+    LP::Constr c;
+
+    p1=lp.addCol();
+    p2=lp.addCol();
+    p3=lp.addCol();
+    p4=lp.addCol();
+    p5=lp.addCol();
+
+    e[p1]=2;
+    *e=12;
+    e[p1]+=2;
+    *e+=12;
+    e[p1]-=2;
+    *e-=12;
+
+    e=2;
+    e=2.2;
+    e=p1;
+    e=f;
+
+    e+=2;
+    e+=2.2;
+    e+=p1;
+    e+=f;
+
+    e-=2;
+    e-=2.2;
+    e-=p1;
+    e-=f;
+
+    e*=2;
+    e*=2.2;
+    e/=2;
+    e/=2.2;
+
+    e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
+       (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
+       (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
+       2.2*f+f*2.2+f/2.2+
+       2*f+f*2+f/2+
+       2.2*p1+p1*2.2+p1/2.2+
+       2*p1+p1*2+p1/2
+       );
+
+
+    c = (e  <= f  );
+    c = (e  <= 2.2);
+    c = (e  <= 2  );
+    c = (e  <= p1 );
+    c = (2.2<= f  );
+    c = (2  <= f  );
+    c = (p1 <= f  );
+    c = (p1 <= p2 );
+    c = (p1 <= 2.2);
+    c = (p1 <= 2  );
+    c = (2.2<= p2 );
+    c = (2  <= p2 );
+
+    c = (e  >= f  );
+    c = (e  >= 2.2);
+    c = (e  >= 2  );
+    c = (e  >= p1 );
+    c = (2.2>= f  );
+    c = (2  >= f  );
+    c = (p1 >= f  );
+    c = (p1 >= p2 );
+    c = (p1 >= 2.2);
+    c = (p1 >= 2  );
+    c = (2.2>= p2 );
+    c = (2  >= p2 );
+
+    c = (e  == f  );
+    c = (e  == 2.2);
+    c = (e  == 2  );
+    c = (e  == p1 );
+    c = (2.2== f  );
+    c = (2  == f  );
+    c = (p1 == f  );
+    //c = (p1 == p2 );
+    c = (p1 == 2.2);
+    c = (p1 == 2  );
+    c = (2.2== p2 );
+    c = (2  == p2 );
+
+    c = ((2 <= e) <= 3);
+    c = ((2 <= p1) <= 3);
+
+    c = ((2 >= e) >= 3);
+    c = ((2 >= p1) >= 3);
+
+    { //Tests for #430
+      LP::Col v=lp.addCol();
+      LP::Constr c = v >= -3;
+      c = c <= 4;
+      LP::Constr c2;
+#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 3 )
+      c2 = ( -3 <= v ) <= 4;
+#else
+      c2 = -3 <= v <= 4;
+#endif
+
+    }
+
+    e[x[3]]=2;
+    e[x[3]]=4;
+    e[x[3]]=1;
+    *e=12;
+
+    lp.addRow(-LP::INF,e,23);
+    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
+    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
+
+    lp.addRow(x[1]+x[3]<=x[5]-3);
+    lp.addRow((-7<=x[1]+x[3]-12)<=3);
+    lp.addRow(x[1]<=x[5]);
+
+    std::ostringstream buf;
+
+
+    e=((p1+p2)+(p1-0.99*p2));
+    //e.prettyPrint(std::cout);
+    //(e<=2).prettyPrint(std::cout);
+    double tolerance=0.001;
+    e.simplify(tolerance);
+    buf << "Coeff. of p2 should be 0.01";
+    check(e[p2]>0, buf.str());
+
+    tolerance=0.02;
+    e.simplify(tolerance);
+    buf << "Coeff. of p2 should be 0";
+    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
+
+    //Test for clone/new
+    LP* lpnew = lp.newSolver();
+    LP* lpclone = lp.cloneSolver();
+    delete lpnew;
+    delete lpclone;
+
+  }
+
+  {
+    LP::DualExpr e,f,g;
+    LP::Row p1 = INVALID, p2 = INVALID;
+
+    e[p1]=2;
+    e[p1]+=2;
+    e[p1]-=2;
+
+    e=p1;
+    e=f;
+
+    e+=p1;
+    e+=f;
+
+    e-=p1;
+    e-=f;
+
+    e*=2;
+    e*=2.2;
+    e/=2;
+    e/=2.2;
+
+    e=((p1+p2)+(p1-p2)+
+       (p1+f)+(f+p1)+(f+g)+
+       (p1-f)+(f-p1)+(f-g)+
+       2.2*f+f*2.2+f/2.2+
+       2*f+f*2+f/2+
+       2.2*p1+p1*2.2+p1/2.2+
+       2*p1+p1*2+p1/2
+       );
+  }
+
+}
+
+void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
+                   double exp_opt) {
+  using std::string;
+  lp.solve();
+
+  std::ostringstream buf;
+  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
+
+  check(lp.primalType()==stat, buf.str());
+
+  if (stat ==  LpSolver::OPTIMAL) {
+    std::ostringstream sbuf;
+    sbuf << "Wrong optimal value (" << lp.primal() <<") with "
+         << lp.solverName() <<"\n     the right optimum is " << exp_opt;
+    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
+  }
+}
+
+void aTest(LpSolver & lp)
+{
+  typedef LpSolver LP;
+
+ //The following example is very simple
+
+  typedef LpSolver::Row Row;
+  typedef LpSolver::Col Col;
+
+
+  Col x1 = lp.addCol();
+  Col x2 = lp.addCol();
+
+
+  //Constraints
+  Row upright=lp.addRow(x1+2*x2 <=1);
+  lp.addRow(x1+x2 >=-1);
+  lp.addRow(x1-x2 <=1);
+  lp.addRow(x1-x2 >=-1);
+  //Nonnegativity of the variables
+  lp.colLowerBound(x1, 0);
+  lp.colLowerBound(x2, 0);
+  //Objective function
+  lp.obj(x1+x2);
+
+  lp.sense(lp.MAX);
+
+  //Testing the problem retrieving routines
+  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(lp.sense() == lp.MAX,"This is a maximization!");
+  check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
+  check(lp.colLowerBound(x1)==0,
+        "The lower bound for variable x1 should be 0.");
+  check(lp.colUpperBound(x1)==LpSolver::INF,
+        "The upper bound for variable x1 should be infty.");
+  check(lp.rowLowerBound(upright) == -LpSolver::INF,
+        "The lower bound for the first row should be -infty.");
+  check(lp.rowUpperBound(upright)==1,
+        "The upper bound for the first row should be 1.");
+  LpSolver::Expr e = lp.row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 2, "The second coefficient should 1.");
+
+  lp.row(upright, x1+x2 <=1);
+  e = lp.row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 1, "The second coefficient should 1.");
+
+  LpSolver::DualExpr de = lp.col(x1);
+  check(  de[upright] == 1, "The first coefficient should 1.");
+
+  LpSolver* clp = lp.cloneSolver();
+
+  //Testing the problem retrieving routines
+  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(clp->sense() == clp->MAX,"This is a maximization!");
+  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
+  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
+  check(clp->colLowerBound(x1)==0,
+        "The lower bound for variable x1 should be 0.");
+  check(clp->colUpperBound(x1)==LpSolver::INF,
+        "The upper bound for variable x1 should be infty.");
+
+  check(lp.rowLowerBound(upright)==-LpSolver::INF,
+        "The lower bound for the first row should be -infty.");
+  check(lp.rowUpperBound(upright)==1,
+        "The upper bound for the first row should be 1.");
+  e = clp->row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 1, "The second coefficient should 1.");
+
+  de = clp->col(x1);
+  check(de[upright] == 1, "The first coefficient should 1.");
+
+  delete clp;
+
+  //Maximization of x1+x2
+  //over the triangle with vertices (0,0) (0,1) (1,0)
+  double expected_opt=1;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Minimization
+  lp.sense(lp.MIN);
+  expected_opt=0;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Vertex (-1,0) instead of (0,0)
+  lp.colLowerBound(x1, -LpSolver::INF);
+  expected_opt=-1;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Erase one constraint and return to maximization
+  lp.erase(upright);
+  lp.sense(lp.MAX);
+  expected_opt=LpSolver::INF;
+  solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
+
+  //Infeasibilty
+  lp.addRow(x1+x2 <=-2);
+  solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
+
+}
+
+template<class LP>
+void cloneTest()
+{
+  //Test for clone/new
+
+  LP* lp = new LP();
+  LP* lpnew = lp->newSolver();
+  LP* lpclone = lp->cloneSolver();
+  delete lp;
+  delete lpnew;
+  delete lpclone;
+}
+
+int main()
+{
+  LpSkeleton lp_skel;
+  lpTest(lp_skel);
+
+#ifdef LEMON_HAVE_LP
+  {
+    Lp lp,lp2;
+    lpTest(lp);
+    aTest(lp2);
+    cloneTest<Lp>();
+  }
+#endif
+
+#ifdef LEMON_HAVE_GLPK
+  {
+    GlpkLp lp_glpk1,lp_glpk2;
+    lpTest(lp_glpk1);
+    aTest(lp_glpk2);
+    cloneTest<GlpkLp>();
+  }
+#endif
+
+#ifdef LEMON_HAVE_CPLEX
+  try {
+    CplexLp lp_cplex1,lp_cplex2;
+    lpTest(lp_cplex1);
+    aTest(lp_cplex2);
+    cloneTest<CplexLp>();
+  } catch (CplexEnv::LicenseError& error) {
+    check(false, error.what());
+  }
+#endif
+
+#ifdef LEMON_HAVE_SOPLEX
+  {
+    SoplexLp lp_soplex1,lp_soplex2;
+    lpTest(lp_soplex1);
+    aTest(lp_soplex2);
+    cloneTest<SoplexLp>();
+  }
+#endif
+
+#ifdef LEMON_HAVE_CLP
+  {
+    ClpLp lp_clp1,lp_clp2;
+    lpTest(lp_clp1);
+    aTest(lp_clp2);
+    cloneTest<ClpLp>();
+  }
+#endif
+
+  return 0;
+}
diff --git a/test/maps_test.cc b/test/maps_test.cc
new file mode 100644
index 0000000..5502e04
--- /dev/null
+++ b/test/maps_test.cc
@@ -0,0 +1,1022 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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 <deque>
+#include <set>
+
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/maps.h>
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/dfs.h>
+#include <algorithm>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace lemon::concepts;
+
+struct A {};
+inline bool operator<(A, A) { return true; }
+struct B {};
+
+class C {
+  int _x;
+public:
+  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; }
+};
+
+class F {
+public:
+  typedef A argument_type;
+  typedef B result_type;
+
+  B operator()(const A&) const { return B(); }
+private:
+  F& operator=(const F&);
+};
+
+int func(A) { return 3; }
+
+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;
+typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
+
+typedef ReadMap<A, bool> BoolMap;
+typedef ReadWriteMap<A, bool> BoolWriteMap;
+typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
+
+int main()
+{
+  // Map concepts
+  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
+  checkConcept<ReadMap<A,C>, ReadMap<A,C> >();
+  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
+  checkConcept<WriteMap<A,C>, WriteMap<A,C> >();
+  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
+  checkConcept<ReadWriteMap<A,C>, ReadWriteMap<A,C> >();
+  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
+  checkConcept<ReferenceMap<A,C,C&,const C&>, ReferenceMap<A,C,C&,const C&> >();
+
+  // NullMap
+  {
+    checkConcept<ReadWriteMap<A,B>, NullMap<A,B> >();
+    NullMap<A,B> map1;
+    NullMap<A,B> map2 = map1;
+    ::lemon::ignore_unused_variable_warning(map2);
+    map1 = nullMap<A,B>();
+  }
+
+  // ConstMap
+  {
+    checkConcept<ReadWriteMap<A,B>, ConstMap<A,B> >();
+    checkConcept<ReadWriteMap<A,C>, ConstMap<A,C> >();
+    ConstMap<A,B> map1;
+    ConstMap<A,B> map2 = B();
+    ConstMap<A,B> map3 = map1;
+    ::lemon::ignore_unused_variable_warning(map2,map3);
+
+    map1 = constMap<A>(B());
+    map1 = constMap<A,B>();
+    map1.setAll(B());
+    ConstMap<A,C> map4(C(1));
+    ConstMap<A,C> map5 = map4;
+    ::lemon::ignore_unused_variable_warning(map5);
+
+    map4 = constMap<A>(C(2));
+    map4.setAll(C(3));
+
+    checkConcept<ReadWriteMap<A,int>, ConstMap<A,int> >();
+    check(constMap<A>(10)[A()] == 10, "Something is wrong with ConstMap");
+
+    checkConcept<ReadWriteMap<A,int>, ConstMap<A,Const<int,10> > >();
+    ConstMap<A,Const<int,10> > map6;
+    ConstMap<A,Const<int,10> > map7 = map6;
+    map6 = constMap<A,int,10>();
+    map7 = constMap<A,Const<int,10> >();
+    check(map6[A()] == 10 && map7[A()] == 10,
+          "Something is wrong with ConstMap");
+  }
+
+  // IdentityMap
+  {
+    checkConcept<ReadMap<A,A>, IdentityMap<A> >();
+    IdentityMap<A> map1;
+    IdentityMap<A> map2 = map1;
+    ::lemon::ignore_unused_variable_warning(map2);
+
+    map1 = identityMap<A>();
+
+    checkConcept<ReadMap<double,double>, IdentityMap<double> >();
+    check(identityMap<double>()[1.0] == 1.0 &&
+          identityMap<double>()[3.14] == 3.14,
+          "Something is wrong with IdentityMap");
+  }
+
+  // RangeMap
+  {
+    checkConcept<ReferenceMap<int,B,B&,const B&>, RangeMap<B> >();
+    RangeMap<B> map1;
+    RangeMap<B> map2(10);
+    RangeMap<B> map3(10,B());
+    RangeMap<B> map4 = map1;
+    RangeMap<B> map5 = rangeMap<B>();
+    RangeMap<B> map6 = rangeMap<B>(10);
+    RangeMap<B> map7 = rangeMap(10,B());
+
+    checkConcept< ReferenceMap<int, double, double&, const double&>,
+                  RangeMap<double> >();
+    std::vector<double> v(10, 0);
+    v[5] = 100;
+    RangeMap<double> map8(v);
+    RangeMap<double> map9 = rangeMap(v);
+    check(map9.size() == 10 && map9[2] == 0 && map9[5] == 100,
+          "Something is wrong with RangeMap");
+  }
+
+  // SparseMap
+  {
+    checkConcept<ReferenceMap<A,B,B&,const B&>, SparseMap<A,B> >();
+    SparseMap<A,B> map1;
+    SparseMap<A,B> map2 = B();
+    SparseMap<A,B> map3 = sparseMap<A,B>();
+    SparseMap<A,B> map4 = sparseMap<A>(B());
+
+    checkConcept< ReferenceMap<double, int, int&, const int&>,
+                  SparseMap<double, int> >();
+    std::map<double, int> m;
+    SparseMap<double, int> map5(m);
+    SparseMap<double, int> map6(m,10);
+    SparseMap<double, int> map7 = sparseMap(m);
+    SparseMap<double, int> map8 = sparseMap(m,10);
+
+    check(map5[1.0] == 0 && map5[3.14] == 0 &&
+          map6[1.0] == 10 && map6[3.14] == 10,
+          "Something is wrong with SparseMap");
+    map5[1.0] = map6[3.14] = 100;
+    check(map5[1.0] == 100 && map5[3.14] == 0 &&
+          map6[1.0] == 10 && map6[3.14] == 100,
+          "Something is wrong with SparseMap");
+  }
+
+  // ComposeMap
+  {
+    typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
+    checkConcept<ReadMap<B,double>, CompMap>();
+    CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
+    ::lemon::ignore_unused_variable_warning(map1);
+    CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
+    ::lemon::ignore_unused_variable_warning(map2);
+
+    SparseMap<double, bool> m1(false); m1[3.14] = true;
+    RangeMap<double> m2(2); m2[0] = 3.0; m2[1] = 3.14;
+    check(!composeMap(m1,m2)[0] && composeMap(m1,m2)[1],
+          "Something is wrong with ComposeMap")
+  }
+
+  // CombineMap
+  {
+    typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
+    checkConcept<ReadMap<A,double>, CombMap>();
+    CombMap map1 = CombMap(DoubleMap(), DoubleMap());
+    ::lemon::ignore_unused_variable_warning(map1);
+    CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
+    ::lemon::ignore_unused_variable_warning(map2);
+
+    check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
+          "Something is wrong with CombineMap");
+  }
+
+  // FunctorToMap, MapToFunctor
+  {
+    checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
+    checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
+    FunctorToMap<F> map1;
+    FunctorToMap<F> map2 = FunctorToMap<F>(F());
+    ::lemon::ignore_unused_variable_warning(map2);
+
+    B b = functorToMap(F())[A()];
+    ::lemon::ignore_unused_variable_warning(b);
+
+    checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
+    MapToFunctor<ReadMap<A,B> > map =
+      MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
+    ::lemon::ignore_unused_variable_warning(map);
+
+    check(functorToMap(&func)[A()] == 3,
+          "Something is wrong with FunctorToMap");
+    check(mapToFunctor(constMap<A,int>(2))(A()) == 2,
+          "Something is wrong with MapToFunctor");
+    check(mapToFunctor(functorToMap(&func))(A()) == 3 &&
+          mapToFunctor(functorToMap(&func))[A()] == 3,
+          "Something is wrong with FunctorToMap or MapToFunctor");
+    check(functorToMap(mapToFunctor(constMap<A,int>(2)))[A()] == 2,
+          "Something is wrong with FunctorToMap or MapToFunctor");
+  }
+
+  // ConvertMap
+  {
+    checkConcept<ReadMap<double,double>,
+      ConvertMap<ReadMap<double, int>, double> >();
+    ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
+    ::lemon::ignore_unused_variable_warning(map1);
+    ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
+    ::lemon::ignore_unused_variable_warning(map2);
+
+  }
+
+  // ForkMap
+  {
+    checkConcept<DoubleWriteMap, ForkMap<DoubleWriteMap, DoubleWriteMap> >();
+
+    typedef RangeMap<double> RM;
+    typedef SparseMap<int, double> SM;
+    RM m1(10, -1);
+    SM m2(-1);
+    checkConcept<ReadWriteMap<int, double>, ForkMap<RM, SM> >();
+    checkConcept<ReadWriteMap<int, double>, ForkMap<SM, RM> >();
+    ForkMap<RM, SM> map1(m1,m2);
+    ForkMap<SM, RM> map2 = forkMap(m2,m1);
+    map2.set(5, 10);
+    check(m1[1] == -1 && m1[5] == 10 && m2[1] == -1 &&
+          m2[5] == 10 && map2[1] == -1 && map2[5] == 10,
+          "Something is wrong with ForkMap");
+  }
+
+  // Arithmetic maps:
+  // - AddMap, SubMap, MulMap, DivMap
+  // - ShiftMap, ShiftWriteMap, ScaleMap, ScaleWriteMap
+  // - NegMap, NegWriteMap, AbsMap
+  {
+    checkConcept<DoubleMap, AddMap<DoubleMap,DoubleMap> >();
+    checkConcept<DoubleMap, SubMap<DoubleMap,DoubleMap> >();
+    checkConcept<DoubleMap, MulMap<DoubleMap,DoubleMap> >();
+    checkConcept<DoubleMap, DivMap<DoubleMap,DoubleMap> >();
+
+    ConstMap<int, double> c1(1.0), c2(3.14);
+    IdentityMap<int> im;
+    ConvertMap<IdentityMap<int>, double> id(im);
+    check(addMap(c1,id)[0] == 1.0  && addMap(c1,id)[10] == 11.0,
+          "Something is wrong with AddMap");
+    check(subMap(id,c1)[0] == -1.0 && subMap(id,c1)[10] == 9.0,
+          "Something is wrong with SubMap");
+    check(mulMap(id,c2)[0] == 0    && mulMap(id,c2)[2]  == 6.28,
+          "Something is wrong with MulMap");
+    check(divMap(c2,id)[1] == 3.14 && divMap(c2,id)[2]  == 1.57,
+          "Something is wrong with DivMap");
+
+    checkConcept<DoubleMap, ShiftMap<DoubleMap> >();
+    checkConcept<DoubleWriteMap, ShiftWriteMap<DoubleWriteMap> >();
+    checkConcept<DoubleMap, ScaleMap<DoubleMap> >();
+    checkConcept<DoubleWriteMap, ScaleWriteMap<DoubleWriteMap> >();
+    checkConcept<DoubleMap, NegMap<DoubleMap> >();
+    checkConcept<DoubleWriteMap, NegWriteMap<DoubleWriteMap> >();
+    checkConcept<DoubleMap, AbsMap<DoubleMap> >();
+
+    check(shiftMap(id, 2.0)[1] == 3.0 && shiftMap(id, 2.0)[10] == 12.0,
+          "Something is wrong with ShiftMap");
+    check(shiftWriteMap(id, 2.0)[1] == 3.0 &&
+          shiftWriteMap(id, 2.0)[10] == 12.0,
+          "Something is wrong with ShiftWriteMap");
+    check(scaleMap(id, 2.0)[1] == 2.0 && scaleMap(id, 2.0)[10] == 20.0,
+          "Something is wrong with ScaleMap");
+    check(scaleWriteMap(id, 2.0)[1] == 2.0 &&
+          scaleWriteMap(id, 2.0)[10] == 20.0,
+          "Something is wrong with ScaleWriteMap");
+    check(negMap(id)[1] == -1.0 && negMap(id)[-10] == 10.0,
+          "Something is wrong with NegMap");
+    check(negWriteMap(id)[1] == -1.0 && negWriteMap(id)[-10] == 10.0,
+          "Something is wrong with NegWriteMap");
+    check(absMap(id)[1] == 1.0 && absMap(id)[-10] == 10.0,
+          "Something is wrong with AbsMap");
+  }
+
+  // Logical maps:
+  // - TrueMap, FalseMap
+  // - AndMap, OrMap
+  // - NotMap, NotWriteMap
+  // - EqualMap, LessMap
+  {
+    checkConcept<BoolMap, TrueMap<A> >();
+    checkConcept<BoolMap, FalseMap<A> >();
+    checkConcept<BoolMap, AndMap<BoolMap,BoolMap> >();
+    checkConcept<BoolMap, OrMap<BoolMap,BoolMap> >();
+    checkConcept<BoolMap, NotMap<BoolMap> >();
+    checkConcept<BoolWriteMap, NotWriteMap<BoolWriteMap> >();
+    checkConcept<BoolMap, EqualMap<DoubleMap,DoubleMap> >();
+    checkConcept<BoolMap, LessMap<DoubleMap,DoubleMap> >();
+
+    TrueMap<int> tm;
+    FalseMap<int> fm;
+    RangeMap<bool> rm(2);
+    rm[0] = true; rm[1] = false;
+    check(andMap(tm,rm)[0] && !andMap(tm,rm)[1] &&
+          !andMap(fm,rm)[0] && !andMap(fm,rm)[1],
+          "Something is wrong with AndMap");
+    check(orMap(tm,rm)[0] && orMap(tm,rm)[1] &&
+          orMap(fm,rm)[0] && !orMap(fm,rm)[1],
+          "Something is wrong with OrMap");
+    check(!notMap(rm)[0] && notMap(rm)[1],
+          "Something is wrong with NotMap");
+    check(!notWriteMap(rm)[0] && notWriteMap(rm)[1],
+          "Something is wrong with NotWriteMap");
+
+    ConstMap<int, double> cm(2.0);
+    IdentityMap<int> im;
+    ConvertMap<IdentityMap<int>, double> id(im);
+    check(lessMap(id,cm)[1] && !lessMap(id,cm)[2] && !lessMap(id,cm)[3],
+          "Something is wrong with LessMap");
+    check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3],
+          "Something is wrong with EqualMap");
+  }
+
+  // LoggerBoolMap
+  {
+    typedef std::vector<int> vec;
+    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
+    checkConcept<WriteMap<int, bool>,
+                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
+
+    vec v1;
+    vec v2(10);
+    LoggerBoolMap<std::back_insert_iterator<vec> >
+      map1(std::back_inserter(v1));
+    LoggerBoolMap<vec::iterator> map2(v2.begin());
+    map1.set(10, false);
+    map1.set(20, true);   map2.set(20, true);
+    map1.set(30, false);  map2.set(40, false);
+    map1.set(50, true);   map2.set(50, true);
+    map1.set(60, true);   map2.set(60, true);
+    check(v1.size() == 3 && v2.size() == 10 &&
+          v1[0]==20 && v1[1]==50 && v1[2]==60 &&
+          v2[0]==20 && v2[1]==50 && v2[2]==60,
+          "Something is wrong with LoggerBoolMap");
+
+    int i = 0;
+    for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
+          it != map2.end(); ++it )
+      check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
+
+    typedef ListDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+    Graph gr;
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+    Node n3 = gr.addNode();
+
+    gr.addArc(n3, n0);
+    gr.addArc(n3, n2);
+    gr.addArc(n0, n2);
+    gr.addArc(n2, n1);
+    gr.addArc(n0, n1);
+
+    {
+      std::vector<Node> v;
+      dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
+
+      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
+            "Something is wrong with LoggerBoolMap");
+    }
+    {
+      std::vector<Node> v(countNodes(gr));
+      dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
+
+      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
+            "Something is wrong with LoggerBoolMap");
+    }
+  }
+
+  // IdMap, RangeIdMap
+  {
+    typedef ListDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
+    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
+    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
+    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
+
+    Graph gr;
+    IdMap<Graph, Node> nmap(gr);
+    IdMap<Graph, Arc> amap(gr);
+    RangeIdMap<Graph, Node> nrmap(gr);
+    RangeIdMap<Graph, Arc> armap(gr);
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    Arc a0 = gr.addArc(n0, n1);
+    Arc a1 = gr.addArc(n0, n2);
+    Arc a2 = gr.addArc(n2, n1);
+    Arc a3 = gr.addArc(n2, n0);
+
+    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
+    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
+    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
+
+    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
+    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
+    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
+    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
+
+    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
+    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
+
+    check(nrmap.size() == 3 && armap.size() == 4,
+          "Wrong RangeIdMap::size()");
+
+    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
+    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
+    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
+
+    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
+    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
+    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
+    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
+
+    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
+    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
+
+    gr.erase(n1);
+
+    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
+    nrmap.swap(n2, n0);
+    if (armap[a1] == 1) armap.swap(a1, a3);
+    armap.swap(a3, a1);
+
+    check(nrmap.size() == 2 && armap.size() == 2,
+          "Wrong RangeIdMap::size()");
+
+    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
+    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
+
+    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
+    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
+
+    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
+    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
+  }
+
+  // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
+  {
+    typedef ListGraph Graph;
+    GRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
+    checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
+    checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
+    checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
+    checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
+    checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
+
+    Graph gr;
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    gr.addEdge(n0,n1);
+    gr.addEdge(n1,n2);
+    gr.addEdge(n0,n2);
+    gr.addEdge(n2,n1);
+    gr.addEdge(n1,n2);
+    gr.addEdge(n0,n1);
+
+    for (EdgeIt e(gr); e != INVALID; ++e) {
+      check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
+      check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
+    }
+
+    check(mapCompare(gr,
+          sourceMap(orienter(gr, constMap<Edge, bool>(true))),
+          targetMap(orienter(gr, constMap<Edge, bool>(false)))),
+          "Wrong SourceMap or TargetMap");
+
+    typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
+    ConstMap<Edge, bool> true_edge_map(true);
+    Digraph dgr(gr, true_edge_map);
+    OutDegMap<Digraph> odm(dgr);
+    InDegMap<Digraph> idm(dgr);
+
+    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
+    check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
+
+    gr.addEdge(n2, n0);
+
+    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
+    check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
+  }
+
+  // CrossRefMap
+  {
+    typedef ListDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadWriteMap<Node, int>,
+                 CrossRefMap<Graph, Node, int> >();
+    checkConcept<ReadWriteMap<Node, bool>,
+                 CrossRefMap<Graph, Node, bool> >();
+    checkConcept<ReadWriteMap<Node, double>,
+                 CrossRefMap<Graph, Node, double> >();
+
+    Graph gr;
+    typedef CrossRefMap<Graph, Node, char> CRMap;
+    CRMap map(gr);
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    map.set(n0, 'A');
+    map.set(n1, 'B');
+    map.set(n2, 'C');
+
+    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
+          "Wrong CrossRefMap");
+    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
+          "Wrong CrossRefMap");
+    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
+          "Wrong CrossRefMap");
+    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
+          "Wrong CrossRefMap::count()");
+
+    CRMap::ValueIt it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
+          it == map.endValue(), "Wrong value iterator");
+
+    map.set(n2, 'A');
+
+    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
+          "Wrong CrossRefMap");
+    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
+    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
+    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
+          "Wrong CrossRefMap");
+    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
+          "Wrong CrossRefMap::count()");
+
+    it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
+          it == map.endValue(), "Wrong value iterator");
+
+    map.set(n0, 'C');
+
+    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
+          "Wrong CrossRefMap");
+    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
+    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
+    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
+    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
+          "Wrong CrossRefMap::count()");
+
+    it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
+          it == map.endValue(), "Wrong value iterator");
+  }
+
+  // CrossRefMap
+  {
+    typedef SmartDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadWriteMap<Node, int>,
+                 CrossRefMap<Graph, Node, int> >();
+
+    Graph gr;
+    typedef CrossRefMap<Graph, Node, char> CRMap;
+    typedef CRMap::ValueIterator ValueIt;
+    CRMap map(gr);
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    map.set(n0, 'A');
+    map.set(n1, 'B');
+    map.set(n2, 'C');
+    map.set(n2, 'A');
+    map.set(n0, 'C');
+
+    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
+          "Wrong CrossRefMap");
+    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
+    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
+    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
+
+    ValueIt it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
+          it == map.endValue(), "Wrong value iterator");
+  }
+
+  // Iterable bool map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+
+    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
+    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
+
+    const int num = 10;
+    Graph g;
+    Ibm map0(g, true);
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Ibm map1(g, true);
+    int n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+    n = 0;
+    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
+        ++n;
+    }
+    check(n == num, "Wrong number");
+    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
+    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
+
+    map1[items[5]] = true;
+
+    n = 0;
+    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
+        ++n;
+    }
+    check(n == num, "Wrong number");
+
+    map1[items[num / 2]] = false;
+    check(map1[items[num / 2]] == false, "Wrong map value");
+
+    n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
+        ++n;
+    }
+    check(n == num - 1, "Wrong number");
+
+    n = 0;
+    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
+        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
+        ++n;
+    }
+    check(n == 1, "Wrong number");
+
+    map1[items[0]] = false;
+    check(map1[items[0]] == false, "Wrong map value");
+
+    map1[items[num - 1]] = false;
+    check(map1[items[num - 1]] == false, "Wrong map value");
+
+    n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
+        ++n;
+    }
+    check(n == num - 3, "Wrong number");
+    check(map1.trueNum() == num - 3, "Wrong number");
+
+    n = 0;
+    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
+        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
+        ++n;
+    }
+    check(n == 3, "Wrong number");
+    check(map1.falseNum() == 3, "Wrong number");
+  }
+
+  // Iterable int map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
+
+    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
+
+    const int num = 10;
+    Graph g;
+    Iim map0(g, 0);
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Iim map1(g);
+    check(map1.size() == 0, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      map1[items[i]] = i;
+    }
+    check(map1.size() == num, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      Iim::ItemIt it(map1, i);
+      check(static_cast<Item>(it) == items[i], "Wrong value");
+      ++it;
+      check(static_cast<Item>(it) == INVALID, "Wrong value");
+    }
+
+    for (int i = 0; i < num; ++i) {
+      map1[items[i]] = i % 2;
+    }
+    check(map1.size() == 2, "Wrong size");
+
+    int n = 0;
+    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
+      ++n;
+    }
+    check(n == (num + 1) / 2, "Wrong number");
+
+    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+  }
+
+  // Iterable value map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
+
+    checkConcept<ReadWriteMap<Item, double>, Ivm>();
+
+    const int num = 10;
+    Graph g;
+    Ivm map0(g, 0.0);
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Ivm map1(g, 0.0);
+    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
+    check(*map1.beginValue() == 0.0, "Wrong value");
+
+    for (int i = 0; i < num; ++i) {
+      map1.set(items[i], static_cast<double>(i));
+    }
+    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      Ivm::ItemIt it(map1, static_cast<double>(i));
+      check(static_cast<Item>(it) == items[i], "Wrong value");
+      ++it;
+      check(static_cast<Item>(it) == INVALID, "Wrong value");
+    }
+
+    for (Ivm::ValueIt vit = map1.beginValue();
+         vit != map1.endValue(); ++vit) {
+      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
+            "Wrong ValueIt");
+    }
+
+    for (int i = 0; i < num; ++i) {
+      map1.set(items[i], static_cast<double>(i % 2));
+    }
+    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
+
+    int n = 0;
+    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
+      ++n;
+    }
+    check(n == (num + 1) / 2, "Wrong number");
+
+    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+  }
+
+  // Graph map utilities:
+  // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
+  // mapFind(), mapFindIf(), mapCount(), mapCountIf()
+  // mapCopy(), mapCompare(), mapFill()
+  {
+    DIGRAPH_TYPEDEFS(SmartDigraph);
+
+    SmartDigraph g;
+    Node n1 = g.addNode();
+    Node n2 = g.addNode();
+    Node n3 = g.addNode();
+
+    SmartDigraph::NodeMap<int> map1(g);
+    SmartDigraph::ArcMap<char> map2(g);
+    ConstMap<Node, A> cmap1 = A();
+    ConstMap<Arc, C> cmap2 = C(0);
+
+    map1[n1] = 10;
+    map1[n2] = 5;
+    map1[n3] = 12;
+
+    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
+    check(mapMin(g, map1) == n2, "Wrong mapMin()");
+    check(mapMax(g, map1) == n3, "Wrong mapMax()");
+    check(mapMin(g, map1, std::greater<int>()) == n3, "Wrong mapMin()");
+    check(mapMax(g, map1, std::greater<int>()) == n2, "Wrong mapMax()");
+    check(mapMinValue(g, map1) == 5, "Wrong mapMinValue()");
+    check(mapMaxValue(g, map1) == 12, "Wrong mapMaxValue()");
+
+    check(mapMin(g, map2) == INVALID, "Wrong mapMin()");
+    check(mapMax(g, map2) == INVALID, "Wrong mapMax()");
+
+    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
+    check(mapMax(g, cmap2) == INVALID, "Wrong mapMax()");
+
+    Arc a1 = g.addArc(n1, n2);
+    Arc a2 = g.addArc(n1, n3);
+    Arc a3 = g.addArc(n2, n3);
+    Arc a4 = g.addArc(n3, n1);
+
+    map2[a1] = 'b';
+    map2[a2] = 'a';
+    map2[a3] = 'b';
+    map2[a4] = 'c';
+
+    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
+    check(mapMin(g, map2) == a2, "Wrong mapMin()");
+    check(mapMax(g, map2) == a4, "Wrong mapMax()");
+    check(mapMin(g, map2, std::greater<int>()) == a4, "Wrong mapMin()");
+    check(mapMax(g, map2, std::greater<int>()) == a2, "Wrong mapMax()");
+    check(mapMinValue(g, map2, std::greater<int>()) == 'c',
+          "Wrong mapMinValue()");
+    check(mapMaxValue(g, map2, std::greater<int>()) == 'a',
+          "Wrong mapMaxValue()");
+
+    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
+    check(mapMax(g, cmap2) != INVALID, "Wrong mapMax()");
+    check(mapMaxValue(g, cmap2) == C(0), "Wrong mapMaxValue()");
+
+    check(mapMin(g, composeMap(functorToMap(&createC), map2)) == a2,
+          "Wrong mapMin()");
+    check(mapMax(g, composeMap(functorToMap(&createC), map2)) == a4,
+          "Wrong mapMax()");
+    check(mapMinValue(g, composeMap(functorToMap(&createC), map2)) == C('a'),
+          "Wrong mapMinValue()");
+    check(mapMaxValue(g, composeMap(functorToMap(&createC), map2)) == C('c'),
+          "Wrong mapMaxValue()");
+
+    // mapFind(), mapFindIf()
+    check(mapFind(g, map1, 5) == n2, "Wrong mapFind()");
+    check(mapFind(g, map1, 6) == INVALID, "Wrong mapFind()");
+    check(mapFind(g, map2, 'a') == a2, "Wrong mapFind()");
+    check(mapFind(g, map2, 'e') == INVALID, "Wrong mapFind()");
+    check(mapFind(g, cmap2, C(0)) == ArcIt(g), "Wrong mapFind()");
+    check(mapFind(g, cmap2, C(1)) == INVALID, "Wrong mapFind()");
+
+    check(mapFindIf(g, map1, Less<int>(7)) == n2,
+          "Wrong mapFindIf()");
+    check(mapFindIf(g, map1, Less<int>(5)) == INVALID,
+          "Wrong mapFindIf()");
+    check(mapFindIf(g, map2, Less<char>('d')) == ArcIt(g),
+          "Wrong mapFindIf()");
+    check(mapFindIf(g, map2, Less<char>('a')) == INVALID,
+          "Wrong mapFindIf()");
+
+    // mapCount(), mapCountIf()
+    check(mapCount(g, map1, 5) == 1, "Wrong mapCount()");
+    check(mapCount(g, map1, 6) == 0, "Wrong mapCount()");
+    check(mapCount(g, map2, 'a') == 1, "Wrong mapCount()");
+    check(mapCount(g, map2, 'b') == 2, "Wrong mapCount()");
+    check(mapCount(g, map2, 'e') == 0, "Wrong mapCount()");
+    check(mapCount(g, cmap2, C(0)) == 4, "Wrong mapCount()");
+    check(mapCount(g, cmap2, C(1)) == 0, "Wrong mapCount()");
+
+    check(mapCountIf(g, map1, Less<int>(11)) == 2,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map1, Less<int>(13)) == 3,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map1, Less<int>(5)) == 0,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map2, Less<char>('d')) == 4,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map2, Less<char>('c')) == 3,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map2, Less<char>('a')) == 0,
+          "Wrong mapCountIf()");
+
+    // MapIt, ConstMapIt
+/*
+These tests can be used after applying bugfix #330
+    typedef SmartDigraph::NodeMap<int>::MapIt MapIt;
+    typedef SmartDigraph::NodeMap<int>::ConstMapIt ConstMapIt;
+    check(*std::min_element(MapIt(map1), MapIt(INVALID)) == 5,
+          "Wrong NodeMap<>::MapIt");
+    check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12,
+          "Wrong NodeMap<>::MapIt");
+
+    int sum = 0;
+    std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum));
+    check(sum == 27, "Wrong NodeMap<>::MapIt");
+    std::for_each(ConstMapIt(map1), ConstMapIt(INVALID), Sum<int>(sum));
+    check(sum == 54, "Wrong NodeMap<>::ConstMapIt");
+*/
+
+    // mapCopy(), mapCompare(), mapFill()
+    check(mapCompare(g, map1, map1), "Wrong mapCompare()");
+    check(mapCompare(g, cmap2, cmap2), "Wrong mapCompare()");
+    check(mapCompare(g, map1, shiftMap(map1, 0)), "Wrong mapCompare()");
+    check(mapCompare(g, map2, scaleMap(map2, 1)), "Wrong mapCompare()");
+    check(!mapCompare(g, map1, shiftMap(map1, 1)), "Wrong mapCompare()");
+
+    SmartDigraph::NodeMap<int> map3(g, 0);
+    SmartDigraph::ArcMap<char> map4(g, 'a');
+
+    check(!mapCompare(g, map1, map3), "Wrong mapCompare()");
+    check(!mapCompare(g, map2, map4), "Wrong mapCompare()");
+
+    mapCopy(g, map1, map3);
+    mapCopy(g, map2, map4);
+
+    check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()");
+    check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");
+
+    Undirector<SmartDigraph> ug(g);
+    Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x');
+    Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14);
+
+    check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
+    check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
+    check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
+    check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
+
+    mapCopy(g, map2, umap1);
+
+    check(mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
+    check(mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
+    check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
+    check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
+
+    mapCopy(g, map2, umap1);
+    mapCopy(g, umap1, map2);
+    mapCopy(ug, map2, umap1);
+    mapCopy(ug, umap1, map2);
+
+    check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
+    mapCopy(ug, umap1, umap2);
+    check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
+
+    check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()");
+    mapFill(g, map1, 2);
+    check(mapCompare(g, constMap<Node>(2), map1), "Wrong mapFill()");
+
+    check(!mapCompare(g, map2, constMap<Arc>('z')), "Wrong mapCompare()");
+    mapCopy(g, constMap<Arc>('z'), map2);
+    check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()");
+  }
+
+  return 0;
+}
diff --git a/test/matching_test.cc b/test/matching_test.cc
new file mode 100644
index 0000000..dcb1d3b
--- /dev/null
+++ b/test/matching_test.cc
@@ -0,0 +1,449 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <queue>
+#include <cstdlib>
+
+#include <lemon/matching.h>
+#include <lemon/smart_graph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+GRAPH_TYPEDEFS(SmartGraph);
+
+
+const int lgfn = 3;
+const std::string lgf[lgfn] = {
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "7 4  0      984\n"
+  "0 7  1      73\n"
+  "7 1  2      204\n"
+  "2 3  3      583\n"
+  "2 7  4      565\n"
+  "2 1  5      582\n"
+  "0 4  6      551\n"
+  "2 5  7      385\n"
+  "1 5  8      561\n"
+  "5 3  9      484\n"
+  "7 5  10     904\n"
+  "3 6  11     47\n"
+  "7 6  12     888\n"
+  "3 0  13     747\n"
+  "6 1  14     310\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "2 5  0      710\n"
+  "0 5  1      241\n"
+  "2 4  2      856\n"
+  "2 6  3      762\n"
+  "4 1  4      747\n"
+  "6 1  5      962\n"
+  "4 7  6      723\n"
+  "1 7  7      661\n"
+  "2 3  8      376\n"
+  "1 0  9      416\n"
+  "6 7  10     391\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "6 2  0      553\n"
+  "0 7  1      653\n"
+  "6 3  2      22\n"
+  "4 7  3      846\n"
+  "7 2  4      981\n"
+  "7 6  5      250\n"
+  "5 2  6      539\n",
+};
+
+void checkMaxMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<bool> MatMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  MatMap mat(g);
+
+  MaxMatching<Graph> mat_test(g);
+  const MaxMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.greedyInit();
+  mat_test.matchingInit(mat);
+  mat_test.startSparse();
+  mat_test.startDense();
+  mat_test.run();
+
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  MaxMatching<Graph>::Status stat =
+    const_mat_test.status(n);
+  ::lemon::ignore_unused_variable_warning(stat);
+  const MaxMatching<Graph>::StatusMap& smap =
+    const_mat_test.statusMap();
+  stat = smap[n];
+  const_mat_test.barrier(n);
+}
+
+void checkMaxWeightedMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedMatching<Graph> mat_test(g, w);
+  const MaxWeightedMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  int k = 0;
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+  const_mat_test.blossomNum();
+  const_mat_test.blossomSize(k);
+  const_mat_test.blossomValue(k);
+}
+
+void checkMaxWeightedPerfectMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
+  const MaxWeightedPerfectMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  int k = 0;
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+  const_mat_test.blossomNum();
+  const_mat_test.blossomSize(k);
+  const_mat_test.blossomValue(k);
+}
+
+void checkMatching(const SmartGraph& graph,
+                   const MaxMatching<SmartGraph>& mm) {
+  int num = 0;
+
+  IntNodeMap comp_index(graph);
+  UnionFind<IntNodeMap> comp(comp_index);
+
+  int barrier_num = 0;
+
+  for (NodeIt n(graph); n != INVALID; ++n) {
+    check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
+          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
+    if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
+      ++barrier_num;
+    } else {
+      comp.insert(n);
+    }
+  }
+
+  for (EdgeIt e(graph); e != INVALID; ++e) {
+    if (mm.matching(e)) {
+      check(e == mm.matching(graph.u(e)), "Wrong matching");
+      check(e == mm.matching(graph.v(e)), "Wrong matching");
+      ++num;
+    }
+    check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
+          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
+          "Wrong Gallai-Edmonds decomposition");
+
+    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
+          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
+          "Wrong Gallai-Edmonds decomposition");
+
+    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
+        mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
+      comp.join(graph.u(e), graph.v(e));
+    }
+  }
+
+  std::set<int> comp_root;
+  int odd_comp_num = 0;
+  for (NodeIt n(graph); n != INVALID; ++n) {
+    if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
+      int root = comp.find(n);
+      if (comp_root.find(root) == comp_root.end()) {
+        comp_root.insert(root);
+        if (comp.size(n) % 2 == 1) {
+          ++odd_comp_num;
+        }
+      }
+    }
+  }
+
+  check(mm.matchingSize() == num, "Wrong matching");
+  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
+         "Wrong matching");
+  return;
+}
+
+void checkWeightedMatching(const SmartGraph& graph,
+                   const SmartGraph::EdgeMap<int>& weight,
+                   const MaxWeightedMatching<SmartGraph>& mwm) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e)) continue;
+    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
+
+    for (int i = 0; i < mwm.blossomNum(); ++i) {
+      bool s = false, t = false;
+      for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
+           n != INVALID; ++n) {
+        if (graph.u(e) == n) s = true;
+        if (graph.v(e) == n) t = true;
+      }
+      if (s == true && t == true) {
+        rw += mwm.blossomValue(i);
+      }
+    }
+    rw -= weight[e] * mwm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (mwm.matching(n) != INVALID) {
+      check(mwm.nodeValue(n) >= 0, "Invalid node value");
+      pv += weight[mwm.matching(n)];
+      SmartGraph::Node o = graph.target(mwm.matching(n));
+      check(mwm.mate(n) == o, "Invalid matching");
+      check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
+            "Invalid matching");
+    } else {
+      check(mwm.mate(n) == INVALID, "Invalid matching");
+      check(mwm.nodeValue(n) == 0, "Invalid matching");
+    }
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwm.nodeValue(n);
+  }
+
+  for (int i = 0; i < mwm.blossomNum(); ++i) {
+    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
+    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
+    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
+  }
+
+  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
+
+  return;
+}
+
+void checkWeightedPerfectMatching(const SmartGraph& graph,
+                          const SmartGraph::EdgeMap<int>& weight,
+                          const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e)) continue;
+    int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
+
+    for (int i = 0; i < mwpm.blossomNum(); ++i) {
+      bool s = false, t = false;
+      for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
+           n != INVALID; ++n) {
+        if (graph.u(e) == n) s = true;
+        if (graph.v(e) == n) t = true;
+      }
+      if (s == true && t == true) {
+        rw += mwpm.blossomValue(i);
+      }
+    }
+    rw -= weight[e] * mwpm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwpm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    check(mwpm.matching(n) != INVALID, "Non perfect");
+    pv += weight[mwpm.matching(n)];
+    SmartGraph::Node o = graph.target(mwpm.matching(n));
+    check(mwpm.mate(n) == o, "Invalid matching");
+    check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
+          "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwpm.nodeValue(n);
+  }
+
+  for (int i = 0; i < mwpm.blossomNum(); ++i) {
+    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
+    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
+    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
+  }
+
+  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
+
+  return;
+}
+
+
+int main() {
+
+  for (int i = 0; i < lgfn; ++i) {
+    SmartGraph graph;
+    SmartGraph::EdgeMap<int> weight(graph);
+
+    istringstream lgfs(lgf[i]);
+    graphReader(graph, lgfs).
+      edgeMap("weight", weight).run();
+
+    bool perfect;
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.run();
+      checkMatching(graph, mm);
+      perfect = 2 * mm.matchingSize() == countNodes(graph);
+    }
+
+    {
+      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
+      mwm.run();
+      checkWeightedMatching(graph, weight, mwm);
+    }
+
+    {
+      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
+      mwm.init();
+      mwm.start();
+      checkWeightedMatching(graph, weight, mwm);
+    }
+
+    {
+      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
+      bool result = mwpm.run();
+
+      check(result == perfect, "Perfect matching found");
+      if (perfect) {
+        checkWeightedPerfectMatching(graph, weight, mwpm);
+      }
+    }
+
+    {
+      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
+      mwpm.init();
+      bool result = mwpm.start();
+
+      check(result == perfect, "Perfect matching found");
+      if (perfect) {
+        checkWeightedPerfectMatching(graph, weight, mwpm);
+      }
+    }
+  }
+
+  return 0;
+}
diff --git a/test/max_cardinality_search_test.cc b/test/max_cardinality_search_test.cc
new file mode 100644
index 0000000..c01066f
--- /dev/null
+++ b/test/max_cardinality_search_test.cc
@@ -0,0 +1,162 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/max_cardinality_search.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concepts/heap.h>
+#include <lemon/lgf_reader.h>
+
+using namespace lemon;
+using namespace std;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "@arcs\n"
+  "    label capacity\n"
+  "0 1 0     2\n"
+  "1 0 1     2\n"
+  "2 1 2     1\n"
+  "2 3 3     3\n"
+  "3 2 4     3\n"
+  "3 1 5     5\n"
+  "@attributes\n"
+  "s 0\n"
+  "x 1\n"
+  "y 2\n"
+  "z 3\n";
+
+void checkMaxCardSearchCompile() {
+
+  typedef concepts::Digraph Digraph;
+  typedef int Value;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc,Value> CapMap;
+  typedef concepts::ReadWriteMap<Node,Value> CardMap;
+  typedef concepts::ReadWriteMap<Node,bool> ProcMap;
+  typedef Digraph::NodeMap<int> HeapCrossRef;
+
+  Digraph g;
+  Node n,s;
+  CapMap cap;
+  CardMap card;
+  ProcMap proc;
+  HeapCrossRef crossref(g);
+
+  typedef MaxCardinalitySearch<Digraph,CapMap>
+    ::SetCapacityMap<CapMap>
+    ::SetCardinalityMap<CardMap>
+    ::SetProcessedMap<ProcMap>
+    ::SetStandardHeap<BinHeap<Value,HeapCrossRef> >
+    ::Create MaxCardType;
+
+  MaxCardType maxcard(g,cap);
+  const MaxCardType& const_maxcard = maxcard;
+
+  const MaxCardType::Heap& heap_const = const_maxcard.heap();
+  MaxCardType::Heap& heap = const_cast<MaxCardType::Heap&>(heap_const);
+  maxcard.heap(heap,crossref);
+
+  maxcard.capacityMap(cap).cardinalityMap(card).processedMap(proc);
+
+  maxcard.init();
+  maxcard.addSource(s);
+  n = maxcard.nextNode();
+   maxcard.processNextNode();
+   maxcard.start();
+   maxcard.run(s);
+   maxcard.run();
+ }
+
+ void checkWithIntMap( std::istringstream& input)
+ {
+   typedef SmartDigraph Digraph;
+   typedef Digraph::Node Node;
+   typedef Digraph::ArcMap<int> CapMap;
+
+   Digraph g;
+   Node s,x,y,z,a;
+   CapMap cap(g);
+
+   DigraphReader<Digraph>(g,input).
+     arcMap("capacity", cap).
+     node("s",s).
+     node("x",x).
+     node("y",y).
+     node("z",z).
+     run();
+
+   MaxCardinalitySearch<Digraph,CapMap> maxcard(g,cap);
+
+   maxcard.init();
+   maxcard.addSource(s);
+   maxcard.start(x);
+
+   check(maxcard.processed(s) && !maxcard.processed(x) &&
+         !maxcard.processed(y), "Wrong processed()!");
+
+   a=maxcard.nextNode();
+   check(maxcard.processNextNode()==a,
+         "Wrong nextNode() or processNextNode() return value!");
+
+   check(maxcard.processed(a), "Wrong processNextNode()!");
+
+   maxcard.start();
+   check(maxcard.cardinality(x)==2 && maxcard.cardinality(y)>=4,
+         "Wrong cardinalities!");
+ }
+
+ void checkWithConst1Map(std::istringstream &input) {
+   typedef SmartDigraph Digraph;
+   typedef Digraph::Node Node;
+
+   Digraph g;
+   Node s,x,y,z;
+
+  DigraphReader<Digraph>(g,input).
+    node("s",s).
+    node("x",x).
+    node("y",y).
+    node("z",z).
+    run();
+
+  MaxCardinalitySearch<Digraph> maxcard(g);
+  maxcard.run(s);
+  check(maxcard.cardinality(x)==1 &&
+        maxcard.cardinality(y)+maxcard.cardinality(z)==3,
+        "Wrong cardinalities!");
+}
+
+int main() {
+
+  std::istringstream input1(test_lgf);
+  checkWithIntMap(input1);
+
+  std::istringstream input2(test_lgf);
+  checkWithConst1Map(input2);
+}
diff --git a/test/max_clique_test.cc b/test/max_clique_test.cc
new file mode 100644
index 0000000..d16f0f9
--- /dev/null
+++ b/test/max_clique_test.cc
@@ -0,0 +1,188 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <sstream>
+#include <lemon/list_graph.h>
+#include <lemon/full_graph.h>
+#include <lemon/grid_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/grosso_locatelli_pullan_mc.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label max_clique\n"
+  "1     0\n"
+  "2     0\n"
+  "3     0\n"
+  "4     1\n"
+  "5     1\n"
+  "6     1\n"
+  "7     1\n"
+  "@edges\n"
+  "    label\n"
+  "1 2     1\n"
+  "1 3     2\n"
+  "1 4     3\n"
+  "1 6     4\n"
+  "2 3     5\n"
+  "2 5     6\n"
+  "2 7     7\n"
+  "3 4     8\n"
+  "3 5     9\n"
+  "4 5    10\n"
+  "4 6    11\n"
+  "4 7    12\n"
+  "5 6    13\n"
+  "5 7    14\n"
+  "6 7    15\n";
+
+
+// Check with general graphs
+template <typename Param>
+void checkMaxCliqueGeneral(Param rule) {
+  typedef ListGraph GR;
+  typedef GrossoLocatelliPullanMc<GR> McAlg;
+  typedef McAlg::CliqueNodeIt CliqueIt;
+
+  // Basic tests
+  {
+    GR g;
+    GR::NodeMap<bool> map(g);
+    McAlg mc(g);
+    mc.iterationLimit(50);
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 0, "Wrong clique size");
+    check(CliqueIt(mc) == INVALID, "Wrong CliqueNodeIt");
+
+    GR::Node u = g.addNode();
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 1, "Wrong clique size");
+    mc.cliqueMap(map);
+    check(map[u], "Wrong clique map");
+    CliqueIt it1(mc);
+    check(static_cast<GR::Node>(it1) == u && ++it1 == INVALID,
+          "Wrong CliqueNodeIt");
+
+    GR::Node v = g.addNode();
+    check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 1, "Wrong clique size");
+    mc.cliqueMap(map);
+    check((map[u] && !map[v]) || (map[v] && !map[u]), "Wrong clique map");
+    CliqueIt it2(mc);
+    check(it2 != INVALID && ++it2 == INVALID, "Wrong CliqueNodeIt");
+
+    g.addEdge(u, v);
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 2, "Wrong clique size");
+    mc.cliqueMap(map);
+    check(map[u] && map[v], "Wrong clique map");
+    CliqueIt it3(mc);
+    check(it3 != INVALID && ++it3 != INVALID && ++it3 == INVALID,
+          "Wrong CliqueNodeIt");
+  }
+
+  // Test graph
+  {
+    GR g;
+    GR::NodeMap<bool> max_clique(g);
+    GR::NodeMap<bool> map(g);
+    std::istringstream input(test_lgf);
+    graphReader(g, input)
+      .nodeMap("max_clique", max_clique)
+      .run();
+
+    McAlg mc(g);
+    mc.iterationLimit(50);
+    check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 4, "Wrong clique size");
+    mc.cliqueMap(map);
+    for (GR::NodeIt n(g); n != INVALID; ++n) {
+      check(map[n] == max_clique[n], "Wrong clique map");
+    }
+    int cnt = 0;
+    for (CliqueIt n(mc); n != INVALID; ++n) {
+      cnt++;
+      check(map[n] && max_clique[n], "Wrong CliqueNodeIt");
+    }
+    check(cnt == 4, "Wrong CliqueNodeIt");
+  }
+}
+
+// Check with full graphs
+template <typename Param>
+void checkMaxCliqueFullGraph(Param rule) {
+  typedef FullGraph GR;
+  typedef GrossoLocatelliPullanMc<FullGraph> McAlg;
+  typedef McAlg::CliqueNodeIt CliqueIt;
+
+  for (int size = 0; size <= 40; size = size * 3 + 1) {
+    GR g(size);
+    GR::NodeMap<bool> map(g);
+    McAlg mc(g);
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == size, "Wrong clique size");
+    mc.cliqueMap(map);
+    for (GR::NodeIt n(g); n != INVALID; ++n) {
+      check(map[n], "Wrong clique map");
+    }
+    int cnt = 0;
+    for (CliqueIt n(mc); n != INVALID; ++n) cnt++;
+    check(cnt == size, "Wrong CliqueNodeIt");
+  }
+}
+
+// Check with grid graphs
+template <typename Param>
+void checkMaxCliqueGridGraph(Param rule) {
+  GridGraph g(5, 7);
+  GridGraph::NodeMap<char> map(g);
+  GrossoLocatelliPullanMc<GridGraph> mc(g);
+
+  mc.iterationLimit(100);
+  check(mc.run(rule) == mc.ITERATION_LIMIT, "Wrong termination cause");
+  check(mc.cliqueSize() == 2, "Wrong clique size");
+
+  mc.stepLimit(100);
+  check(mc.run(rule) == mc.STEP_LIMIT, "Wrong termination cause");
+  check(mc.cliqueSize() == 2, "Wrong clique size");
+
+  mc.sizeLimit(2);
+  check(mc.run(rule) == mc.SIZE_LIMIT, "Wrong termination cause");
+  check(mc.cliqueSize() == 2, "Wrong clique size");
+}
+
+
+int main() {
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::RANDOM);
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::DEGREE_BASED);
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::PENALTY_BASED);
+
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::RANDOM);
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::DEGREE_BASED);
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::PENALTY_BASED);
+
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::RANDOM);
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::DEGREE_BASED);
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::PENALTY_BASED);
+
+  return 0;
+}
diff --git a/test/max_flow_test.cc b/test/max_flow_test.cc
new file mode 100644
index 0000000..f63874a
--- /dev/null
+++ b/test/max_flow_test.cc
@@ -0,0 +1,395 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/preflow.h>
+#include <lemon/edmonds_karp.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/elevator.h>
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "    label capacity\n"
+  "0 1 0     20\n"
+  "0 2 1     0\n"
+  "1 1 2     3\n"
+  "1 2 3     8\n"
+  "1 3 4     8\n"
+  "2 5 5     5\n"
+  "3 2 6     5\n"
+  "3 5 7     5\n"
+  "3 6 8     5\n"
+  "4 3 9     3\n"
+  "5 7 10    3\n"
+  "5 6 11    10\n"
+  "5 8 12    10\n"
+  "6 8 13    8\n"
+  "8 9 14    20\n"
+  "8 1 15    5\n"
+  "9 5 16    5\n"
+  "@attributes\n"
+  "source 1\n"
+  "target 8\n";
+
+
+// Checks the general interface of a max flow algorithm
+template <typename GR, typename CAP>
+struct MaxFlowClassConcept
+{
+
+  template <typename MF>
+  struct Constraints {
+
+    typedef typename GR::Node Node;
+    typedef typename GR::Arc Arc;
+    typedef typename CAP::Value Value;
+    typedef concepts::ReadWriteMap<Arc, Value> FlowMap;
+    typedef concepts::WriteMap<Node, bool> CutMap;
+
+    GR g;
+    Node n;
+    Arc e;
+    CAP cap;
+    FlowMap flow;
+    CutMap cut;
+    Value v;
+    bool b;
+
+    void constraints() {
+      checkConcept<concepts::Digraph, GR>();
+
+      const Constraints& me = *this;
+
+      typedef typename MF
+          ::template SetFlowMap<FlowMap>
+          ::Create MaxFlowType;
+      typedef typename MF::Create MaxFlowType2;
+      MaxFlowType max_flow(me.g, me.cap, me.n, me.n);
+      const MaxFlowType& const_max_flow = max_flow;
+
+      max_flow
+          .capacityMap(cap)
+          .flowMap(flow)
+          .source(n)
+          .target(n);
+
+      typename MaxFlowType::Tolerance tol = const_max_flow.tolerance();
+      max_flow.tolerance(tol);
+
+      max_flow.init();
+      max_flow.init(cap);
+      max_flow.run();
+
+      v = const_max_flow.flowValue();
+      v = const_max_flow.flow(e);
+      const FlowMap& fm = const_max_flow.flowMap();
+
+      b = const_max_flow.minCut(n);
+      const_max_flow.minCutMap(cut);
+
+      ::lemon::ignore_unused_variable_warning(fm);
+    }
+
+  };
+
+};
+
+// Checks the specific parts of Preflow's interface
+void checkPreflowCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Digraph::Node n;
+  CapMap cap;
+
+  typedef Preflow<Digraph, CapMap>
+      ::SetElevator<Elev>
+      ::SetStandardElevator<LinkedElev>
+      ::Create PreflowType;
+  PreflowType preflow_test(g, cap, n, n);
+  const PreflowType& const_preflow_test = preflow_test;
+
+  const PreflowType::Elevator& elev = const_preflow_test.elevator();
+  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
+
+  bool b = preflow_test.init(cap);
+  preflow_test.startFirstPhase();
+  preflow_test.startSecondPhase();
+  preflow_test.runMinCut();
+
+  ::lemon::ignore_unused_variable_warning(b);
+}
+
+// Checks the specific parts of EdmondsKarp's interface
+void checkEdmondsKarpCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Digraph::Node n;
+  CapMap cap;
+
+  EdmondsKarp<Digraph, CapMap> ek_test(g, cap, n, n);
+
+  ek_test.init(cap);
+  bool b = ek_test.checkedInit(cap);
+  b = ek_test.augment();
+  ek_test.start();
+
+  ::lemon::ignore_unused_variable_warning(b);
+}
+
+
+template <typename T>
+T cutValue (const SmartDigraph& g,
+              const SmartDigraph::NodeMap<bool>& cut,
+              const SmartDigraph::ArcMap<T>& cap) {
+
+  T c=0;
+  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
+    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
+  }
+  return c;
+}
+
+template <typename T>
+bool checkFlow(const SmartDigraph& g,
+               const SmartDigraph::ArcMap<T>& flow,
+               const SmartDigraph::ArcMap<T>& cap,
+               SmartDigraph::Node s, SmartDigraph::Node t) {
+
+  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
+    if (flow[e] < 0 || flow[e] > cap[e]) return false;
+  }
+
+  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
+    if (n == s || n == t) continue;
+    T sum = 0;
+    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
+      sum += flow[e];
+    }
+    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
+      sum -= flow[e];
+    }
+    if (sum != 0) return false;
+  }
+  return true;
+}
+
+void initFlowTest()
+{
+  DIGRAPH_TYPEDEFS(SmartDigraph);
+
+  SmartDigraph g;
+  SmartDigraph::ArcMap<int> cap(g),iflow(g);
+  Node s=g.addNode(); Node t=g.addNode();
+  Node n1=g.addNode(); Node n2=g.addNode();
+  Arc a;
+  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
+  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
+  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
+
+  Preflow<SmartDigraph> pre(g,cap,s,t);
+  pre.init(iflow);
+  pre.startFirstPhase();
+  check(pre.flowValue() == 10, "The incorrect max flow value.");
+  check(pre.minCut(s), "Wrong min cut (Node s).");
+  check(pre.minCut(n1), "Wrong min cut (Node n1).");
+  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
+  check(!pre.minCut(t), "Wrong min cut (Node t).");
+}
+
+template <typename MF, typename SF>
+void checkMaxFlowAlg() {
+  typedef SmartDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+
+  typedef typename MF::Value Value;
+  typedef Digraph::ArcMap<Value> CapMap;
+  typedef CapMap FlowMap;
+  typedef BoolNodeMap CutMap;
+
+  Digraph g;
+  Node s, t;
+  CapMap cap(g);
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(g,input)
+      .arcMap("capacity", cap)
+      .node("source",s)
+      .node("target",t)
+      .run();
+
+  MF max_flow(g, cap, s, t);
+  max_flow.run();
+
+  check(checkFlow(g, max_flow.flowMap(), cap, s, t),
+        "The flow is not feasible.");
+
+  CutMap min_cut(g);
+  max_flow.minCutMap(min_cut);
+  Value min_cut_value = cutValue(g, min_cut, cap);
+
+  check(max_flow.flowValue() == min_cut_value,
+        "The max flow value is not equal to the min cut value.");
+
+  FlowMap flow(g);
+  for (ArcIt e(g); e != INVALID; ++e) flow[e] = max_flow.flowMap()[e];
+
+  Value flow_value = max_flow.flowValue();
+
+  for (ArcIt e(g); e != INVALID; ++e) cap[e] = 2 * cap[e];
+  max_flow.init(flow);
+
+  SF::startFirstPhase(max_flow);       // start first phase of the algorithm
+
+  CutMap min_cut1(g);
+  max_flow.minCutMap(min_cut1);
+  min_cut_value = cutValue(g, min_cut1, cap);
+
+  check(max_flow.flowValue() == min_cut_value &&
+        min_cut_value == 2 * flow_value,
+        "The max flow value or the min cut value is wrong.");
+
+  SF::startSecondPhase(max_flow);       // start second phase of the algorithm
+
+  check(checkFlow(g, max_flow.flowMap(), cap, s, t),
+        "The flow is not feasible.");
+
+  CutMap min_cut2(g);
+  max_flow.minCutMap(min_cut2);
+  min_cut_value = cutValue(g, min_cut2, cap);
+
+  check(max_flow.flowValue() == min_cut_value &&
+        min_cut_value == 2 * flow_value,
+        "The max flow value or the min cut value was not doubled");
+
+
+  max_flow.flowMap(flow);
+
+  NodeIt tmp1(g, s);
+  ++tmp1;
+  if (tmp1 != INVALID) s = tmp1;
+
+  NodeIt tmp2(g, t);
+  ++tmp2;
+  if (tmp2 != INVALID) t = tmp2;
+
+  max_flow.source(s);
+  max_flow.target(t);
+
+  max_flow.run();
+
+  CutMap min_cut3(g);
+  max_flow.minCutMap(min_cut3);
+  min_cut_value=cutValue(g, min_cut3, cap);
+
+  check(max_flow.flowValue() == min_cut_value,
+        "The max flow value or the min cut value is wrong.");
+}
+
+// Struct for calling start functions of a general max flow algorithm
+template <typename MF>
+struct GeneralStartFunctions {
+
+  static void startFirstPhase(MF& mf) {
+    mf.start();
+  }
+
+  static void startSecondPhase(MF& mf) {
+    ::lemon::ignore_unused_variable_warning(mf);
+  }
+
+};
+
+// Struct for calling start functions of Preflow
+template <typename MF>
+struct PreflowStartFunctions {
+
+  static void startFirstPhase(MF& mf) {
+    mf.startFirstPhase();
+  }
+
+  static void startSecondPhase(MF& mf) {
+    mf.startSecondPhase();
+  }
+
+};
+
+int main() {
+
+  typedef concepts::Digraph GR;
+  typedef concepts::ReadMap<GR::Arc, int> CM1;
+  typedef concepts::ReadMap<GR::Arc, double> CM2;
+
+  // Check the interface of Preflow
+  checkConcept< MaxFlowClassConcept<GR, CM1>,
+                Preflow<GR, CM1> >();
+  checkConcept< MaxFlowClassConcept<GR, CM2>,
+                Preflow<GR, CM2> >();
+
+  // Check the interface of EdmondsKarp
+  checkConcept< MaxFlowClassConcept<GR, CM1>,
+                EdmondsKarp<GR, CM1> >();
+  checkConcept< MaxFlowClassConcept<GR, CM2>,
+                EdmondsKarp<GR, CM2> >();
+
+  // Check Preflow
+  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1;
+  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
+  checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >();
+  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >();
+  initFlowTest();
+
+  // Check EdmondsKarp
+  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
+  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2;
+  checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >();
+  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >();
+
+  initFlowTest();
+
+  return 0;
+}
diff --git a/test/min_cost_arborescence_test.cc b/test/min_cost_arborescence_test.cc
new file mode 100644
index 0000000..3a5ea36
--- /dev/null
+++ b/test/min_cost_arborescence_test.cc
@@ -0,0 +1,207 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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 <set>
+#include <vector>
+#include <iterator>
+
+#include <lemon/smart_graph.h>
+#include <lemon/min_cost_arborescence.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/concepts/digraph.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace std;
+
+const char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "     label  cost\n"
+  "1 8  0      107\n"
+  "0 3  1      70\n"
+  "2 1  2      46\n"
+  "4 1  3      28\n"
+  "4 4  4      91\n"
+  "3 9  5      76\n"
+  "9 8  6      61\n"
+  "8 1  7      39\n"
+  "9 8  8      74\n"
+  "8 0  9      39\n"
+  "4 3  10     45\n"
+  "2 2  11     34\n"
+  "0 1  12     100\n"
+  "6 3  13     95\n"
+  "4 1  14     22\n"
+  "1 1  15     31\n"
+  "7 2  16     51\n"
+  "2 6  17     29\n"
+  "8 3  18     115\n"
+  "6 9  19     32\n"
+  "1 1  20     60\n"
+  "0 3  21     40\n"
+  "@attributes\n"
+  "source 0\n";
+
+
+void checkMinCostArborescenceCompile()
+{
+  typedef double VType;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
+  typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
+
+  typedef MinCostArborescence<Digraph, CostMap>::
+            SetArborescenceMap<ArbMap>::
+            SetPredMap<PredMap>::Create MinCostArbType;
+
+  Digraph g;
+  Node s, n;
+  Arc e;
+  VType c;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(c,b);
+  int i;
+  CostMap cost;
+  ArbMap arb;
+  PredMap pred;
+
+  MinCostArbType mcarb_test(g, cost);
+  const MinCostArbType& const_mcarb_test = mcarb_test;
+
+  mcarb_test
+    .arborescenceMap(arb)
+    .predMap(pred)
+    .run(s);
+
+  mcarb_test.init();
+  mcarb_test.addSource(s);
+  mcarb_test.start();
+  n = mcarb_test.processNextNode();
+  b = const_mcarb_test.emptyQueue();
+  i = const_mcarb_test.queueSize();
+
+  c = const_mcarb_test.arborescenceCost();
+  b = const_mcarb_test.arborescence(e);
+  e = const_mcarb_test.pred(n);
+  const MinCostArbType::ArborescenceMap &am =
+    const_mcarb_test.arborescenceMap();
+  const MinCostArbType::PredMap &pm =
+    const_mcarb_test.predMap();
+  b = const_mcarb_test.reached(n);
+  b = const_mcarb_test.processed(n);
+
+  i = const_mcarb_test.dualNum();
+  c = const_mcarb_test.dualValue();
+  i = const_mcarb_test.dualSize(i);
+  c = const_mcarb_test.dualValue(i);
+
+  ::lemon::ignore_unused_variable_warning(am);
+  ::lemon::ignore_unused_variable_warning(pm);
+}
+
+int main() {
+  typedef SmartDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+
+  typedef Digraph::ArcMap<double> CostMap;
+
+  Digraph digraph;
+  CostMap cost(digraph);
+  Node source;
+
+  std::istringstream is(test_lgf);
+  digraphReader(digraph, is).
+    arcMap("cost", cost).
+    node("source", source).run();
+
+  MinCostArborescence<Digraph, CostMap> mca(digraph, cost);
+  mca.run(source);
+
+  vector<pair<double, set<Node> > > dualSolution(mca.dualNum());
+
+  for (int i = 0; i < mca.dualNum(); ++i) {
+    dualSolution[i].first = mca.dualValue(i);
+    for (MinCostArborescence<Digraph, CostMap>::DualIt it(mca, i);
+         it != INVALID; ++it) {
+      dualSolution[i].second.insert(it);
+    }
+  }
+
+  for (ArcIt it(digraph); it != INVALID; ++it) {
+    if (mca.reached(digraph.source(it))) {
+      double sum = 0.0;
+      for (int i = 0; i < int(dualSolution.size()); ++i) {
+        if (dualSolution[i].second.find(digraph.target(it))
+            != dualSolution[i].second.end() &&
+            dualSolution[i].second.find(digraph.source(it))
+            == dualSolution[i].second.end()) {
+          sum += dualSolution[i].first;
+        }
+      }
+      if (mca.arborescence(it)) {
+        check(sum == cost[it], "Invalid dual solution");
+      }
+      check(sum <= cost[it], "Invalid dual solution");
+    }
+  }
+
+
+  check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
+
+  check(mca.reached(source), "Invalid arborescence");
+  for (ArcIt a(digraph); a != INVALID; ++a) {
+    check(!mca.reached(digraph.source(a)) ||
+          mca.reached(digraph.target(a)), "Invalid arborescence");
+  }
+
+  for (NodeIt n(digraph); n != INVALID; ++n) {
+    if (!mca.reached(n)) continue;
+    int cnt = 0;
+    for (InArcIt a(digraph, n); a != INVALID; ++a) {
+      if (mca.arborescence(a)) {
+        check(mca.pred(n) == a, "Invalid arborescence");
+        ++cnt;
+      }
+    }
+    check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
+  }
+
+  Digraph::ArcMap<bool> arborescence(digraph);
+  check(mca.arborescenceCost() ==
+        minCostArborescence(digraph, cost, source, arborescence),
+        "Wrong result of the function interface");
+
+  return 0;
+}
diff --git a/test/min_cost_flow_test.cc b/test/min_cost_flow_test.cc
new file mode 100644
index 0000000..15dcf54
--- /dev/null
+++ b/test/min_cost_flow_test.cc
@@ -0,0 +1,548 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <limits>
+
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+
+#include <lemon/network_simplex.h>
+#include <lemon/capacity_scaling.h>
+#include <lemon/cost_scaling.h>
+#include <lemon/cycle_canceling.h>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/heap.h>
+#include <lemon/concept_check.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+// Test networks
+char test_lgf[] =
+  "@nodes\n"
+  "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
+  "    1    20   27    0   30   20   30\n"
+  "    2    -4    0    0    0   -8   -3\n"
+  "    3     0    0    0    0    0    0\n"
+  "    4     0    0    0    0    0    0\n"
+  "    5     9    0    0    0    6   11\n"
+  "    6    -6    0    0    0   -5   -6\n"
+  "    7     0    0    0    0    0    0\n"
+  "    8     0    0    0    0    0    3\n"
+  "    9     3    0    0    0    0    0\n"
+  "   10    -2    0    0    0   -7   -2\n"
+  "   11     0    0    0    0  -10    0\n"
+  "   12   -20  -27    0  -30  -30  -20\n"
+  "\n"
+  "@arcs\n"
+  "       cost  cap low1 low2 low3\n"
+  " 1  2    70   11    0    8    8\n"
+  " 1  3   150    3    0    1    0\n"
+  " 1  4    80   15    0    2    2\n"
+  " 2  8    80   12    0    0    0\n"
+  " 3  5   140    5    0    3    1\n"
+  " 4  6    60   10    0    1    0\n"
+  " 4  7    80    2    0    0    0\n"
+  " 4  8   110    3    0    0    0\n"
+  " 5  7    60   14    0    0    0\n"
+  " 5 11   120   12    0    0    0\n"
+  " 6  3     0    3    0    0    0\n"
+  " 6  9   140    4    0    0    0\n"
+  " 6 10    90    8    0    0    0\n"
+  " 7  1    30    5    0    0   -5\n"
+  " 8 12    60   16    0    4    3\n"
+  " 9 12    50    6    0    0    0\n"
+  "10 12    70   13    0    5    2\n"
+  "10  2   100    7    0    0    0\n"
+  "10  7    60   10    0    0   -3\n"
+  "11 10    20   14    0    6  -20\n"
+  "12 11    30   10    0    0  -10\n"
+  "\n"
+  "@attributes\n"
+  "source 1\n"
+  "target 12\n";
+
+char test_neg1_lgf[] =
+  "@nodes\n"
+  "label   sup\n"
+  "    1   100\n"
+  "    2     0\n"
+  "    3     0\n"
+  "    4  -100\n"
+  "    5     0\n"
+  "    6     0\n"
+  "    7     0\n"
+  "@arcs\n"
+  "      cost   low1   low2\n"
+  "1 2    100      0      0\n"
+  "1 3     30      0      0\n"
+  "2 4     20      0      0\n"
+  "3 4     80      0      0\n"
+  "3 2     50      0      0\n"
+  "5 3     10      0      0\n"
+  "5 6     80      0   1000\n"
+  "6 7     30      0  -1000\n"
+  "7 5   -120      0      0\n";
+
+char test_neg2_lgf[] =
+  "@nodes\n"
+  "label   sup\n"
+  "    1   100\n"
+  "    2  -300\n"
+  "@arcs\n"
+  "      cost\n"
+  "1 2     -1\n";
+
+
+// Test data
+typedef ListDigraph Digraph;
+DIGRAPH_TYPEDEFS(ListDigraph);
+
+Digraph gr;
+Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
+Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
+ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
+Node v, w;
+
+Digraph neg1_gr;
+Digraph::ArcMap<int> neg1_c(neg1_gr), neg1_l1(neg1_gr), neg1_l2(neg1_gr);
+ConstMap<Arc, int> neg1_u1(std::numeric_limits<int>::max()), neg1_u2(5000);
+Digraph::NodeMap<int> neg1_s(neg1_gr);
+
+Digraph neg2_gr;
+Digraph::ArcMap<int> neg2_c(neg2_gr);
+ConstMap<Arc, int> neg2_l(0), neg2_u(1000);
+Digraph::NodeMap<int> neg2_s(neg2_gr);
+
+
+enum SupplyType {
+  EQ,
+  GEQ,
+  LEQ
+};
+
+
+// Check the interface of an MCF algorithm
+template <typename GR, typename Value, typename Cost>
+class McfClassConcept
+{
+public:
+
+  template <typename MCF>
+  struct Constraints {
+    void constraints() {
+      checkConcept<concepts::Digraph, GR>();
+
+      const Constraints& me = *this;
+
+      MCF mcf(me.g);
+      const MCF& const_mcf = mcf;
+
+      b = mcf.reset().resetParams()
+             .lowerMap(me.lower)
+             .upperMap(me.upper)
+             .costMap(me.cost)
+             .supplyMap(me.sup)
+             .stSupply(me.n, me.n, me.k)
+             .run();
+
+      c = const_mcf.totalCost();
+      x = const_mcf.template totalCost<double>();
+      v = const_mcf.flow(me.a);
+      c = const_mcf.potential(me.n);
+      const_mcf.flowMap(fm);
+      const_mcf.potentialMap(pm);
+    }
+
+    typedef typename GR::Node Node;
+    typedef typename GR::Arc Arc;
+    typedef concepts::ReadMap<Node, Value> NM;
+    typedef concepts::ReadMap<Arc, Value> VAM;
+    typedef concepts::ReadMap<Arc, Cost> CAM;
+    typedef concepts::WriteMap<Arc, Value> FlowMap;
+    typedef concepts::WriteMap<Node, Cost> PotMap;
+
+    GR g;
+    VAM lower;
+    VAM upper;
+    CAM cost;
+    NM sup;
+    Node n;
+    Arc a;
+    Value k;
+
+    FlowMap fm;
+    PotMap pm;
+    bool b;
+    double x;
+    typename MCF::Value v;
+    typename MCF::Cost c;
+  };
+
+};
+
+
+// Check the feasibility of the given flow (primal soluiton)
+template < typename GR, typename LM, typename UM,
+           typename SM, typename FM >
+bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
+                const SM& supply, const FM& flow,
+                SupplyType type = EQ )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  for (ArcIt e(gr); e != INVALID; ++e) {
+    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
+  }
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    typename SM::Value sum = 0;
+    for (OutArcIt e(gr, n); e != INVALID; ++e)
+      sum += flow[e];
+    for (InArcIt e(gr, n); e != INVALID; ++e)
+      sum -= flow[e];
+    bool b = (type ==  EQ && sum == supply[n]) ||
+             (type == GEQ && sum >= supply[n]) ||
+             (type == LEQ && sum <= supply[n]);
+    if (!b) return false;
+  }
+
+  return true;
+}
+
+// Check the feasibility of the given potentials (dual soluiton)
+// using the "Complementary Slackness" optimality condition
+template < typename GR, typename LM, typename UM,
+           typename CM, typename SM, typename FM, typename PM >
+bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
+                     const CM& cost, const SM& supply, const FM& flow,
+                     const PM& pi, SupplyType type )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  bool opt = true;
+  for (ArcIt e(gr); opt && e != INVALID; ++e) {
+    typename CM::Value red_cost =
+      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
+    opt = red_cost == 0 ||
+          (red_cost > 0 && flow[e] == lower[e]) ||
+          (red_cost < 0 && flow[e] == upper[e]);
+  }
+
+  for (NodeIt n(gr); opt && n != INVALID; ++n) {
+    typename SM::Value sum = 0;
+    for (OutArcIt e(gr, n); e != INVALID; ++e)
+      sum += flow[e];
+    for (InArcIt e(gr, n); e != INVALID; ++e)
+      sum -= flow[e];
+    if (type != LEQ) {
+      opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
+    } else {
+      opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
+    }
+  }
+
+  return opt;
+}
+
+// Check whether the dual cost is equal to the primal cost
+template < typename GR, typename LM, typename UM,
+           typename CM, typename SM, typename PM >
+bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
+                    const CM& cost, const SM& supply, const PM& pi,
+                    typename CM::Value total )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  typename CM::Value dual_cost = 0;
+  SM red_supply(gr);
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    red_supply[n] = supply[n];
+  }
+  for (ArcIt a(gr); a != INVALID; ++a) {
+    if (lower[a] != 0) {
+      dual_cost += lower[a] * cost[a];
+      red_supply[gr.source(a)] -= lower[a];
+      red_supply[gr.target(a)] += lower[a];
+    }
+  }
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    dual_cost -= red_supply[n] * pi[n];
+  }
+  for (ArcIt a(gr); a != INVALID; ++a) {
+    typename CM::Value red_cost =
+      cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
+    dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
+  }
+
+  return dual_cost == total;
+}
+
+// Run a minimum cost flow algorithm and check the results
+template < typename MCF, typename GR,
+           typename LM, typename UM,
+           typename CM, typename SM,
+           typename PT >
+void checkMcf( const MCF& mcf, PT mcf_result,
+               const GR& gr, const LM& lower, const UM& upper,
+               const CM& cost, const SM& supply,
+               PT result, bool optimal, typename CM::Value total,
+               const std::string &test_id = "",
+               SupplyType type = EQ )
+{
+  check(mcf_result == result, "Wrong result " + test_id);
+  if (optimal) {
+    typename GR::template ArcMap<typename SM::Value> flow(gr);
+    typename GR::template NodeMap<typename CM::Value> pi(gr);
+    mcf.flowMap(flow);
+    mcf.potentialMap(pi);
+    check(checkFlow(gr, lower, upper, supply, flow, type),
+          "The flow is not feasible " + test_id);
+    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
+    check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
+          "Wrong potentials " + test_id);
+    check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
+          "Wrong dual cost " + test_id);
+  }
+}
+
+template < typename MCF, typename Param >
+void runMcfGeqTests( Param param,
+                     const std::string &test_str = "",
+                     bool full_neg_cost_support = false )
+{
+  MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr);
+
+  // Basic tests
+  mcf1.upperMap(u).costMap(c).supplyMap(s1);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s1,
+           mcf1.OPTIMAL, true,     5240, test_str + "-1");
+  mcf1.stSupply(v, w, 27);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s2,
+           mcf1.OPTIMAL, true,     7620, test_str + "-2");
+  mcf1.lowerMap(l2).supplyMap(s1);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s1,
+           mcf1.OPTIMAL, true,     5970, test_str + "-3");
+  mcf1.stSupply(v, w, 27);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2,
+           mcf1.OPTIMAL, true,     8010, test_str + "-4");
+  mcf1.resetParams().supplyMap(s1);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1,
+           mcf1.OPTIMAL, true,       74, test_str + "-5");
+  mcf1.lowerMap(l2).stSupply(v, w, 27);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, cu, cc, s2,
+           mcf1.OPTIMAL, true,       94, test_str + "-6");
+  mcf1.reset();
+  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s3,
+           mcf1.OPTIMAL, true,        0, test_str + "-7");
+  mcf1.lowerMap(l2).upperMap(u);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, cc, s3,
+           mcf1.INFEASIBLE, false,    0, test_str + "-8");
+  mcf1.lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
+  checkMcf(mcf1, mcf1.run(param), gr, l3, u, c, s4,
+           mcf1.OPTIMAL, true,     6360, test_str + "-9");
+
+  // Tests for the GEQ form
+  mcf1.resetParams().upperMap(u).costMap(c).supplyMap(s5);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5,
+           mcf1.OPTIMAL, true,     3530, test_str + "-10", GEQ);
+  mcf1.lowerMap(l2);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
+           mcf1.OPTIMAL, true,     4540, test_str + "-11", GEQ);
+  mcf1.supplyMap(s6);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
+           mcf1.INFEASIBLE, false,    0, test_str + "-12", GEQ);
+
+  // Tests with negative costs
+  mcf2.lowerMap(neg1_l1).costMap(neg1_c).supplyMap(neg1_s);
+  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u1, neg1_c, neg1_s,
+           mcf2.UNBOUNDED, false,     0, test_str + "-13");
+  mcf2.upperMap(neg1_u2);
+  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s,
+           mcf2.OPTIMAL, true,   -40000, test_str + "-14");
+  mcf2.resetParams().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s);
+  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s,
+           mcf2.UNBOUNDED, false,     0, test_str + "-15");
+
+  mcf3.costMap(neg2_c).supplyMap(neg2_s);
+  if (full_neg_cost_support) {
+    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
+             mcf3.OPTIMAL, true,   -300, test_str + "-16", GEQ);
+  } else {
+    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
+             mcf3.UNBOUNDED, false,   0, test_str + "-17", GEQ);
+  }
+  mcf3.upperMap(neg2_u);
+  checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
+           mcf3.OPTIMAL, true,     -300, test_str + "-18", GEQ);
+
+  // Tests for empty graph
+  Digraph gr0;
+  MCF mcf0(gr0);
+  mcf0.run(param);
+  check(mcf0.totalCost() == 0, "Wrong total cost");  
+}
+
+template < typename MCF, typename Param >
+void runMcfLeqTests( Param param,
+                     const std::string &test_str = "" )
+{
+  // Tests for the LEQ form
+  MCF mcf1(gr);
+  mcf1.supplyType(mcf1.LEQ);
+  mcf1.upperMap(u).costMap(c).supplyMap(s6);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s6,
+           mcf1.OPTIMAL, true,   5080, test_str + "-19", LEQ);
+  mcf1.lowerMap(l2);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
+           mcf1.OPTIMAL, true,   5930, test_str + "-20", LEQ);
+  mcf1.supplyMap(s5);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
+           mcf1.INFEASIBLE, false,  0, test_str + "-21", LEQ);
+}
+
+
+int main()
+{
+  // Read the test networks
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(gr, input)
+    .arcMap("cost", c)
+    .arcMap("cap", u)
+    .arcMap("low1", l1)
+    .arcMap("low2", l2)
+    .arcMap("low3", l3)
+    .nodeMap("sup1", s1)
+    .nodeMap("sup2", s2)
+    .nodeMap("sup3", s3)
+    .nodeMap("sup4", s4)
+    .nodeMap("sup5", s5)
+    .nodeMap("sup6", s6)
+    .node("source", v)
+    .node("target", w)
+    .run();
+
+  std::istringstream neg_inp1(test_neg1_lgf);
+  DigraphReader<Digraph>(neg1_gr, neg_inp1)
+    .arcMap("cost", neg1_c)
+    .arcMap("low1", neg1_l1)
+    .arcMap("low2", neg1_l2)
+    .nodeMap("sup", neg1_s)
+    .run();
+
+  std::istringstream neg_inp2(test_neg2_lgf);
+  DigraphReader<Digraph>(neg2_gr, neg_inp2)
+    .arcMap("cost", neg2_c)
+    .nodeMap("sup", neg2_s)
+    .run();
+
+  // Check the interface of NetworkSimplex
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  NetworkSimplex<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  NetworkSimplex<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  NetworkSimplex<GR, int, double> >();
+  }
+
+  // Check the interface of CapacityScaling
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  CapacityScaling<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  CapacityScaling<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  CapacityScaling<GR, int, double> >();
+    typedef CapacityScaling<GR>::
+      SetHeap<concepts::Heap<int, RangeMap<int> > >::Create CAS;
+    checkConcept< McfClassConcept<GR, int, int>, CAS >();
+  }
+
+  // Check the interface of CostScaling
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  CostScaling<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  CostScaling<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  CostScaling<GR, int, double> >();
+    typedef CostScaling<GR>::
+      SetLargeCost<double>::Create COS;
+    checkConcept< McfClassConcept<GR, int, int>, COS >();
+  }
+
+  // Check the interface of CycleCanceling
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  CycleCanceling<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  CycleCanceling<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  CycleCanceling<GR, int, double> >();
+  }
+
+  // Test NetworkSimplex
+  {
+    typedef NetworkSimplex<Digraph> MCF;
+    runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true);
+    runMcfLeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE");
+    runMcfGeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE", true);
+    runMcfLeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE");
+    runMcfGeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS", true);
+    runMcfLeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS");
+    runMcfGeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL", true);
+    runMcfLeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL");
+    runMcfGeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL", true);
+    runMcfLeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL");
+  }
+
+  // Test CapacityScaling
+  {
+    typedef CapacityScaling<Digraph> MCF;
+    runMcfGeqTests<MCF>(0, "SSP");
+    runMcfGeqTests<MCF>(2, "CAS");
+  }
+
+  // Test CostScaling
+  {
+    typedef CostScaling<Digraph> MCF;
+    runMcfGeqTests<MCF>(MCF::PUSH, "COS-PR");
+    runMcfGeqTests<MCF>(MCF::AUGMENT, "COS-AR");
+    runMcfGeqTests<MCF>(MCF::PARTIAL_AUGMENT, "COS-PAR");
+  }
+
+  // Test CycleCanceling
+  {
+    typedef CycleCanceling<Digraph> MCF;
+    runMcfGeqTests<MCF>(MCF::SIMPLE_CYCLE_CANCELING, "SCC");
+    runMcfGeqTests<MCF>(MCF::MINIMUM_MEAN_CYCLE_CANCELING, "MMCC");
+    runMcfGeqTests<MCF>(MCF::CANCEL_AND_TIGHTEN, "CAT");
+  }
+
+  return 0;
+}
diff --git a/test/min_mean_cycle_test.cc b/test/min_mean_cycle_test.cc
new file mode 100644
index 0000000..e752454
--- /dev/null
+++ b/test/min_mean_cycle_test.cc
@@ -0,0 +1,223 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+
+#include <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/path.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concept_check.h>
+
+#include <lemon/karp_mmc.h>
+#include <lemon/hartmann_orlin_mmc.h>
+#include <lemon/howard_mmc.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@arcs\n"
+  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
+  "1 2    1    1    1    1   0  0  0  0\n"
+  "2 4    5    5    5    5   1  0  0  0\n"
+  "2 3    8    8    8    8   0  0  0  0\n"
+  "3 2   -2    0    0    0   1  0  0  0\n"
+  "3 4    4    4    4    4   0  0  0  0\n"
+  "3 7   -4   -4   -4   -4   0  0  0  0\n"
+  "4 1    2    2    2    2   0  0  0  0\n"
+  "4 3    3    3    3    3   1  0  0  0\n"
+  "4 4    3    3    0    0   0  0  1  0\n"
+  "5 2    4    4    4    4   0  0  0  0\n"
+  "5 6    3    3    3    3   0  1  0  0\n"
+  "6 5    2    2    2    2   0  1  0  0\n"
+  "6 4   -1   -1   -1   -1   0  0  0  0\n"
+  "6 7    1    1    1    1   0  0  0  0\n"
+  "7 7    4    4    4   -1   0  0  0  1\n";
+
+
+// Check the interface of an MMC algorithm
+template <typename GR, typename Cost>
+struct MmcClassConcept
+{
+  template <typename MMC>
+  struct Constraints {
+    void constraints() {
+      const Constraints& me = *this;
+
+      typedef typename MMC
+        ::template SetPath<ListPath<GR> >
+        ::template SetLargeCost<Cost>
+        ::Create MmcAlg;
+      MmcAlg mmc(me.g, me.cost);
+      const MmcAlg& const_mmc = mmc;
+
+      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
+      mmc.tolerance(tol);
+
+      b = mmc.cycle(p).run();
+      b = mmc.findCycleMean();
+      b = mmc.findCycle();
+
+      v = const_mmc.cycleCost();
+      i = const_mmc.cycleSize();
+      d = const_mmc.cycleMean();
+      p = const_mmc.cycle();
+    }
+
+    typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
+
+    GR g;
+    CM cost;
+    ListPath<GR> p;
+    Cost v;
+    int i;
+    double d;
+    bool b;
+  };
+};
+
+// Perform a test with the given parameters
+template <typename MMC>
+void checkMmcAlg(const SmartDigraph& gr,
+                 const SmartDigraph::ArcMap<int>& lm,
+                 const SmartDigraph::ArcMap<int>& cm,
+                 int cost, int size) {
+  MMC alg(gr, lm);
+  check(alg.findCycleMean(), "Wrong result");
+  check(alg.cycleMean() == static_cast<double>(cost) / size,
+        "Wrong cycle mean");
+  alg.findCycle();
+  check(alg.cycleCost() == cost && alg.cycleSize() == size,
+        "Wrong path");
+  SmartDigraph::ArcMap<int> cycle(gr, 0);
+  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
+    ++cycle[a];
+  }
+  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
+    check(cm[a] == cycle[a], "Wrong path");
+  }
+}
+
+// Class for comparing types
+template <typename T1, typename T2>
+struct IsSameType {
+  static const int result = 0;
+};
+
+template <typename T>
+struct IsSameType<T,T> {
+  static const int result = 1;
+};
+
+
+int main() {
+  #ifdef LEMON_HAVE_LONG_LONG
+    typedef long long long_int;
+  #else
+    typedef long long_int;
+  #endif
+
+  // Check the interface
+  {
+    typedef concepts::Digraph GR;
+
+    // KarpMmc
+    checkConcept< MmcClassConcept<GR, int>,
+                  KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    // HartmannOrlinMmc
+    checkConcept< MmcClassConcept<GR, int>,
+                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    // HowardMmc
+    checkConcept< MmcClassConcept<GR, int>,
+                  HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
+           ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
+    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
+           ::LargeCost, double>::result == 1), "Wrong LargeCost type");
+  }
+
+  // Run various tests
+  {
+    typedef SmartDigraph GR;
+    DIGRAPH_TYPEDEFS(GR);
+
+    GR gr;
+    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
+    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
+
+    std::istringstream input(test_lgf);
+    digraphReader(gr, input).
+      arcMap("len1", l1).
+      arcMap("len2", l2).
+      arcMap("len3", l3).
+      arcMap("len4", l4).
+      arcMap("c1", c1).
+      arcMap("c2", c2).
+      arcMap("c3", c3).
+      arcMap("c4", c4).
+      run();
+
+    // Karp
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+
+    // HartmannOrlin
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+
+    // Howard
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+
+    // Howard with iteration limit
+    HowardMmc<GR, IntArcMap> mmc(gr, l1);
+    check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT),
+      "Wrong termination cause");
+    check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL),
+      "Wrong termination cause");
+  }
+
+  return 0;
+}
diff --git a/test/mip_test.cc b/test/mip_test.cc
new file mode 100644
index 0000000..641ceb5
--- /dev/null
+++ b/test/mip_test.cc
@@ -0,0 +1,171 @@
+/* -*- 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 "test_tools.h"
+
+#include <lemon/config.h>
+
+#ifdef LEMON_HAVE_CPLEX
+#include <lemon/cplex.h>
+#endif
+
+#ifdef LEMON_HAVE_GLPK
+#include <lemon/glpk.h>
+#endif
+
+#ifdef LEMON_HAVE_CBC
+#include <lemon/cbc.h>
+#endif
+
+#ifdef LEMON_HAVE_MIP
+#include <lemon/lp.h>
+#endif
+
+
+using namespace lemon;
+
+void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
+                   double exp_opt) {
+  using std::string;
+
+  mip.solve();
+  //int decimal,sign;
+  std::ostringstream buf;
+  buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
+
+
+  //  itoa(stat,buf1, 10);
+  check(mip.type()==stat, buf.str());
+
+  if (stat ==  MipSolver::OPTIMAL) {
+    std::ostringstream sbuf;
+    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)
+  }
+}
+
+void aTest(MipSolver& mip)
+{
+  //The following example is very simple
+
+
+  typedef MipSolver::Row Row;
+  typedef MipSolver::Col Col;
+
+
+  Col x1 = mip.addCol();
+  Col x2 = mip.addCol();
+
+
+  //Objective function
+  mip.obj(x1);
+
+  mip.max();
+
+  //Unconstrained optimization
+  mip.solve();
+  //Check it out!
+
+  //Constraints
+  mip.addRow(2 * x1 + x2 <= 2);
+  Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
+
+  //Nonnegativity of the variable x1
+  mip.colLowerBound(x1, 0);
+
+
+  //Maximization of x1
+  //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
+  double expected_opt=4.0/5.0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+
+  //Restrict x2 to integer
+  mip.colType(x2,MipSolver::INTEGER);
+  expected_opt=1.0/2.0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+
+  //Restrict both to integer
+  mip.colType(x1,MipSolver::INTEGER);
+  expected_opt=0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+  //Erase a variable
+  mip.erase(x2);
+  mip.rowUpperBound(y2, 8);
+  expected_opt=1;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+}
+
+
+template<class MIP>
+void cloneTest()
+{
+
+  MIP* mip = new MIP();
+  MIP* mipnew = mip->newSolver();
+  MIP* mipclone = mip->cloneSolver();
+  delete mip;
+  delete mipnew;
+  delete mipclone;
+}
+
+int main()
+{
+
+#ifdef LEMON_HAVE_MIP
+  {
+    Mip mip1;
+    aTest(mip1);
+    cloneTest<Mip>();
+  }
+#endif
+
+#ifdef LEMON_HAVE_GLPK
+  {
+    GlpkMip mip1;
+    aTest(mip1);
+    cloneTest<GlpkMip>();
+  }
+#endif
+
+#ifdef LEMON_HAVE_CPLEX
+  try {
+    CplexMip mip2;
+    aTest(mip2);
+    cloneTest<CplexMip>();
+  } catch (CplexEnv::LicenseError& error) {
+    check(false, error.what());
+  }
+#endif
+
+#ifdef LEMON_HAVE_CBC
+  {
+    CbcMip mip1;
+    aTest(mip1);
+    cloneTest<CbcMip>();
+  }
+#endif
+
+  return 0;
+
+}
diff --git a/test/nagamochi_ibaraki_test.cc b/test/nagamochi_ibaraki_test.cc
new file mode 100644
index 0000000..94ec29d
--- /dev/null
+++ b/test/nagamochi_ibaraki_test.cc
@@ -0,0 +1,142 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <sstream>
+
+#include <lemon/smart_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/nagamochi_ibaraki.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace std;
+
+const std::string lgf =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@edges\n"
+  "     cap1 cap2 cap3\n"
+  "0 1  1    1    1   \n"
+  "0 2  2    2    4   \n"
+  "1 2  4    4    4   \n"
+  "3 4  1    1    1   \n"
+  "3 5  2    2    4   \n"
+  "4 5  4    4    4   \n"
+  "2 3  1    6    6   \n";
+
+void checkNagamochiIbarakiCompile()
+{
+  typedef int Value;
+  typedef concepts::Graph Graph;
+
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef concepts::ReadMap<Edge, Value> CapMap;
+  typedef concepts::WriteMap<Node, bool> CutMap;
+
+  Graph g;
+  Node n;
+  CapMap cap;
+  CutMap cut;
+  Value v;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(v,b);
+
+  NagamochiIbaraki<Graph, CapMap> ni_test(g, cap);
+  const NagamochiIbaraki<Graph, CapMap>& const_ni_test = ni_test;
+
+  ni_test.init();
+  ni_test.start();
+  b = ni_test.processNextPhase();
+  ni_test.run();
+
+  v = const_ni_test.minCutValue();
+  v = const_ni_test.minCutMap(cut);
+}
+
+template <typename Graph, typename CapMap, typename CutMap>
+typename CapMap::Value
+  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
+{
+  typename CapMap::Value sum = 0;
+  for (typename Graph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (cut[graph.u(e)] != cut[graph.v(e)]) {
+      sum += cap[e];
+    }
+  }
+  return sum;
+}
+
+int main() {
+  SmartGraph graph;
+  SmartGraph::EdgeMap<int> cap1(graph), cap2(graph), cap3(graph);
+  SmartGraph::NodeMap<bool> cut(graph);
+
+  istringstream input(lgf);
+  graphReader(graph, input)
+    .edgeMap("cap1", cap1)
+    .edgeMap("cap2", cap2)
+    .edgeMap("cap3", cap3)
+    .run();
+
+  {
+    NagamochiIbaraki<SmartGraph> ni(graph, cap1);
+    ni.run();
+    ni.minCutMap(cut);
+
+    check(ni.minCutValue() == 1, "Wrong cut value");
+    check(ni.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
+  }
+  {
+    NagamochiIbaraki<SmartGraph> ni(graph, cap2);
+    ni.run();
+    ni.minCutMap(cut);
+
+    check(ni.minCutValue() == 3, "Wrong cut value");
+    check(ni.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
+  }
+  {
+    NagamochiIbaraki<SmartGraph> ni(graph, cap3);
+    ni.run();
+    ni.minCutMap(cut);
+
+    check(ni.minCutValue() == 5, "Wrong cut value");
+    check(ni.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
+  }
+  {
+    NagamochiIbaraki<SmartGraph>::SetUnitCapacity::Create ni(graph);
+    ni.run();
+    ni.minCutMap(cut);
+
+    ConstMap<SmartGraph::Edge, int> cap4(1);
+    check(ni.minCutValue() == 1, "Wrong cut value");
+    check(ni.minCutValue() == cutValue(graph, cap4, cut), "Wrong cut value");
+  }
+
+  return 0;
+}
diff --git a/test/path_test.cc b/test/path_test.cc
new file mode 100644
index 0000000..f2d9603
--- /dev/null
+++ b/test/path_test.cc
@@ -0,0 +1,339 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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 <string>
+#include <iostream>
+
+#include <lemon/concepts/path.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concept_check.h>
+
+#include <lemon/path.h>
+#include <lemon/list_graph.h>
+
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+template <typename GR>
+void checkConcepts() {
+  checkConcept<concepts::Path<GR>, concepts::Path<GR> >();
+  checkConcept<concepts::Path<GR>, Path<GR> >();
+  checkConcept<concepts::Path<GR>, SimplePath<GR> >();
+  checkConcept<concepts::Path<GR>, StaticPath<GR> >();
+  checkConcept<concepts::Path<GR>, ListPath<GR> >();
+}
+
+// Conecpt checking for path structures
+void checkPathConcepts() {
+  checkConcepts<concepts::Digraph>();
+  checkConcepts<ListDigraph>();
+}
+
+// Check if proper copy consructor is called (use valgrind for testing)
+template <typename GR, typename P1, typename P2>
+void checkCopy(typename GR::Arc a) {
+  P1 p;
+  p.addBack(a);
+  P1 q;
+  q = p;
+  P1 r(p);
+  P2 q2;
+  q2 = p;
+  P2 r2(p);
+}
+
+// Tests for copy constructors and assignment operators of paths
+void checkPathCopy() {
+  ListDigraph g;
+  ListDigraph::Arc a = g.addArc(g.addNode(), g.addNode());
+
+  typedef Path<ListDigraph> Path1;
+  typedef SimplePath<ListDigraph> Path2;
+  typedef ListPath<ListDigraph> Path3;
+  typedef StaticPath<ListDigraph> Path4;
+  checkCopy<ListDigraph, Path1, Path2>(a);
+  checkCopy<ListDigraph, Path1, Path3>(a);
+  checkCopy<ListDigraph, Path1, Path4>(a);
+  checkCopy<ListDigraph, Path2, Path1>(a);
+  checkCopy<ListDigraph, Path2, Path3>(a);
+  checkCopy<ListDigraph, Path2, Path4>(a);
+  checkCopy<ListDigraph, Path3, Path1>(a);
+  checkCopy<ListDigraph, Path3, Path2>(a);
+  checkCopy<ListDigraph, Path3, Path4>(a);
+}
+
+// Class for testing path functions
+class CheckPathFunctions {
+  typedef ListDigraph GR;
+  DIGRAPH_TYPEDEFS(GR);
+  GR gr;
+  const GR& cgr;
+  Node n1, n2, n3, n4;
+  Node tmp_n;
+  Arc a1, a2, a3, a4;
+  Arc tmp_a;
+
+public:
+
+  CheckPathFunctions() : cgr(gr) {
+    n1 = gr.addNode();
+    n2 = gr.addNode();
+    n3 = gr.addNode();
+    n4 = gr.addNode();
+    a1 = gr.addArc(n1, n2);
+    a2 = gr.addArc(n2, n3);
+    a3 = gr.addArc(n3, n4);
+    a4 = gr.addArc(n4, n1);
+  }
+
+  void run() {
+    checkBackAndFrontInsertablePath<Path<GR> >();
+    checkBackAndFrontInsertablePath<ListPath<GR> >();
+    checkBackInsertablePath<SimplePath<GR> >();
+
+    checkListPathSplitAndSplice();
+  }
+
+private:
+
+  template <typename P>
+  void checkBackInsertablePath() {
+
+    // Create and check empty path
+    P p;
+    const P& cp = p;
+    check(cp.empty(), "The path is not empty");
+    check(cp.length() == 0, "The path is not empty");
+//    check(cp.front() == INVALID, "Wrong front()");
+//    check(cp.back() == INVALID, "Wrong back()");
+    typename P::ArcIt ai(cp);
+    check(ai == INVALID, "Wrong ArcIt");
+    check(pathSource(cgr, cp) == INVALID, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == INVALID, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+    PathNodeIt<P> ni(cgr, cp);
+    check(ni == INVALID, "Wrong PathNodeIt");
+
+    // Check single-arc path
+    p.addBack(a1);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 1, "Wrong length");
+    check(cp.front() == a1, "Wrong front()");
+    check(cp.back() == a1, "Wrong back()");
+    check(cp.nth(0) == a1, "Wrong nth()");
+    ai = cp.nthIt(0);
+    check((tmp_a = ai) == a1, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    typename P::ArcIt ai2(cp);
+    check((tmp_a = ai2) == a1, "Wrong ArcIt");
+    check(++ai2 == INVALID, "Wrong ArcIt");
+    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+    PathNodeIt<P> ni2(cgr, cp);
+    check((tmp_n = ni2) == n1, "Wrong PathNodeIt");
+    check((tmp_n = ++ni2) == n2, "Wrong PathNodeIt");
+    check(++ni2 == INVALID, "Wrong PathNodeIt");
+
+    // Check adding more arcs
+    p.addBack(a2);
+    p.addBack(a3);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 3, "Wrong length");
+    check(cp.front() == a1, "Wrong front()");
+    check(cp.back() == a3, "Wrong back()");
+    check(cp.nth(0) == a1, "Wrong nth()");
+    check(cp.nth(1) == a2, "Wrong nth()");
+    check(cp.nth(2) == a3, "Wrong nth()");
+    typename P::ArcIt ai3(cp);
+    check((tmp_a = ai3) == a1, "Wrong ArcIt");
+    check((tmp_a = ++ai3) == a2, "Wrong nthIt()");
+    check((tmp_a = ++ai3) == a3, "Wrong nthIt()");
+    check(++ai3 == INVALID, "Wrong nthIt()");
+    ai = cp.nthIt(0);
+    check((tmp_a = ai) == a1, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
+    ai = cp.nthIt(2);
+    check((tmp_a = ai) == a3, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n4, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+    PathNodeIt<P> ni3(cgr, cp);
+    check((tmp_n = ni3) == n1, "Wrong PathNodeIt");
+    check((tmp_n = ++ni3) == n2, "Wrong PathNodeIt");
+    check((tmp_n = ++ni3) == n3, "Wrong PathNodeIt");
+    check((tmp_n = ++ni3) == n4, "Wrong PathNodeIt");
+    check(++ni3 == INVALID, "Wrong PathNodeIt");
+
+    // Check arc removal and addition
+    p.eraseBack();
+    p.eraseBack();
+    p.addBack(a2);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 2, "Wrong length");
+    check(cp.front() == a1, "Wrong front()");
+    check(cp.back() == a2, "Wrong back()");
+    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+
+    // Check clear()
+    p.clear();
+    check(cp.empty(), "The path is not empty");
+    check(cp.length() == 0, "The path is not empty");
+
+    // Check inconsistent path
+    p.addBack(a4);
+    p.addBack(a2);
+    p.addBack(a1);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 3, "Wrong length");
+    check(cp.front() == a4, "Wrong front()");
+    check(cp.back() == a1, "Wrong back()");
+    check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
+    check(!checkPath(cgr, cp), "Wrong checkPath()");
+  }
+
+  template <typename P>
+  void checkBackAndFrontInsertablePath() {
+
+    // Include back insertable test cases
+    checkBackInsertablePath<P>();
+
+    // Check front and back insertion
+    P p;
+    const P& cp = p;
+    p.addFront(a4);
+    p.addBack(a1);
+    p.addFront(a3);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 3, "Wrong length");
+    check(cp.front() == a3, "Wrong front()");
+    check(cp.back() == a1, "Wrong back()");
+    check(cp.nth(0) == a3, "Wrong nth()");
+    check(cp.nth(1) == a4, "Wrong nth()");
+    check(cp.nth(2) == a1, "Wrong nth()");
+    typename P::ArcIt ai(cp);
+    check((tmp_a = ai) == a3, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a1, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    ai = cp.nthIt(0);
+    check((tmp_a = ai) == a3, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    ai = cp.nthIt(2);
+    check((tmp_a = ai) == a1, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(pathSource(cgr, cp) == n3, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+
+    // Check eraseFront()
+    p.eraseFront();
+    p.addBack(a2);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 3, "Wrong length");
+    check(cp.front() == a4, "Wrong front()");
+    check(cp.back() == a2, "Wrong back()");
+    check(cp.nth(0) == a4, "Wrong nth()");
+    check(cp.nth(1) == a1, "Wrong nth()");
+    check(cp.nth(2) == a2, "Wrong nth()");
+    typename P::ArcIt ai2(cp);
+    check((tmp_a = ai2) == a4, "Wrong ArcIt");
+    check((tmp_a = ++ai2) == a1, "Wrong nthIt()");
+    check((tmp_a = ++ai2) == a2, "Wrong nthIt()");
+    check(++ai2 == INVALID, "Wrong nthIt()");
+    ai = cp.nthIt(0);
+    check((tmp_a = ai) == a4, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a1, "Wrong nthIt()");
+    ai = cp.nthIt(2);
+    check((tmp_a = ai) == a2, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+  }
+
+  void checkListPathSplitAndSplice() {
+
+    // Build a path with spliceFront() and spliceBack()
+    ListPath<GR> p1, p2, p3, p4;
+    p1.addBack(a3);
+    p1.addFront(a2);
+    p2.addBack(a1);
+    p1.spliceFront(p2);
+    p3.addFront(a4);
+    p1.spliceBack(p3);
+    check(p1.length() == 4, "Wrong length");
+    check(p1.front() == a1, "Wrong front()");
+    check(p1.back() == a4, "Wrong back()");
+    ListPath<GR>::ArcIt ai(p1);
+    check((tmp_a = ai) == a1, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a3, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(checkPath(cgr, p1), "Wrong checkPath()");
+
+    // Check split()
+    p1.split(p1.nthIt(2), p2);
+    check(p1.length() == 2, "Wrong length");
+    ai = p1.nthIt(0);
+    check((tmp_a = ai) == a1, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(checkPath(cgr, p1), "Wrong checkPath()");
+    check(p2.length() == 2, "Wrong length");
+    ai = p2.nthIt(0);
+    check((tmp_a = ai) == a3, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(checkPath(cgr, p2), "Wrong checkPath()");
+
+    // Check split() and splice()
+    p1.spliceFront(p2);
+    p1.split(p1.nthIt(2), p2);
+    p2.split(p2.nthIt(1), p3);
+    p2.spliceBack(p1);
+    p2.splice(p2.nthIt(1), p3);
+    check(p2.length() == 4, "Wrong length");
+    check(p2.front() == a1, "Wrong front()");
+    check(p2.back() == a4, "Wrong back()");
+    ai = p2.nthIt(0);
+    check((tmp_a = ai) == a1, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a3, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(checkPath(cgr, p2), "Wrong checkPath()");
+  }
+
+};
+
+int main() {
+  checkPathConcepts();
+  checkPathCopy();
+  CheckPathFunctions cpf;
+  cpf.run();
+
+  return 0;
+}
diff --git a/test/planarity_test.cc b/test/planarity_test.cc
new file mode 100644
index 0000000..0ac11ee
--- /dev/null
+++ b/test/planarity_test.cc
@@ -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;
+}
diff --git a/test/radix_sort_test.cc b/test/radix_sort_test.cc
new file mode 100644
index 0000000..6ae2deb
--- /dev/null
+++ b/test/radix_sort_test.cc
@@ -0,0 +1,266 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/time_measure.h>
+#include <lemon/smart_graph.h>
+#include <lemon/maps.h>
+#include <lemon/radix_sort.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+#include <vector>
+#include <list>
+#include <algorithm>
+
+using namespace lemon;
+
+static const int n = 10000;
+
+struct Negate {
+  typedef int argument_type;
+  typedef int result_type;
+  int operator()(int a) { return - a; }
+};
+
+int negate(int a) { return - a; }
+
+template<class T>
+bool isTheSame(T &a, T&b)
+{
+  typename T::iterator ai=a.begin();
+  typename T::iterator bi=b.begin();
+  for(;ai!=a.end()||bi!=b.end();++ai,++bi)
+    if(*ai!=*bi) return false;
+  return ai==a.end()&&bi==b.end();
+}
+
+template<class T>
+T listsort(typename T::iterator b, typename T::iterator e)
+{
+  if(b==e) return T();
+  typename T::iterator bn=b;
+  if(++bn==e) {
+    T l;
+    l.push_back(*b);
+    return l;
+  }
+  typename T::iterator m=b;
+  bool x=false;
+  for(typename T::iterator i=b;i!=e;++i,x=!x)
+    if(x) ++m;
+  T l1(listsort<T>(b,m));
+  T l2(listsort<T>(m,e));
+  T l;
+  while((!l1.empty())&&(!l2.empty()))
+    if(l1.front()<=l2.front())
+      {
+        l.push_back(l1.front());
+        l1.pop_front();
+      }
+    else {
+      l.push_back(l2.front());
+      l2.pop_front();
+    }
+  while(!l1.empty())
+    {
+      l.push_back(l1.front());
+      l1.pop_front();
+    }
+  while(!l2.empty())
+    {
+      l.push_back(l2.front());
+      l2.pop_front();
+    }
+  return l;
+}
+
+template<class T>
+void generateIntSequence(int n, T & data) {
+  int prime = 9973;
+  int root = 136, value = 1;
+  for (int i = 0; i < n; ++i) {
+    data.push_back(value - prime / 2);
+    value = (value * root) % prime;
+  }
+}
+
+template<class T>
+void generateCharSequence(int n, T & data) {
+  int prime = 251;
+  int root = 3, value = root;
+  for (int i = 0; i < n; ++i) {
+    data.push_back(static_cast<unsigned char>(value));
+    value = (value * root) % prime;
+  }
+}
+
+void checkRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    // radixSort(data2.begin(), data2.end(), Negate());
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+    // radixSort(data2.begin(), data2.end(), negate);
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+  {
+    std::list<int> data1;
+    generateIntSequence(n, data1);
+
+    std::list<int> data2(listsort<std::list<int> >(data1.begin(), data1.end()));
+
+    radixSort(data1.begin(), data1.end());
+
+    check(isTheSame(data1,data2), "Test failed");
+
+
+    // radixSort(data2.begin(), data2.end(), Negate());
+    // check(isTheSame(data1,data2), "Test failed");
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+    // radixSort(data2.begin(), data2.end(), negate);
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+  }
+
+  {
+    std::list<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::list<unsigned char> data2(listsort<std::list<unsigned char> >
+                                   (data1.begin(),
+                                    data1.end()));
+
+    radixSort(data1.begin(), data1.end());
+    check(isTheSame(data1,data2), "Test failed");
+
+  }
+}
+
+
+void checkStableRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    stableRadixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), Negate());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), negate);
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+  {
+    std::list<int> data1;
+    generateIntSequence(n, data1);
+
+    std::list<int> data2(listsort<std::list<int> >(data1.begin(),
+                                                   data1.end()));
+    stableRadixSort(data1.begin(), data1.end());
+    check(isTheSame(data1,data2), "Test failed");
+
+    // stableRadixSort(data2.begin(), data2.end(), Negate());
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+    // stableRadixSort(data2.begin(), data2.end(), negate);
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+  }
+
+  {
+    std::list<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::list<unsigned char> data2(listsort<std::list<unsigned char> >
+                                   (data1.begin(),
+                                    data1.end()));
+    radixSort(data1.begin(), data1.end());
+    check(isTheSame(data1,data2), "Test failed");
+
+  }
+}
+
+int main() {
+
+  checkRadixSort();
+  checkStableRadixSort();
+
+  return 0;
+}
diff --git a/test/random_test.cc b/test/random_test.cc
new file mode 100644
index 0000000..49dd8b6
--- /dev/null
+++ b/test/random_test.cc
@@ -0,0 +1,40 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/random.h>
+#include "test_tools.h"
+
+int seed_array[] = {1, 2};
+
+int main()
+{
+  double a=lemon::rnd();
+  check(a<1.0&&a>0.0,"This should be in [0,1)");
+  a=lemon::rnd.gauss();
+  a=lemon::rnd.gamma(3.45,0);
+  a=lemon::rnd.gamma(4);
+  //Does gamma work with integer k?
+  a=lemon::rnd.gamma(4.0,0);
+  a=lemon::rnd.poisson(.5);
+
+  lemon::rnd.seed(100);
+  lemon::rnd.seed(seed_array, seed_array +
+                  (sizeof(seed_array) / sizeof(seed_array[0])));
+
+  return 0;
+}
diff --git a/test/suurballe_test.cc b/test/suurballe_test.cc
new file mode 100644
index 0000000..7c00f21
--- /dev/null
+++ b/test/suurballe_test.cc
@@ -0,0 +1,267 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/path.h>
+#include <lemon/suurballe.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/heap.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"
+  "8\n"
+  "9\n"
+  "10\n"
+  "11\n"
+  "12\n"
+  "@arcs\n"
+  "      length\n"
+  " 1  2  70\n"
+  " 1  3 150\n"
+  " 1  4  80\n"
+  " 2  8  80\n"
+  " 3  5 140\n"
+  " 4  6  60\n"
+  " 4  7  80\n"
+  " 4  8 110\n"
+  " 5  7  60\n"
+  " 5 11 120\n"
+  " 6  3   0\n"
+  " 6  9 140\n"
+  " 6 10  90\n"
+  " 7  1  30\n"
+  " 8 12  60\n"
+  " 9 12  50\n"
+  "10 12  70\n"
+  "10  2 100\n"
+  "10  7  60\n"
+  "11 10  20\n"
+  "12 11  30\n"
+  "@attributes\n"
+  "source  1\n"
+  "target 12\n"
+  "@end\n";
+
+// Check the interface of Suurballe
+void checkSuurballeCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc, VType> LengthMap;
+
+  typedef Suurballe<Digraph, LengthMap> ST;
+  typedef Suurballe<Digraph, LengthMap>
+    ::SetFlowMap<ST::FlowMap>
+    ::SetPotentialMap<ST::PotentialMap>
+    ::SetPath<SimplePath<Digraph> >
+    ::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > >
+    ::Create SuurballeType;
+
+  Digraph g;
+  Node n;
+  Arc e;
+  LengthMap len;
+  SuurballeType::FlowMap flow(g);
+  SuurballeType::PotentialMap pi(g);
+
+  SuurballeType suurb_test(g, len);
+  const SuurballeType& const_suurb_test = suurb_test;
+
+  suurb_test
+    .flowMap(flow)
+    .potentialMap(pi);
+
+  int k;
+  k = suurb_test.run(n, n);
+  k = suurb_test.run(n, n, k);
+  suurb_test.init(n);
+  suurb_test.fullInit(n);
+  suurb_test.start(n);
+  suurb_test.start(n, k);
+  k = suurb_test.findFlow(n);
+  k = suurb_test.findFlow(n, k);
+  suurb_test.findPaths();
+
+  int f;
+  VType c;
+  ::lemon::ignore_unused_variable_warning(f,c);
+
+  c = const_suurb_test.totalLength();
+  f = const_suurb_test.flow(e);
+  const SuurballeType::FlowMap& fm =
+    const_suurb_test.flowMap();
+  c = const_suurb_test.potential(n);
+  const SuurballeType::PotentialMap& pm =
+    const_suurb_test.potentialMap();
+  k = const_suurb_test.pathNum();
+  Path<Digraph> p = const_suurb_test.path(k);
+
+  ::lemon::ignore_unused_variable_warning(fm);
+  ::lemon::ignore_unused_variable_warning(pm);
+}
+
+// Check the feasibility of the flow
+template <typename Digraph, typename FlowMap>
+bool checkFlow( const Digraph& gr, const FlowMap& flow,
+                typename Digraph::Node s, typename Digraph::Node t,
+                int value )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  for (ArcIt e(gr); e != INVALID; ++e)
+    if (!(flow[e] == 0 || flow[e] == 1)) return false;
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    int sum = 0;
+    for (OutArcIt e(gr, n); e != INVALID; ++e)
+      sum += flow[e];
+    for (InArcIt e(gr, n); e != INVALID; ++e)
+      sum -= flow[e];
+    if (n == s && sum != value) return false;
+    if (n == t && sum != -value) return false;
+    if (n != s && n != t && sum != 0) return false;
+  }
+
+  return true;
+}
+
+// Check the optimalitiy of the flow
+template < typename Digraph, typename CostMap,
+           typename FlowMap, typename PotentialMap >
+bool checkOptimality( const Digraph& gr, const CostMap& cost,
+                      const FlowMap& flow, const PotentialMap& pi )
+{
+  // Check the "Complementary Slackness" optimality condition
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  bool opt = true;
+  for (ArcIt e(gr); e != INVALID; ++e) {
+    typename CostMap::Value red_cost =
+      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
+    opt = (flow[e] == 0 && red_cost >= 0) ||
+          (flow[e] == 1 && red_cost <= 0);
+    if (!opt) break;
+  }
+  return opt;
+}
+
+// Check a path
+template <typename Digraph, typename Path>
+bool checkPath( const Digraph& gr, const Path& path,
+                typename Digraph::Node s, typename Digraph::Node t)
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  Node n = s;
+  for (int i = 0; i < path.length(); ++i) {
+    if (gr.source(path.nth(i)) != n) return false;
+    n = gr.target(path.nth(i));
+  }
+  return n == t;
+}
+
+
+int main()
+{
+  DIGRAPH_TYPEDEFS(ListDigraph);
+
+  // Read the test digraph
+  ListDigraph digraph;
+  ListDigraph::ArcMap<int> length(digraph);
+  Node s, t;
+
+  std::istringstream input(test_lgf);
+  DigraphReader<ListDigraph>(digraph, input).
+    arcMap("length", length).
+    node("source", s).
+    node("target", t).
+    run();
+
+  // Check run()
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length);
+
+    // Find 2 paths
+    check(suurballe.run(s, t) == 2, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 510, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+
+    // Find 3 paths
+    check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+
+    // Find 5 paths (only 3 can be found)
+    check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+  }
+
+  // Check fullInit() + start()
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length);
+    suurballe.fullInit(s);
+
+    // Find 2 paths
+    check(suurballe.start(t) == 2, "Wrong number of paths");
+    check(suurballe.totalLength() == 510, "The flow is not optimal");
+
+    // Find 3 paths
+    check(suurballe.start(t, 3) == 3, "Wrong number of paths");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+
+    // Find 5 paths (only 3 can be found)
+    check(suurballe.start(t, 5) == 3, "Wrong number of paths");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+  }
+
+  return 0;
+}
diff --git a/test/test_tools.h b/test/test_tools.h
new file mode 100644
index 0000000..3300356
--- /dev/null
+++ b/test/test_tools.h
@@ -0,0 +1,50 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_TEST_TEST_TOOLS_H
+#define LEMON_TEST_TEST_TOOLS_H
+
+///\ingroup misc
+///\file
+///\brief Some utilities to write test programs.
+
+#include <iostream>
+#include <stdlib.h>
+
+///If \c rc is fail, writes an error message and exits.
+
+///If \c rc is fail, writes an error message and exits.
+///The error message contains the file name and the line number of the
+///source code in a standard from, which makes it possible to go there
+///using good source browsers like e.g. \c emacs.
+///
+///For example
+///\code check(0==1,"This is obviously false.");\endcode will
+///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 { }                                                          \
+  }                                                                     \
+
+
+#endif
diff --git a/test/test_tools_fail.cc b/test/test_tools_fail.cc
new file mode 100644
index 0000000..6407cd1
--- /dev/null
+++ b/test/test_tools_fail.cc
@@ -0,0 +1,25 @@
+/* -*- 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 "test_tools.h"
+
+int main()
+{
+  check(false, "Don't panic. Failing is the right behaviour here.");
+  return 0;
+}
diff --git a/test/test_tools_pass.cc b/test/test_tools_pass.cc
new file mode 100644
index 0000000..b590c15
--- /dev/null
+++ b/test/test_tools_pass.cc
@@ -0,0 +1,25 @@
+/* -*- 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 "test_tools.h"
+
+int main()
+{
+  check(true, "It should pass.");
+  return 0;
+}
diff --git a/test/time_measure_test.cc b/test/time_measure_test.cc
new file mode 100644
index 0000000..4e7155a
--- /dev/null
+++ b/test/time_measure_test.cc
@@ -0,0 +1,60 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/time_measure.h>
+#include <lemon/concept_check.h>
+
+using namespace lemon;
+
+void f()
+{
+  double d=0;
+  for(int i=0;i<1000;i++)
+    d+=0.1;
+}
+
+void g()
+{
+  static Timer T;
+
+  for(int i=0;i<1000;i++)
+    {
+      TimeStamp x(T);
+      ::lemon::ignore_unused_variable_warning(x);
+    }
+}
+
+int main()
+{
+  Timer T;
+  unsigned int n;
+  for(n=0;T.realTime()<0.1;n++) ;
+  std::cout << T << " (" << n << " time queries)\n";
+
+  TimeStamp full;
+  TimeStamp t;
+  t=runningTimeTest(f,0.1,&n,&full);
+  std::cout << t << " (" << n << " tests)\n";
+  std::cout << "Total: " << full << "\n";
+
+  t=runningTimeTest(g,0.1,&n,&full);
+  std::cout << t << " (" << n << " tests)\n";
+  std::cout << "Total: " << full << "\n";
+
+  return 0;
+}
diff --git a/test/tsp_test.cc b/test/tsp_test.cc
new file mode 100644
index 0000000..398a812
--- /dev/null
+++ b/test/tsp_test.cc
@@ -0,0 +1,287 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * 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/full_graph.h>
+#include <lemon/math.h>
+#include <lemon/maps.h>
+#include <lemon/random.h>
+#include <lemon/dim2.h>
+
+#include <lemon/nearest_neighbor_tsp.h>
+#include <lemon/greedy_tsp.h>
+#include <lemon/insertion_tsp.h>
+#include <lemon/christofides_tsp.h>
+#include <lemon/opt2_tsp.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+// // Tests checkMetricCost() function
+// void metricCostTest() {
+//   GRAPH_TYPEDEFS(FullGraph);
+//   FullGraph g(10);
+//   check(checkMetricCost(g, constMap<Edge>(0)), "Wrong checkMetricCost()");
+//   check(checkMetricCost(g, constMap<Edge>(1)), "Wrong checkMetricCost()");
+//   check(!checkMetricCost(g, constMap<Edge>(-1)), "Wrong checkMetricCost()");
+//
+//   FullGraph::EdgeMap<float> cost(g);
+//   for (NodeIt u(g); u != INVALID; ++u) {
+//     for (NodeIt v(g); v != INVALID; ++v) {
+//       if (u == v) continue;
+//       float x1 = g.id(u), x2 = g.id(v);
+//       float y1 = x1 * x1, y2 = x2 * x2;
+//       cost[g.edge(u, v)] = std::sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
+//     }
+//   }
+//   check(checkMetricCost(g, cost), "Wrong checkMetricCost()");
+//   float eps = Tolerance<float>::defaultEpsilon();
+//   cost[g.edge(g(0), g(9))] =
+//     cost[g.edge(g(0), g(8))] + cost[g.edge(g(8), g(9))] + eps * 2;
+//   check(!checkMetricCost(g, cost), "Wrong checkMetricCost()");
+//   check(checkMetricCost(g, cost, Tolerance<float>(eps * 4)),
+//     "Wrong checkMetricCost()");
+// }
+
+// Checks tour validity
+template <typename Container>
+bool checkTour(const FullGraph &gr, const Container &p) {
+  FullGraph::NodeMap<bool> used(gr, false);
+
+  int node_cnt = 0;
+  for (typename Container::const_iterator it = p.begin(); it != p.end(); ++it)
+    {
+      FullGraph::Node node = *it;
+      if (used[node]) return false;
+      used[node] = true;
+      ++node_cnt;
+    }
+
+  return (node_cnt == gr.nodeNum());
+}
+
+// Checks tour validity
+bool checkTourPath(const FullGraph &gr, const Path<FullGraph> &p) {
+  FullGraph::NodeMap<bool> used(gr, false);
+
+  if (!checkPath(gr, p)) return false;
+  if (gr.nodeNum() <= 1 && p.length() != 0) return false;
+  if (gr.nodeNum() > 1 && p.length() != gr.nodeNum()) return false;
+
+  for (int i = 0; i < p.length(); ++i) {
+    if (used[gr.target(p.nth(i))]) return false;
+    used[gr.target(p.nth(i))] = true;
+  }
+  return true;
+}
+
+// Checks tour cost
+template <typename CostMap>
+bool checkCost(const FullGraph &gr, const std::vector<FullGraph::Node> &p,
+               const CostMap &cost, typename CostMap::Value total)
+{
+  typedef typename CostMap::Value Cost;
+
+  Cost s = 0;
+  for (int i = 0; i < int(p.size()) - 1; ++i)
+    s += cost[gr.edge(p[i], p[i+1])];
+  if (int(p.size()) >= 2)
+    s += cost[gr.edge(p.back(), p.front())];
+
+  return !Tolerance<Cost>().different(s, total);
+}
+
+// Checks tour cost
+template <typename CostMap>
+bool checkCost(const FullGraph &, const Path<FullGraph> &p,
+               const CostMap &cost, typename CostMap::Value total)
+{
+  typedef typename CostMap::Value Cost;
+
+  Cost s = 0;
+  for (int i = 0; i < p.length(); ++i)
+    s += cost[p.nth(i)];
+
+  return !Tolerance<Cost>().different(s, total);
+}
+
+// Tests a TSP algorithm on small graphs
+template <typename TSP>
+void tspTestSmall(const std::string &alg_name) {
+  GRAPH_TYPEDEFS(FullGraph);
+
+  for (int n = 0; n <= 5; ++n) {
+    FullGraph g(n);
+    unsigned nsize = n;
+    int esize = n <= 1 ? 0 : n;
+
+    ConstMap<Edge, int> cost_map(1);
+    TSP alg(g, cost_map);
+
+    check(alg.run() == esize, alg_name + ": Wrong total cost");
+    check(alg.tourCost() == esize, alg_name + ": Wrong total cost");
+
+    std::list<Node> list1(nsize), list2;
+    std::vector<Node> vec1(nsize), vec2;
+    alg.tourNodes(list1.begin());
+    alg.tourNodes(vec1.begin());
+    alg.tourNodes(std::front_inserter(list2));
+    alg.tourNodes(std::back_inserter(vec2));
+    check(checkTour(g, alg.tourNodes()), alg_name + ": Wrong node sequence");
+    check(checkTour(g, list1), alg_name + ": Wrong node sequence");
+    check(checkTour(g, vec1), alg_name + ": Wrong node sequence");
+    check(checkTour(g, list2), alg_name + ": Wrong node sequence");
+    check(checkTour(g, vec2), alg_name + ": Wrong node sequence");
+    check(checkCost(g, vec1, constMap<Edge, int>(1), esize),
+      alg_name + ": Wrong tour cost");
+
+    SimplePath<FullGraph> path;
+    alg.tour(path);
+    check(path.length() == esize, alg_name + ": Wrong tour");
+    check(checkTourPath(g, path), alg_name + ": Wrong tour");
+    check(checkCost(g, path, constMap<Edge, int>(1), esize),
+      alg_name + ": Wrong tour cost");
+  }
+}
+
+// Tests a TSP algorithm on random graphs
+template <typename TSP>
+void tspTestRandom(const std::string &alg_name) {
+  GRAPH_TYPEDEFS(FullGraph);
+
+  FullGraph g(20);
+  FullGraph::NodeMap<dim2::Point<double> > pos(g);
+  DoubleEdgeMap cost(g);
+
+  TSP alg(g, cost);
+  Opt2Tsp<DoubleEdgeMap > opt2(g, cost);
+
+  for (int i = 1; i <= 3; i++) {
+    for (NodeIt u(g); u != INVALID; ++u) {
+      pos[u] = dim2::Point<double>(rnd(), rnd());
+    }
+    for (NodeIt u(g); u != INVALID; ++u) {
+      for (NodeIt v(g); v != INVALID; ++v) {
+        if (u == v) continue;
+        cost[g.edge(u, v)] = (pos[u] - pos[v]).normSquare();
+      }
+    }
+
+    check(alg.run() > 0, alg_name + ": Wrong total cost");
+
+    std::vector<Node> vec;
+    alg.tourNodes(std::back_inserter(vec));
+    check(checkTour(g, vec), alg_name + ": Wrong node sequence");
+    check(checkCost(g, vec, cost, alg.tourCost()),
+      alg_name + ": Wrong tour cost");
+
+    SimplePath<FullGraph> path;
+    alg.tour(path);
+    check(checkTourPath(g, path), alg_name + ": Wrong tour");
+    check(checkCost(g, path, cost, alg.tourCost()),
+      alg_name + ": Wrong tour cost");
+
+    check(!Tolerance<double>().less(alg.tourCost(), opt2.run(alg.tourNodes())),
+      "2-opt improvement: Wrong total cost");
+    check(checkTour(g, opt2.tourNodes()),
+      "2-opt improvement: Wrong node sequence");
+    check(checkCost(g, opt2.tourNodes(), cost, opt2.tourCost()),
+      "2-opt improvement: Wrong tour cost");
+
+    check(!Tolerance<double>().less(alg.tourCost(), opt2.run(path)),
+      "2-opt improvement: Wrong total cost");
+    check(checkTour(g, opt2.tourNodes()),
+      "2-opt improvement: Wrong node sequence");
+    check(checkCost(g, opt2.tourNodes(), cost, opt2.tourCost()),
+      "2-opt improvement: Wrong tour cost");
+  }
+}
+
+// Algorithm class for Nearest Insertion
+template <typename CM>
+class NearestInsertionTsp : public InsertionTsp<CM> {
+public:
+  NearestInsertionTsp(const FullGraph &gr, const CM &cost)
+    : InsertionTsp<CM>(gr, cost) {}
+  typename CM::Value run() {
+    return InsertionTsp<CM>::run(InsertionTsp<CM>::NEAREST);
+  }
+};
+
+// Algorithm class for Farthest Insertion
+template <typename CM>
+class FarthestInsertionTsp : public InsertionTsp<CM> {
+public:
+  FarthestInsertionTsp(const FullGraph &gr, const CM &cost)
+    : InsertionTsp<CM>(gr, cost) {}
+  typename CM::Value run() {
+    return InsertionTsp<CM>::run(InsertionTsp<CM>::FARTHEST);
+  }
+};
+
+// Algorithm class for Cheapest Insertion
+template <typename CM>
+class CheapestInsertionTsp : public InsertionTsp<CM> {
+public:
+  CheapestInsertionTsp(const FullGraph &gr, const CM &cost)
+    : InsertionTsp<CM>(gr, cost) {}
+  typename CM::Value run() {
+    return InsertionTsp<CM>::run(InsertionTsp<CM>::CHEAPEST);
+  }
+};
+
+// Algorithm class for Random Insertion
+template <typename CM>
+class RandomInsertionTsp : public InsertionTsp<CM> {
+public:
+  RandomInsertionTsp(const FullGraph &gr, const CM &cost)
+    : InsertionTsp<CM>(gr, cost) {}
+  typename CM::Value run() {
+    return InsertionTsp<CM>::run(InsertionTsp<CM>::RANDOM);
+  }
+};
+
+int main() {
+  GRAPH_TYPEDEFS(FullGraph);
+
+  // metricCostTest();
+
+  tspTestSmall<NearestNeighborTsp<ConstMap<Edge, int> > >("Nearest Neighbor");
+  tspTestSmall<GreedyTsp<ConstMap<Edge, int> > >("Greedy");
+  tspTestSmall<NearestInsertionTsp<ConstMap<Edge, int> > >("Nearest Insertion");
+  tspTestSmall<FarthestInsertionTsp<ConstMap<Edge, int> > >
+    ("Farthest Insertion");
+  tspTestSmall<CheapestInsertionTsp<ConstMap<Edge, int> > >
+    ("Cheapest Insertion");
+  tspTestSmall<RandomInsertionTsp<ConstMap<Edge, int> > >("Random Insertion");
+  tspTestSmall<ChristofidesTsp<ConstMap<Edge, int> > >("Christofides");
+  tspTestSmall<Opt2Tsp<ConstMap<Edge, int> > >("2-opt");
+
+  tspTestRandom<NearestNeighborTsp<DoubleEdgeMap > >("Nearest Neighbor");
+  tspTestRandom<GreedyTsp<DoubleEdgeMap > >("Greedy");
+  tspTestRandom<NearestInsertionTsp<DoubleEdgeMap > >("Nearest Insertion");
+  tspTestRandom<FarthestInsertionTsp<DoubleEdgeMap > >("Farthest Insertion");
+  tspTestRandom<CheapestInsertionTsp<DoubleEdgeMap > >("Cheapest Insertion");
+  tspTestRandom<RandomInsertionTsp<DoubleEdgeMap > >("Random Insertion");
+  tspTestRandom<ChristofidesTsp<DoubleEdgeMap > >("Christofides");
+  tspTestRandom<Opt2Tsp<DoubleEdgeMap > >("2-opt");
+
+  return 0;
+}
diff --git a/test/unionfind_test.cc b/test/unionfind_test.cc
new file mode 100644
index 0000000..e82d8e6
--- /dev/null
+++ b/test/unionfind_test.cc
@@ -0,0 +1,102 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/list_graph.h>
+#include <lemon/maps.h>
+#include <lemon/unionfind.h>
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace std;
+
+typedef UnionFindEnum<ListGraph::NodeMap<int> > UFE;
+
+int main() {
+  ListGraph g;
+  ListGraph::NodeMap<int> base(g);
+  UFE U(base);
+  vector<ListGraph::Node> n;
+
+  for(int i=0;i<20;i++) n.push_back(g.addNode());
+
+  U.insert(n[1]);
+  U.insert(n[2]);
+
+  check(U.join(n[1],n[2]) != -1, "Something is wrong with UnionFindEnum");
+
+  U.insert(n[3]);
+  U.insert(n[4]);
+  U.insert(n[5]);
+  U.insert(n[6]);
+  U.insert(n[7]);
+
+
+  check(U.join(n[1],n[4]) != -1, "Something is wrong with UnionFindEnum");
+  check(U.join(n[2],n[4]) == -1, "Something is wrong with UnionFindEnum");
+  check(U.join(n[3],n[5]) != -1, "Something is wrong with UnionFindEnum");
+
+
+  U.insert(n[8],U.find(n[5]));
+
+
+  check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[5])) == 3, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[6])) == 1, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[2])) == 3, "Something is wrong with UnionFindEnum");
+
+
+  U.insert(n[9]);
+  U.insert(n[10],U.find(n[9]));
+
+
+  check(U.join(n[8],n[10])  != -1, "Something is wrong with UnionFindEnum");
+
+
+  check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[9])) == 5, "Something is wrong with UnionFindEnum");
+
+  check(U.size(U.find(n[8])) == 5, "Something is wrong with UnionFindEnum");
+
+  U.erase(n[9]);
+  U.erase(n[1]);
+
+  check(U.size(U.find(n[10])) == 4, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[2]))  == 2, "Something is wrong with UnionFindEnum");
+
+  U.erase(n[6]);
+  U.split(U.find(n[8]));
+
+
+  check(U.size(U.find(n[4])) == 2, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[3])) == 1, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[2])) == 2, "Something is wrong with UnionFindEnum");
+
+
+  check(U.join(n[3],n[4]) != -1, "Something is wrong with UnionFindEnum");
+  check(U.join(n[2],n[4]) == -1, "Something is wrong with UnionFindEnum");
+
+
+  check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[3])) == 3, "Something is wrong with UnionFindEnum");
+  check(U.size(U.find(n[2])) == 3, "Something is wrong with UnionFindEnum");
+
+  U.eraseClass(U.find(n[4]));
+  U.eraseClass(U.find(n[7]));
+
+  return 0;
+}
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
new file mode 100644
index 0000000..64b7df7
--- /dev/null
+++ b/tools/CMakeLists.txt
@@ -0,0 +1,31 @@
+INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}
+  ${PROJECT_BINARY_DIR}
+)
+
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
+
+ADD_EXECUTABLE(lgf-gen lgf-gen.cc)
+TARGET_LINK_LIBRARIES(lgf-gen lemon)
+
+ADD_EXECUTABLE(dimacs-to-lgf dimacs-to-lgf.cc)
+TARGET_LINK_LIBRARIES(dimacs-to-lgf lemon)
+
+ADD_EXECUTABLE(dimacs-solver dimacs-solver.cc)
+TARGET_LINK_LIBRARIES(dimacs-solver lemon)
+
+INSTALL(
+  TARGETS lgf-gen dimacs-to-lgf dimacs-solver
+  RUNTIME DESTINATION bin
+  COMPONENT bin
+)
+
+IF(NOT WIN32)
+  INSTALL(
+    PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/lemon-0.x-to-1.x.sh
+    DESTINATION bin
+    COMPONENT bin
+  )
+ENDIF()
diff --git a/tools/dimacs-solver.cc b/tools/dimacs-solver.cc
new file mode 100644
index 0000000..60da233
--- /dev/null
+++ b/tools/dimacs-solver.cc
@@ -0,0 +1,279 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup tools
+///\file
+///\brief DIMACS problem solver.
+///
+/// This program solves various problems given in DIMACS format.
+///
+/// See
+/// \code
+///   dimacs-solver --help
+/// \endcode
+/// for more info on usage.
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include <lemon/smart_graph.h>
+#include <lemon/dimacs.h>
+#include <lemon/lgf_writer.h>
+#include <lemon/time_measure.h>
+
+#include <lemon/arg_parser.h>
+#include <lemon/error.h>
+
+#include <lemon/dijkstra.h>
+#include <lemon/preflow.h>
+#include <lemon/matching.h>
+#include <lemon/network_simplex.h>
+
+using namespace lemon;
+typedef SmartDigraph Digraph;
+DIGRAPH_TYPEDEFS(Digraph);
+typedef SmartGraph Graph;
+
+template<class Value>
+void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
+              DimacsDescriptor &desc)
+{
+  bool report = !ap.given("q");
+  Digraph g;
+  Node s;
+  Digraph::ArcMap<Value> len(g);
+  Timer t;
+  t.restart();
+  readDimacsSp(is, g, len, s, desc);
+  if(report) std::cerr << "Read the file: " << t << '\n';
+  t.restart();
+  Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
+  if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
+  t.restart();
+  dij.run(s);
+  if(report) std::cerr << "Run Dijkstra: " << t << '\n';
+}
+
+template<class Value>
+void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
+               Value infty, DimacsDescriptor &desc)
+{
+  bool report = !ap.given("q");
+  Digraph g;
+  Node s,t;
+  Digraph::ArcMap<Value> cap(g);
+  Timer ti;
+  ti.restart();
+  readDimacsMax(is, g, cap, s, t, infty, desc);
+  if(report) std::cerr << "Read the file: " << ti << '\n';
+  ti.restart();
+  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
+  if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
+  ti.restart();
+  pre.run();
+  if(report) std::cerr << "Run Preflow: " << ti << '\n';
+  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
+}
+
+template<class Value, class LargeValue>
+void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
+               Value infty, DimacsDescriptor &desc)
+{
+  bool report = !ap.given("q");
+  Digraph g;
+  Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
+  Digraph::NodeMap<Value> sup(g);
+  Timer ti;
+
+  ti.restart();
+  readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
+  ti.stop();
+  Value sum_sup = 0;
+  for (Digraph::NodeIt n(g); n != INVALID; ++n) {
+    sum_sup += sup[n];
+  }
+  if (report) {
+    std::cerr << "Sum of supply values: " << sum_sup << "\n";
+    if (sum_sup <= 0)
+      std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
+    else
+      std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
+  }
+  if (report) std::cerr << "Read the file: " << ti << '\n';
+
+  typedef NetworkSimplex<Digraph, Value> MCF;
+  ti.restart();
+  MCF ns(g);
+  ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
+  if (sum_sup > 0) ns.supplyType(ns.LEQ);
+  if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
+  ti.restart();
+  typename MCF::ProblemType res = ns.run();
+  if (report) {
+    std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
+    std::cerr << "Feasible flow: " << (res == MCF::OPTIMAL ? "found" :
+                                       "not found") << '\n';
+    if (res) std::cerr << "Min flow cost: "
+                       << ns.template totalCost<LargeValue>() << '\n';
+  }
+}
+
+void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
+              DimacsDescriptor &desc)
+{
+  bool report = !ap.given("q");
+  Graph g;
+  Timer ti;
+  ti.restart();
+  readDimacsMat(is, g, desc);
+  if(report) std::cerr << "Read the file: " << ti << '\n';
+  ti.restart();
+  MaxMatching<Graph> mat(g);
+  if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
+  ti.restart();
+  mat.run();
+  if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
+  if(report) std::cerr << "\nCardinality of max matching: "
+                       << mat.matchingSize() << '\n';
+}
+
+
+template<class Value, class LargeValue>
+void solve(ArgParser &ap, std::istream &is, std::ostream &os,
+           DimacsDescriptor &desc)
+{
+  std::stringstream iss(static_cast<std::string>(ap["infcap"]));
+  Value infty;
+  iss >> infty;
+  if(iss.fail())
+    {
+      std::cerr << "Cannot interpret '"
+                << static_cast<std::string>(ap["infcap"]) << "' as infinite"
+                << std::endl;
+      exit(1);
+    }
+
+  switch(desc.type)
+    {
+    case DimacsDescriptor::MIN:
+      solve_min<Value, LargeValue>(ap,is,os,infty,desc);
+      break;
+    case DimacsDescriptor::MAX:
+      solve_max<Value>(ap,is,os,infty,desc);
+      break;
+    case DimacsDescriptor::SP:
+      solve_sp<Value>(ap,is,os,desc);
+      break;
+    case DimacsDescriptor::MAT:
+      solve_mat(ap,is,os,desc);
+      break;
+    default:
+      break;
+    }
+}
+
+int main(int argc, const char *argv[]) {
+
+  std::string inputName;
+  std::string outputName;
+
+  ArgParser ap(argc, argv);
+  ap.other("[INFILE [OUTFILE]]",
+           "If either the INFILE or OUTFILE file is missing the standard\n"
+           "     input/output will be used instead.")
+    .boolOption("q", "Do not print any report")
+    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
+    .optionGroup("datatype","int")
+#ifdef LEMON_HAVE_LONG_LONG
+    .boolOption("long","Use 'long long' for capacities, costs etc.")
+    .optionGroup("datatype","long")
+#endif
+    .boolOption("double","Use 'double' for capacities, costs etc.")
+    .optionGroup("datatype","double")
+    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
+    .optionGroup("datatype","ldouble")
+    .onlyOneGroup("datatype")
+    .stringOption("infcap","Value used for 'very high' capacities","0")
+    .run();
+
+  std::ifstream input;
+  std::ofstream output;
+
+  switch(ap.files().size())
+    {
+    case 2:
+      output.open(ap.files()[1].c_str());
+      if (!output) {
+        throw IoError("Cannot open the file for writing", ap.files()[1]);
+      }
+    case 1:
+      input.open(ap.files()[0].c_str());
+      if (!input) {
+        throw IoError("File cannot be found", ap.files()[0]);
+      }
+    case 0:
+      break;
+    default:
+      std::cerr << ap.commandName() << ": too many arguments\n";
+      return 1;
+    }
+  std::istream& is = (ap.files().size()<1 ? std::cin : input);
+  std::ostream& os = (ap.files().size()<2 ? std::cout : output);
+
+  DimacsDescriptor desc = dimacsType(is);
+
+  if(!ap.given("q"))
+    {
+      std::cout << "Problem type: ";
+      switch(desc.type)
+        {
+        case DimacsDescriptor::MIN:
+          std::cout << "min";
+          break;
+        case DimacsDescriptor::MAX:
+          std::cout << "max";
+          break;
+        case DimacsDescriptor::SP:
+          std::cout << "sp";
+        case DimacsDescriptor::MAT:
+          std::cout << "mat";
+          break;
+        default:
+          exit(1);
+          break;
+        }
+      std::cout << "\nNum of nodes: " << desc.nodeNum;
+      std::cout << "\nNum of arcs:  " << desc.edgeNum;
+      std::cout << "\n\n";
+    }
+
+  if(ap.given("double"))
+    solve<double, double>(ap,is,os,desc);
+  else if(ap.given("ldouble"))
+    solve<long double, long double>(ap,is,os,desc);
+#ifdef LEMON_HAVE_LONG_LONG
+  else if(ap.given("long"))
+    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
+
+  return 0;
+}
diff --git a/tools/dimacs-to-lgf.cc b/tools/dimacs-to-lgf.cc
new file mode 100644
index 0000000..3968645
--- /dev/null
+++ b/tools/dimacs-to-lgf.cc
@@ -0,0 +1,148 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup tools
+///\file
+///\brief DIMACS to LGF converter.
+///
+/// This program converts various DIMACS formats to the LEMON Digraph Format
+/// (LGF).
+///
+/// See
+/// \code
+///   dimacs-to-lgf --help
+/// \endcode
+/// for more info on the usage.
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include <lemon/smart_graph.h>
+#include <lemon/dimacs.h>
+#include <lemon/lgf_writer.h>
+
+#include <lemon/arg_parser.h>
+#include <lemon/error.h>
+
+using namespace std;
+using namespace lemon;
+
+
+int main(int argc, const char *argv[]) {
+  typedef SmartDigraph Digraph;
+
+  typedef Digraph::Arc Arc;
+  typedef Digraph::Node Node;
+  typedef Digraph::ArcIt ArcIt;
+  typedef Digraph::NodeIt NodeIt;
+  typedef Digraph::ArcMap<double> DoubleArcMap;
+  typedef Digraph::NodeMap<double> DoubleNodeMap;
+
+  std::string inputName;
+  std::string outputName;
+
+  ArgParser ap(argc, argv);
+  ap.other("[INFILE [OUTFILE]]",
+           "If either the INFILE or OUTFILE file is missing the standard\n"
+           "     input/output will be used instead.")
+    .run();
+
+  ifstream input;
+  ofstream output;
+
+  switch(ap.files().size())
+    {
+    case 2:
+      output.open(ap.files()[1].c_str());
+      if (!output) {
+        throw IoError("Cannot open the file for writing", ap.files()[1]);
+      }
+    case 1:
+      input.open(ap.files()[0].c_str());
+      if (!input) {
+        throw IoError("File cannot be found", ap.files()[0]);
+      }
+    case 0:
+      break;
+    default:
+      cerr << ap.commandName() << ": too many arguments\n";
+      return 1;
+  }
+  istream& is = (ap.files().size()<1 ? cin : input);
+  ostream& os = (ap.files().size()<2 ? cout : output);
+
+  DimacsDescriptor desc = dimacsType(is);
+  switch(desc.type)
+    {
+    case DimacsDescriptor::MIN:
+      {
+        Digraph digraph;
+        DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
+        DoubleNodeMap supply(digraph);
+        readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc);
+        DigraphWriter<Digraph>(digraph, os).
+          nodeMap("supply", supply).
+          arcMap("lower", lower).
+          arcMap("capacity", capacity).
+          arcMap("cost", cost).
+          attribute("problem","min").
+          run();
+      }
+      break;
+    case DimacsDescriptor::MAX:
+      {
+        Digraph digraph;
+        Node s, t;
+        DoubleArcMap capacity(digraph);
+        readDimacsMax(is, digraph, capacity, s, t, 0, desc);
+        DigraphWriter<Digraph>(digraph, os).
+          arcMap("capacity", capacity).
+          node("source", s).
+          node("target", t).
+          attribute("problem","max").
+          run();
+      }
+      break;
+    case DimacsDescriptor::SP:
+      {
+        Digraph digraph;
+        Node s;
+        DoubleArcMap capacity(digraph);
+        readDimacsSp(is, digraph, capacity, s, desc);
+        DigraphWriter<Digraph>(digraph, os).
+          arcMap("capacity", capacity).
+          node("source", s).
+          attribute("problem","sp").
+          run();
+      }
+      break;
+    case DimacsDescriptor::MAT:
+      {
+        Digraph digraph;
+        readDimacsMat(is, digraph,desc);
+        DigraphWriter<Digraph>(digraph, os).
+          attribute("problem","mat").
+          run();
+      }
+      break;
+    default:
+      break;
+    }
+  return 0;
+}
diff --git a/tools/lemon-0.x-to-1.x.sh b/tools/lemon-0.x-to-1.x.sh
new file mode 100755
index 0000000..1dac1be
--- /dev/null
+++ b/tools/lemon-0.x-to-1.x.sh
@@ -0,0 +1,134 @@
+#!/bin/bash
+
+set -e
+
+if [ $# -eq 0 -o x$1 = "x-h" -o x$1 = "x-help" -o x$1 = "x--help" ]; then
+    echo "Usage:"
+    echo "  $0 source-file(s)"
+    exit
+fi
+
+for i in $@
+do
+    echo Update $i...
+    TMP=`mktemp`
+    sed -e "s/\<undirected graph\>/_gr_aph_label_/g"\
+        -e "s/\<undirected graphs\>/_gr_aph_label_s/g"\
+        -e "s/\<undirected edge\>/_ed_ge_label_/g"\
+        -e "s/\<undirected edges\>/_ed_ge_label_s/g"\
+        -e "s/\<directed graph\>/_digr_aph_label_/g"\
+        -e "s/\<directed graphs\>/_digr_aph_label_s/g"\
+        -e "s/\<directed edge\>/_ar_c_label_/g"\
+        -e "s/\<directed edges\>/_ar_c_label_s/g"\
+        -e "s/UGraph/_Gr_aph_label_/g"\
+        -e "s/u[Gg]raph/_gr_aph_label_/g"\
+        -e "s/Graph\>/_Digr_aph_label_/g"\
+        -e "s/\<graph\>/_digr_aph_label_/g"\
+        -e "s/Graphs\>/_Digr_aph_label_s/g"\
+        -e "s/\<graphs\>/_digr_aph_label_s/g"\
+        -e "s/\([Gg]\)raph\([a-z]\)/_\1r_aph_label_\2/g"\
+        -e "s/\([a-z_]\)graph/\1_gr_aph_label_/g"\
+        -e "s/Graph/_Digr_aph_label_/g"\
+        -e "s/graph/_digr_aph_label_/g"\
+        -e "s/UEdge/_Ed_ge_label_/g"\
+        -e "s/u[Ee]dge/_ed_ge_label_/g"\
+        -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
+        -e "s/Edge\>/_Ar_c_label_/g"\
+        -e "s/\<edge\>/_ar_c_label_/g"\
+        -e "s/_edge\>/__ar_c_label_/g"\
+        -e "s/Edges\>/_Ar_c_label_s/g"\
+        -e "s/\<edges\>/_ar_c_label_s/g"\
+        -e "s/_edges\>/__ar_c_label_s/g"\
+        -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
+        -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
+        -e "s/Edge/_Ar_c_label_/g"\
+        -e "s/edge/_ar_c_label_/g"\
+        -e "s/A[Nn]ode/_Re_d_label_/g"\
+        -e "s/B[Nn]ode/_Blu_e_label_/g"\
+        -e "s/A-[Nn]ode/_Re_d_label_/g"\
+        -e "s/B-[Nn]ode/_Blu_e_label_/g"\
+        -e "s/a[Nn]ode/_re_d_label_/g"\
+        -e "s/b[Nn]ode/_blu_e_label_/g"\
+        -e "s/\<UGRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__GR_APH_TY_PEDE_FS_label_\1/g"\
+        -e "s/\<GRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__DIGR_APH_TY_PEDE_FS_label_\1/g"\
+        -e "s/\<UGRAPH_TYPEDEFS\>/_GR_APH_TY_PEDE_FS_label_/g"\
+        -e "s/\<GRAPH_TYPEDEFS\>/_DIGR_APH_TY_PEDE_FS_label_/g"\
+        -e "s/_Digr_aph_label_/Digraph/g"\
+        -e "s/_digr_aph_label_/digraph/g"\
+        -e "s/_Gr_aph_label_/Graph/g"\
+        -e "s/_gr_aph_label_/graph/g"\
+        -e "s/_Ar_c_label_/Arc/g"\
+        -e "s/_ar_c_label_/arc/g"\
+        -e "s/_Ed_ge_label_/Edge/g"\
+        -e "s/_ed_ge_label_/edge/g"\
+        -e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
+        -e "s/_Re_d_label_/Red/g"\
+        -e "s/_Blu_e_label_/Blue/g"\
+        -e "s/_re_d_label_/red/g"\
+        -e "s/_blu_e_label_/blue/g"\
+        -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
+        -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
+        -e "s/\<digraph_adaptor\.h\>/adaptors.h/g"\
+        -e "s/\<digraph_utils\.h\>/core.h/g"\
+        -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
+        -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
+        -e "s/\<topology\.h\>/connectivity.h/g"\
+        -e "s/DigraphToEps/GraphToEps/g"\
+        -e "s/digraphToEps/graphToEps/g"\
+        -e "s/\<DefPredMap\>/SetPredMap/g"\
+        -e "s/\<DefDistMap\>/SetDistMap/g"\
+        -e "s/\<DefReachedMap\>/SetReachedMap/g"\
+        -e "s/\<DefProcessedMap\>/SetProcessedMap/g"\
+        -e "s/\<DefHeap\>/SetHeap/g"\
+        -e "s/\<DefStandardHeap\>/SetStandradHeap/g"\
+        -e "s/\<DefOperationTraits\>/SetOperationTraits/g"\
+        -e "s/\<DefProcessedMapToBeDefaultMap\>/SetStandardProcessedMap/g"\
+        -e "s/\<copyGraph\>/graphCopy/g"\
+        -e "s/\<copyDigraph\>/digraphCopy/g"\
+        -e "s/\<HyperCubeDigraph\>/HypercubeGraph/g"\
+        -e "s/\<IntegerMap\>/RangeMap/g"\
+        -e "s/\<integerMap\>/rangeMap/g"\
+        -e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\
+        -e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\
+        -e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\
+        -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\
+        -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
+        -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
+        -e "s/\<InvertableMap\>/CrossRefMap/g"\
+        -e "s/\<invertableMap\>/crossRefMap/g"\
+        -e "s/\<DescriptorMap\>/RangeIdMap/g"\
+        -e "s/\<descriptorMap\>/rangeIdMap/g"\
+        -e "s/\<BoundingBox\>/Box/g"\
+        -e "s/\<readNauty\>/readNautyGraph/g"\
+        -e "s/\<RevDigraphAdaptor\>/ReverseDigraph/g"\
+        -e "s/\<revDigraphAdaptor\>/reverseDigraph/g"\
+        -e "s/\<SubDigraphAdaptor\>/SubDigraph/g"\
+        -e "s/\<subDigraphAdaptor\>/subDigraph/g"\
+        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
+        -e "s/\<subGraphAdaptor\>/subGraph/g"\
+        -e "s/\<NodeSubDigraphAdaptor\>/FilterNodes/g"\
+        -e "s/\<nodeSubDigraphAdaptor\>/filterNodes/g"\
+        -e "s/\<ArcSubDigraphAdaptor\>/FilterArcs/g"\
+        -e "s/\<arcSubDigraphAdaptor\>/filterArcs/g"\
+        -e "s/\<UndirDigraphAdaptor\>/Undirector/g"\
+        -e "s/\<undirDigraphAdaptor\>/undirector/g"\
+        -e "s/\<ResDigraphAdaptor\>/ResidualDigraph/g"\
+        -e "s/\<resDigraphAdaptor\>/residualDigraph/g"\
+        -e "s/\<SplitDigraphAdaptor\>/SplitNodes/g"\
+        -e "s/\<splitDigraphAdaptor\>/splitNodes/g"\
+        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
+        -e "s/\<subGraphAdaptor\>/subGraph/g"\
+        -e "s/\<NodeSubGraphAdaptor\>/FilterNodes/g"\
+        -e "s/\<nodeSubGraphAdaptor\>/filterNodes/g"\
+        -e "s/\<ArcSubGraphAdaptor\>/FilterEdges/g"\
+        -e "s/\<arcSubGraphAdaptor\>/filterEdges/g"\
+        -e "s/\<DirGraphAdaptor\>/Orienter/g"\
+        -e "s/\<dirGraphAdaptor\>/orienter/g"\
+        -e "s/\<LpCplex\>/CplexLp/g"\
+        -e "s/\<MipCplex\>/CplexMip/g"\
+        -e "s/\<LpGlpk\>/GlpkLp/g"\
+        -e "s/\<MipGlpk\>/GlpkMip/g"\
+        -e "s/\<LpSoplex\>/SoplexLp/g"\
+    <$i > $TMP
+    mv $TMP $i
+done
diff --git a/tools/lgf-gen.cc b/tools/lgf-gen.cc
new file mode 100644
index 0000000..390c8ae
--- /dev/null
+++ b/tools/lgf-gen.cc
@@ -0,0 +1,847 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+/// \ingroup tools
+/// \file
+/// \brief Special plane graph generator.
+///
+/// Graph generator application for various types of plane graphs.
+///
+/// See
+/// \code
+///   lgf-gen --help
+/// \endcode
+/// for more information on the usage.
+
+#include <algorithm>
+#include <set>
+#include <ctime>
+#include <lemon/list_graph.h>
+#include <lemon/random.h>
+#include <lemon/dim2.h>
+#include <lemon/bfs.h>
+#include <lemon/counter.h>
+#include <lemon/suurballe.h>
+#include <lemon/graph_to_eps.h>
+#include <lemon/lgf_writer.h>
+#include <lemon/arg_parser.h>
+#include <lemon/euler.h>
+#include <lemon/math.h>
+#include <lemon/kruskal.h>
+#include <lemon/time_measure.h>
+
+using namespace lemon;
+
+typedef dim2::Point<double> Point;
+
+GRAPH_TYPEDEFS(ListGraph);
+
+bool progress=true;
+
+int N;
+// int girth;
+
+ListGraph g;
+
+std::vector<Node> nodes;
+ListGraph::NodeMap<Point> coords(g);
+
+
+double totalLen(){
+  double tlen=0;
+  for(EdgeIt e(g);e!=INVALID;++e)
+    tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
+  return tlen;
+}
+
+int tsp_impr_num=0;
+
+const double EPSILON=1e-8;
+bool tsp_improve(Node u, Node v)
+{
+  double luv=std::sqrt((coords[v]-coords[u]).normSquare());
+  Node u2=u;
+  Node v2=v;
+  do {
+    Node n;
+    for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e) { }
+    u2=v2;
+    v2=n;
+    if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
+       std::sqrt((coords[u]-coords[u2]).normSquare())+
+       std::sqrt((coords[v]-coords[v2]).normSquare()))
+      {
+         g.erase(findEdge(g,u,v));
+         g.erase(findEdge(g,u2,v2));
+        g.addEdge(u2,u);
+        g.addEdge(v,v2);
+        tsp_impr_num++;
+        return true;
+      }
+  } while(v2!=u);
+  return false;
+}
+
+bool tsp_improve(Node u)
+{
+  for(IncEdgeIt e(g,u);e!=INVALID;++e)
+    if(tsp_improve(u,g.runningNode(e))) return true;
+  return false;
+}
+
+void tsp_improve()
+{
+  bool b;
+  do {
+    b=false;
+    for(NodeIt n(g);n!=INVALID;++n)
+      if(tsp_improve(n)) b=true;
+  } while(b);
+}
+
+void tsp()
+{
+  for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
+  tsp_improve();
+}
+
+class Line
+{
+public:
+  Point a;
+  Point b;
+  Line(Point _a,Point _b) :a(_a),b(_b) {}
+  Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
+  Line(const Arc &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
+  Line(const Edge &e) : a(coords[g.u(e)]),b(coords[g.v(e)]) {}
+};
+
+inline std::ostream& operator<<(std::ostream &os, const Line &l)
+{
+  os << l.a << "->" << l.b;
+  return os;
+}
+
+bool cross(Line a, Line b)
+{
+  Point ao=rot90(a.b-a.a);
+  Point bo=rot90(b.b-b.a);
+  return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
+    (bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
+}
+
+struct Parc
+{
+  Node a;
+  Node b;
+  double len;
+};
+
+bool pedgeLess(Parc a,Parc b)
+{
+  return a.len<b.len;
+}
+
+std::vector<Edge> arcs;
+
+namespace _delaunay_bits {
+
+  struct Part {
+    int prev, curr, next;
+
+    Part(int p, int c, int n) : prev(p), curr(c), next(n) {}
+  };
+
+  inline std::ostream& operator<<(std::ostream& os, const Part& part) {
+    os << '(' << part.prev << ',' << part.curr << ',' << part.next << ')';
+    return os;
+  }
+
+  inline double circle_point(const Point& p, const Point& q, const Point& r) {
+    double a = p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y);
+    if (a == 0) return std::numeric_limits<double>::quiet_NaN();
+
+    double d = (p.x * p.x + p.y * p.y) * (q.y - r.y) +
+      (q.x * q.x + q.y * q.y) * (r.y - p.y) +
+      (r.x * r.x + r.y * r.y) * (p.y - q.y);
+
+    double e = (p.x * p.x + p.y * p.y) * (q.x - r.x) +
+      (q.x * q.x + q.y * q.y) * (r.x - p.x) +
+      (r.x * r.x + r.y * r.y) * (p.x - q.x);
+
+    double f = (p.x * p.x + p.y * p.y) * (q.x * r.y - r.x * q.y) +
+      (q.x * q.x + q.y * q.y) * (r.x * p.y - p.x * r.y) +
+      (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y);
+
+    return d / (2 * a) + std::sqrt((d * d + e * e) / (4 * a * a) + f / a);
+  }
+
+  inline bool circle_form(const Point& p, const Point& q, const Point& r) {
+    return rot90(q - p) * (r - q) < 0.0;
+  }
+
+  inline double intersection(const Point& p, const Point& q, double sx) {
+    const double epsilon = 1e-8;
+
+    if (p.x == q.x) return (p.y + q.y) / 2.0;
+
+    if (sx < p.x + epsilon) return p.y;
+    if (sx < q.x + epsilon) return q.y;
+
+    double a = q.x - p.x;
+    double b = (q.x - sx) * p.y - (p.x - sx) * q.y;
+    double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare();
+    return (b - std::sqrt(d)) / a;
+  }
+
+  struct YLess {
+
+
+    YLess(const std::vector<Point>& points, double& sweep)
+      : _points(points), _sweep(sweep) {}
+
+    bool operator()(const Part& l, const Part& r) const {
+      const double epsilon = 1e-8;
+
+      //      std::cerr << l << " vs " << r << std::endl;
+      double lbx = l.prev != -1 ?
+        intersection(_points[l.prev], _points[l.curr], _sweep) :
+        - std::numeric_limits<double>::infinity();
+      double rbx = r.prev != -1 ?
+        intersection(_points[r.prev], _points[r.curr], _sweep) :
+        - std::numeric_limits<double>::infinity();
+      double lex = l.next != -1 ?
+        intersection(_points[l.curr], _points[l.next], _sweep) :
+        std::numeric_limits<double>::infinity();
+      double rex = r.next != -1 ?
+        intersection(_points[r.curr], _points[r.next], _sweep) :
+        std::numeric_limits<double>::infinity();
+
+      if (lbx > lex) std::swap(lbx, lex);
+      if (rbx > rex) std::swap(rbx, rex);
+
+      if (lex < epsilon + rex && lbx + epsilon < rex) return true;
+      if (rex < epsilon + lex && rbx + epsilon < lex) return false;
+      return lex < rex;
+    }
+
+    const std::vector<Point>& _points;
+    double& _sweep;
+  };
+
+  struct BeachIt;
+
+  typedef std::multimap<double, BeachIt*> SpikeHeap;
+
+  typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
+
+  struct BeachIt {
+    Beach::iterator it;
+
+    BeachIt(Beach::iterator iter) : it(iter) {}
+  };
+
+}
+
+inline void delaunay() {
+  Counter cnt("Number of arcs added: ");
+
+  using namespace _delaunay_bits;
+
+  typedef _delaunay_bits::Part Part;
+  typedef std::vector<std::pair<double, int> > SiteHeap;
+
+
+  std::vector<Point> points;
+  std::vector<Node> nodes;
+
+  for (NodeIt it(g); it != INVALID; ++it) {
+    nodes.push_back(it);
+    points.push_back(coords[it]);
+  }
+
+  SiteHeap siteheap(points.size());
+
+  double sweep;
+
+
+  for (int i = 0; i < int(siteheap.size()); ++i) {
+    siteheap[i] = std::make_pair(points[i].x, i);
+  }
+
+  std::sort(siteheap.begin(), siteheap.end());
+  sweep = siteheap.front().first;
+
+  YLess yless(points, sweep);
+  Beach beach(yless);
+
+  SpikeHeap spikeheap;
+
+  std::set<std::pair<int, int> > arcs;
+
+  int siteindex = 0;
+  {
+    SiteHeap front;
+
+    while (siteindex < int(siteheap.size()) &&
+           siteheap[0].first == siteheap[siteindex].first) {
+      front.push_back(std::make_pair(points[siteheap[siteindex].second].y,
+                                     siteheap[siteindex].second));
+      ++siteindex;
+    }
+
+    std::sort(front.begin(), front.end());
+
+    for (int i = 0; i < int(front.size()); ++i) {
+      int prev = (i == 0 ? -1 : front[i - 1].second);
+      int curr = front[i].second;
+      int next = (i + 1 == int(front.size()) ? -1 : front[i + 1].second);
+
+      beach.insert(std::make_pair(Part(prev, curr, next),
+                                  spikeheap.end()));
+    }
+  }
+
+  while (siteindex < int(points.size()) || !spikeheap.empty()) {
+
+    SpikeHeap::iterator spit = spikeheap.begin();
+
+    if (siteindex < int(points.size()) &&
+        (spit == spikeheap.end() || siteheap[siteindex].first < spit->first)) {
+      int site = siteheap[siteindex].second;
+      sweep = siteheap[siteindex].first;
+
+      Beach::iterator bit = beach.upper_bound(Part(site, site, site));
+
+      if (bit->second != spikeheap.end()) {
+        delete bit->second->second;
+        spikeheap.erase(bit->second);
+      }
+
+      int prev = bit->first.prev;
+      int curr = bit->first.curr;
+      int next = bit->first.next;
+
+      beach.erase(bit);
+
+      SpikeHeap::iterator pit = spikeheap.end();
+      if (prev != -1 &&
+          circle_form(points[prev], points[curr], points[site])) {
+        double x = circle_point(points[prev], points[curr], points[site]);
+        pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        pit->second->it =
+          beach.insert(std::make_pair(Part(prev, curr, site), pit));
+      } else {
+        beach.insert(std::make_pair(Part(prev, curr, site), pit));
+      }
+
+      beach.insert(std::make_pair(Part(curr, site, curr), spikeheap.end()));
+
+      SpikeHeap::iterator nit = spikeheap.end();
+      if (next != -1 &&
+          circle_form(points[site], points[curr],points[next])) {
+        double x = circle_point(points[site], points[curr], points[next]);
+        nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        nit->second->it =
+          beach.insert(std::make_pair(Part(site, curr, next), nit));
+      } else {
+        beach.insert(std::make_pair(Part(site, curr, next), nit));
+      }
+
+      ++siteindex;
+    } else {
+      sweep = spit->first;
+
+      Beach::iterator bit = spit->second->it;
+
+      int prev = bit->first.prev;
+      int curr = bit->first.curr;
+      int next = bit->first.next;
+
+      {
+        std::pair<int, int> arc;
+
+        arc = prev < curr ?
+          std::make_pair(prev, curr) : std::make_pair(curr, prev);
+
+        if (arcs.find(arc) == arcs.end()) {
+          arcs.insert(arc);
+          g.addEdge(nodes[prev], nodes[curr]);
+          ++cnt;
+        }
+
+        arc = curr < next ?
+          std::make_pair(curr, next) : std::make_pair(next, curr);
+
+        if (arcs.find(arc) == arcs.end()) {
+          arcs.insert(arc);
+          g.addEdge(nodes[curr], nodes[next]);
+          ++cnt;
+        }
+      }
+
+      Beach::iterator pbit = bit; --pbit;
+      int ppv = pbit->first.prev;
+      Beach::iterator nbit = bit; ++nbit;
+      int nnt = nbit->first.next;
+
+      if (bit->second != spikeheap.end())
+        {
+          delete bit->second->second;
+          spikeheap.erase(bit->second);
+        }
+      if (pbit->second != spikeheap.end())
+        {
+          delete pbit->second->second;
+          spikeheap.erase(pbit->second);
+        }
+      if (nbit->second != spikeheap.end())
+        {
+          delete nbit->second->second;
+          spikeheap.erase(nbit->second);
+        }
+      
+      beach.erase(nbit);
+      beach.erase(bit);
+      beach.erase(pbit);
+
+      SpikeHeap::iterator pit = spikeheap.end();
+      if (ppv != -1 && ppv != next &&
+          circle_form(points[ppv], points[prev], points[next])) {
+        double x = circle_point(points[ppv], points[prev], points[next]);
+        if (x < sweep) x = sweep;
+        pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        pit->second->it =
+          beach.insert(std::make_pair(Part(ppv, prev, next), pit));
+      } else {
+        beach.insert(std::make_pair(Part(ppv, prev, next), pit));
+      }
+
+      SpikeHeap::iterator nit = spikeheap.end();
+      if (nnt != -1 && prev != nnt &&
+          circle_form(points[prev], points[next], points[nnt])) {
+        double x = circle_point(points[prev], points[next], points[nnt]);
+        if (x < sweep) x = sweep;
+        nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        nit->second->it =
+          beach.insert(std::make_pair(Part(prev, next, nnt), nit));
+      } else {
+        beach.insert(std::make_pair(Part(prev, next, nnt), nit));
+      }
+
+    }
+  }
+
+  for (Beach::iterator it = beach.begin(); it != beach.end(); ++it) {
+    int curr = it->first.curr;
+    int next = it->first.next;
+
+    if (next == -1) continue;
+
+    std::pair<int, int> arc;
+
+    arc = curr < next ?
+      std::make_pair(curr, next) : std::make_pair(next, curr);
+
+    if (arcs.find(arc) == arcs.end()) {
+      arcs.insert(arc);
+      g.addEdge(nodes[curr], nodes[next]);
+      ++cnt;
+    }
+  }
+}
+
+void sparse(int d)
+{
+  Counter cnt("Number of arcs removed: ");
+  Bfs<ListGraph> bfs(g);
+  for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
+      ei!=arcs.rend();++ei)
+    {
+      Node a=g.u(*ei);
+      Node b=g.v(*ei);
+      g.erase(*ei);
+      bfs.run(a,b);
+      if(bfs.predArc(b)==INVALID || bfs.dist(b)>d)
+        g.addEdge(a,b);
+      else cnt++;
+    }
+}
+
+void sparse2(int d)
+{
+  Counter cnt("Number of arcs removed: ");
+  for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
+      ei!=arcs.rend();++ei)
+    {
+      Node a=g.u(*ei);
+      Node b=g.v(*ei);
+      g.erase(*ei);
+      ConstMap<Arc,int> cegy(1);
+      Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
+      int k=sur.run(a,b,2);
+      if(k<2 || sur.totalLength()>d)
+        g.addEdge(a,b);
+      else cnt++;
+//       else std::cout << "Remove arc " << g.id(a) << "-" << g.id(b) << '\n';
+    }
+}
+
+void sparseTriangle(int d)
+{
+  Counter cnt("Number of arcs added: ");
+  std::vector<Parc> pedges;
+  for(NodeIt n(g);n!=INVALID;++n)
+    for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
+      {
+        Parc p;
+        p.a=n;
+        p.b=m;
+        p.len=(coords[m]-coords[n]).normSquare();
+        pedges.push_back(p);
+      }
+  std::sort(pedges.begin(),pedges.end(),pedgeLess);
+  for(std::vector<Parc>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
+    {
+      Line li(pi->a,pi->b);
+      EdgeIt e(g);
+      for(;e!=INVALID && !cross(e,li);++e) ;
+      Edge ne;
+      if(e==INVALID) {
+        ConstMap<Arc,int> cegy(1);
+        Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
+        int k=sur.run(pi->a,pi->b,2);
+        if(k<2 || sur.totalLength()>d)
+          {
+            ne=g.addEdge(pi->a,pi->b);
+            arcs.push_back(ne);
+            cnt++;
+          }
+      }
+    }
+}
+
+template <typename Graph, typename CoordMap>
+class LengthSquareMap {
+public:
+  typedef typename Graph::Edge Key;
+  typedef typename CoordMap::Value::Value Value;
+
+  LengthSquareMap(const Graph& graph, const CoordMap& coords)
+    : _graph(graph), _coords(coords) {}
+
+  Value operator[](const Key& key) const {
+    return (_coords[_graph.v(key)] -
+            _coords[_graph.u(key)]).normSquare();
+  }
+
+private:
+
+  const Graph& _graph;
+  const CoordMap& _coords;
+};
+
+void minTree() {
+  std::vector<Parc> pedges;
+  Timer T;
+  std::cout << T.realTime() << "s: Creating delaunay triangulation...\n";
+  delaunay();
+  std::cout << T.realTime() << "s: Calculating spanning tree...\n";
+  LengthSquareMap<ListGraph, ListGraph::NodeMap<Point> > ls(g, coords);
+  ListGraph::EdgeMap<bool> tree(g);
+  kruskal(g, ls, tree);
+  std::cout << T.realTime() << "s: Removing non tree arcs...\n";
+  std::vector<Edge> remove;
+  for (EdgeIt e(g); e != INVALID; ++e) {
+    if (!tree[e]) remove.push_back(e);
+  }
+  for(int i = 0; i < int(remove.size()); ++i) {
+    g.erase(remove[i]);
+  }
+  std::cout << T.realTime() << "s: Done\n";
+}
+
+void tsp2()
+{
+  std::cout << "Find a tree..." << std::endl;
+
+  minTree();
+
+  std::cout << "Total arc length (tree) : " << totalLen() << std::endl;
+
+  std::cout << "Make it Euler..." << std::endl;
+
+  {
+    std::vector<Node> leafs;
+    for(NodeIt n(g);n!=INVALID;++n)
+      if(countIncEdges(g,n)%2==1) leafs.push_back(n);
+
+//    for(unsigned int i=0;i<leafs.size();i+=2)
+//       g.addArc(leafs[i],leafs[i+1]);
+
+    std::vector<Parc> pedges;
+    for(unsigned int i=0;i<leafs.size()-1;i++)
+      for(unsigned int j=i+1;j<leafs.size();j++)
+        {
+          Node n=leafs[i];
+          Node m=leafs[j];
+          Parc p;
+          p.a=n;
+          p.b=m;
+          p.len=(coords[m]-coords[n]).normSquare();
+          pedges.push_back(p);
+        }
+    std::sort(pedges.begin(),pedges.end(),pedgeLess);
+    for(unsigned int i=0;i<pedges.size();i++)
+      if(countIncEdges(g,pedges[i].a)%2 &&
+         countIncEdges(g,pedges[i].b)%2)
+        g.addEdge(pedges[i].a,pedges[i].b);
+  }
+
+  for(NodeIt n(g);n!=INVALID;++n)
+    if(countIncEdges(g,n)%2 || countIncEdges(g,n)==0 )
+      std::cout << "GEBASZ!!!" << std::endl;
+
+  for(EdgeIt e(g);e!=INVALID;++e)
+    if(g.u(e)==g.v(e))
+      std::cout << "LOOP GEBASZ!!!" << std::endl;
+
+  std::cout << "Number of arcs : " << countEdges(g) << std::endl;
+
+  std::cout << "Total arc length (euler) : " << totalLen() << std::endl;
+
+  ListGraph::EdgeMap<Arc> enext(g);
+  {
+    EulerIt<ListGraph> e(g);
+    Arc eo=e;
+    Arc ef=e;
+//     std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
+    for(++e;e!=INVALID;++e)
+      {
+//         std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
+        enext[eo]=e;
+        eo=e;
+      }
+    enext[eo]=ef;
+  }
+
+  std::cout << "Creating a tour from that..." << std::endl;
+
+  int nnum = countNodes(g);
+  int ednum = countEdges(g);
+
+  for(Arc p=enext[EdgeIt(g)];ednum>nnum;p=enext[p])
+    {
+//       std::cout << "Checking arc " << g.id(p) << std::endl;
+      Arc e=enext[p];
+      Arc f=enext[e];
+      Node n2=g.source(f);
+      Node n1=g.oppositeNode(n2,e);
+      Node n3=g.oppositeNode(n2,f);
+      if(countIncEdges(g,n2)>2)
+        {
+//           std::cout << "Remove an Arc" << std::endl;
+          Arc ff=enext[f];
+          g.erase(e);
+          g.erase(f);
+          if(n1!=n3)
+            {
+              Arc ne=g.direct(g.addEdge(n1,n3),n1);
+              enext[p]=ne;
+              enext[ne]=ff;
+              ednum--;
+            }
+          else {
+            enext[p]=ff;
+            ednum-=2;
+          }
+        }
+    }
+
+  std::cout << "Total arc length (tour) : " << totalLen() << std::endl;
+
+  std::cout << "2-opt the tour..." << std::endl;
+
+  tsp_improve();
+
+  std::cout << "Total arc length (2-opt tour) : " << totalLen() << std::endl;
+}
+
+
+int main(int argc,const char **argv)
+{
+  ArgParser ap(argc,argv);
+
+//   bool eps;
+  bool disc_d, square_d, gauss_d;
+//   bool tsp_a,two_a,tree_a;
+  int num_of_cities=1;
+  double area=1;
+  N=100;
+//   girth=10;
+  std::string ndist("disc");
+  ap.refOption("n", "Number of nodes (default is 100)", N)
+    .intOption("g", "Girth parameter (default is 10)", 10)
+    .refOption("cities", "Number of cities (default is 1)", num_of_cities)
+    .refOption("area", "Full relative area of the cities (default is 1)", area)
+    .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",
+               disc_d)
+    .optionGroup("dist", "disc")
+    .refOption("square", "Nodes are evenly distributed on a unit square",
+               square_d)
+    .optionGroup("dist", "square")
+    .refOption("gauss", "Nodes are located according to a two-dim Gauss "
+               "distribution", gauss_d)
+    .optionGroup("dist", "gauss")
+    .onlyOneGroup("dist")
+    .boolOption("eps", "Also generate .eps output (<prefix>.eps)")
+    .boolOption("nonodes", "Draw only the edges in the generated .eps output")
+    .boolOption("dir", "Directed graph is generated (each edge is replaced by "
+                "two directed arcs)")
+    .boolOption("2con", "Create a two connected planar graph")
+    .optionGroup("alg","2con")
+    .boolOption("tree", "Create a min. cost spanning tree")
+    .optionGroup("alg","tree")
+    .boolOption("tsp", "Create a TSP tour")
+    .optionGroup("alg","tsp")
+    .boolOption("tsp2", "Create a TSP tour (tree based)")
+    .optionGroup("alg","tsp2")
+    .boolOption("dela", "Delaunay triangulation graph")
+    .optionGroup("alg","dela")
+    .onlyOneGroup("alg")
+    .boolOption("rand", "Use time seed for random number generator")
+    .optionGroup("rand", "rand")
+    .intOption("seed", "Random seed", -1)
+    .optionGroup("rand", "seed")
+    .onlyOneGroup("rand")
+    .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
+    .run();
+
+  if (ap["rand"]) {
+    int seed = int(time(0));
+    std::cout << "Random number seed: " << seed << std::endl;
+    rnd = Random(seed);
+  }
+  if (ap.given("seed")) {
+    int seed = ap["seed"];
+    std::cout << "Random number seed: " << seed << std::endl;
+    rnd = Random(seed);
+  }
+
+  std::string prefix;
+  switch(ap.files().size())
+    {
+    case 0:
+      prefix="lgf-gen-out";
+      break;
+    case 1:
+      prefix=ap.files()[0];
+      break;
+    default:
+      std::cerr << "\nAt most one prefix can be given\n\n";
+      exit(1);
+    }
+
+  double sum_sizes=0;
+  std::vector<double> sizes;
+  std::vector<double> cum_sizes;
+  for(int s=0;s<num_of_cities;s++)
+    {
+      //         sum_sizes+=rnd.exponential();
+      double d=rnd();
+      sum_sizes+=d;
+      sizes.push_back(d);
+      cum_sizes.push_back(sum_sizes);
+    }
+  int i=0;
+  for(int s=0;s<num_of_cities;s++)
+    {
+      Point center=(num_of_cities==1?Point(0,0):rnd.disc());
+      if(gauss_d)
+        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
+          Node n=g.addNode();
+          nodes.push_back(n);
+          coords[n]=center+rnd.gauss2()*area*
+            std::sqrt(sizes[s]/sum_sizes);
+        }
+      else if(square_d)
+        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
+          Node n=g.addNode();
+          nodes.push_back(n);
+          coords[n]=center+Point(rnd()*2-1,rnd()*2-1)*area*
+            std::sqrt(sizes[s]/sum_sizes);
+        }
+      else if(disc_d || true)
+        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
+          Node n=g.addNode();
+          nodes.push_back(n);
+          coords[n]=center+rnd.disc()*area*
+            std::sqrt(sizes[s]/sum_sizes);
+        }
+    }
+
+//   for (ListGraph::NodeIt n(g); n != INVALID; ++n) {
+//     std::cerr << coords[n] << std::endl;
+//   }
+
+  if(ap["tsp"]) {
+    tsp();
+    std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
+  }
+  if(ap["tsp2"]) {
+    tsp2();
+    std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
+  }
+  else if(ap["2con"]) {
+    std::cout << "Make triangles\n";
+    //   triangle();
+    sparseTriangle(ap["g"]);
+    std::cout << "Make it sparser\n";
+    sparse2(ap["g"]);
+  }
+  else if(ap["tree"]) {
+    minTree();
+  }
+  else if(ap["dela"]) {
+    delaunay();
+  }
+
+
+  std::cout << "Number of nodes    : " << countNodes(g) << std::endl;
+  std::cout << "Number of arcs    : " << countEdges(g) << std::endl;
+  double tlen=0;
+  for(EdgeIt e(g);e!=INVALID;++e)
+    tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
+  std::cout << "Total arc length  : " << tlen << std::endl;
+
+  if(ap["eps"])
+    graphToEps(g,prefix+".eps").scaleToA4().
+      scale(600).nodeScale(.005).arcWidthScale(.001).preScale(false).
+      coords(coords).hideNodes(ap.given("nonodes")).run();
+
+  if(ap["dir"])
+    DigraphWriter<ListGraph>(g,prefix+".lgf").
+      nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
+      nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
+      run();
+  else GraphWriter<ListGraph>(g,prefix+".lgf").
+         nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
+         nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
+         run();
+}
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/liblemon.git



More information about the debian-med-commit mailing list