Index: .hgignore
===================================================================
--- .hgignore	(revision 385)
+++ .hgignore	(revision 517)
@@ -23,8 +23,14 @@
 lemon/stamp-h2
 doc/Doxyfile
+cmake/cmake.version
 .dirstamp
 .libs/*
 .deps/*
 demo/*.eps
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
 
 syntax: regexp
@@ -35,9 +41,9 @@
 ^autom4te.cache/.*
 ^build-aux/.*
-^objs.*/.*
+^.*objs.*/.*
 ^test/[a-z_]*$
 ^tools/[a-z-_]*$
 ^demo/.*_demo$
-^build/.*
+^.*build.*/.*
 ^doc/gen-images/.*
 CMakeFiles
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 274)
+++ CMakeLists.txt	(revision 527)
@@ -1,6 +1,10 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
-SET(PROJECT_NAME "LEMON")
-SET(PROJECT_VERSION "hg-tip" CACHE STRING "The version string.")
+IF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
+  INCLUDE(${CMAKE_SOURCE_DIR}/cmake/version.cmake)
+ELSE(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
+  SET(PROJECT_NAME "LEMON")
+  SET(PROJECT_VERSION "hg-tip" CACHE STRING "LEMON version string.")
+ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
 
 PROJECT(${PROJECT_NAME})
@@ -10,4 +14,25 @@
 INCLUDE(FindDoxygen)
 INCLUDE(FindGhostscript)
+FIND_PACKAGE(GLPK 4.33)
+
+ADD_DEFINITIONS(-DHAVE_CONFIG_H)
+
+IF(MSVC)
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250 /wd4355 /wd4800 /wd4996")
+# Suppressed warnings:
+# C4250: 'class1' : inherits 'class2::member' via dominance
+# C4355: 'this' : used in base member initializer list
+# C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
+# C4996: 'function': was declared deprecated
+ENDIF(MSVC)
+
+IF(GLPK_FOUND)
+  SET(HAVE_LP TRUE)
+  SET(HAVE_MIP TRUE)
+  SET(HAVE_GLPK TRUE)
+ENDIF(GLPK_FOUND)
+
+INCLUDE(CheckTypeSize)
+CHECK_TYPE_SIZE("long long" LONG_LONG)
 
 ENABLE_TESTING()
@@ -15,16 +40,11 @@
 ADD_SUBDIRECTORY(lemon)
 ADD_SUBDIRECTORY(demo)
+ADD_SUBDIRECTORY(tools)
 ADD_SUBDIRECTORY(doc)
 ADD_SUBDIRECTORY(test)
 
 IF(WIN32)
-  INSTALL(FILES ${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico
-    DESTINATION bin)
-ENDIF(WIN32)
-
-IF(WIN32)
   SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
-  SET(CPACK_PACKAGE_VENDOR
-    "EGRES - Egervary Research Group on Combinatorial Optimization")
+  SET(CPACK_PACKAGE_VENDOR "EGRES")
   SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
     "LEMON - Library of Efficient Models and Optimization in Networks")
@@ -38,34 +58,36 @@
     "${PROJECT_NAME} ${PROJECT_VERSION}")
 
-  # Variables to generate a component-based installer.
-  #SET(CPACK_COMPONENTS_ALL headers library html_documentation)
+  SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
 
-  #SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
-  #SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Static library")
-  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
+  SET(CPACK_COMPONENT_HEADERS_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 for use with the LEMON library")
-  #SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
-  #  "Static library used to build programs with LEMON")
-  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
-  #  "Doxygen generated documentation")
+  SET(CPACK_COMPONENT_HEADERS_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_DEPENDS library)
 
-  #SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
-  #SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
-  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
+  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
+  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
+  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
 
-  #SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
-  #  "Components needed to develop software using LEMON")
-  #SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
-  #  "Documentation of LEMON")
+  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
+    "Components needed to develop software using LEMON")
+  SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
+    "Documentation of LEMON")
 
-  #SET(CPACK_ALL_INSTALL_TYPES Full Developer)
+  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
 
-  #SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
-  #SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
-  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
+  SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
+  SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
+  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
 
   SET(CPACK_GENERATOR "NSIS")
@@ -79,5 +101,5 @@
   SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
   SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
-    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\doc\\\\index.html\\\"
+    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
     ")
   SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
Index: LICENSE
===================================================================
--- LICENSE	(revision 107)
+++ LICENSE	(revision 440)
@@ -2,5 +2,5 @@
 copyright/license.
 
-Copyright (C) 2003-2008 Egervary Jeno Kombinatorikus Optimalizalasi
+Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
 Kutatocsoport (Egervary Combinatorial Optimization Research Group,
 EGRES).
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 363)
+++ Makefile.am	(revision 508)
@@ -13,5 +13,10 @@
 	m4/lx_check_soplex.m4 \
 	CMakeLists.txt \
-	cmake
+	cmake/FindGhostscript.cmake \
+	cmake/FindGLPK.cmake \
+	cmake/version.cmake.in \
+	cmake/version.cmake \
+	cmake/nsis/lemon.ico \
+	cmake/nsis/uninstall.ico
 
 pkgconfigdir = $(libdir)/pkgconfig
Index: cmake/FindGLPK.cmake
===================================================================
--- cmake/FindGLPK.cmake	(revision 473)
+++ cmake/FindGLPK.cmake	(revision 473)
@@ -0,0 +1,20 @@
+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)
+
+FIND_LIBRARY(GLPK_LIBRARY
+  NAMES glpk
+  PATHS ${GLPK_REGKEY}/lib)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR)
+
+IF(GLPK_FOUND)
+  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)
Index: cmake/FindGhostscript.cmake
===================================================================
--- cmake/FindGhostscript.cmake	(revision 225)
+++ cmake/FindGhostscript.cmake	(revision 489)
@@ -4,5 +4,5 @@
   NAMES gs gswin32c
   PATHS "$ENV{ProgramFiles}/gs"
-  PATH_SUFFIXES gs8.61/bin gs8.62/bin
+  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."
 )
Index: cmake/version.cmake.in
===================================================================
--- cmake/version.cmake.in	(revision 478)
+++ cmake/version.cmake.in	(revision 478)
@@ -0,0 +1,2 @@
+SET(PROJECT_NAME "@PACKAGE_NAME@")
+SET(PROJECT_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
Index: configure.ac
===================================================================
--- configure.ac	(revision 363)
+++ configure.ac	(revision 517)
@@ -22,4 +22,10 @@
 dnl Do compilation tests using the C++ compiler.
 AC_LANG([C++])
+
+dnl Check the existence of long long type.
+AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
+if test x"$long_long_found" = x"yes"; then
+  AC_DEFINE([HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
+fi
 
 dnl Checks for programs.
@@ -51,7 +57,11 @@
 
 dnl Checks for libraries.
-#LX_CHECK_GLPK
-#LX_CHECK_CPLEX
-#LX_CHECK_SOPLEX
+LX_CHECK_GLPK
+LX_CHECK_CPLEX
+LX_CHECK_SOPLEX
+LX_CHECK_CLP
+
+AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
+AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
 
 dnl Disable/enable building the demo programs.
@@ -97,8 +107,9 @@
 dnl Add dependencies on files generated by configure.
 AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
-  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in'])
+  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
 
 AC_CONFIG_FILES([
 Makefile
+cmake/version.cmake
 doc/Doxyfile
 lemon/lemon.pc
@@ -115,8 +126,11 @@
 echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
 echo
-#echo GLPK support.................. : $lx_glpk_found
-#echo CPLEX support................. : $lx_cplex_found
-#echo SOPLEX support................ : $lx_soplex_found
-#echo
+echo Compiler supports long long... : $long_long_found
+echo
+echo GLPK support.................. : $lx_glpk_found
+echo CPLEX support................. : $lx_cplex_found
+echo SOPLEX support................ : $lx_soplex_found
+echo CLP support................... : $lx_clp_found
+echo
 echo Build demo programs........... : $enable_demo
 echo Build additional tools........ : $enable_tools
Index: demo/CMakeLists.txt
===================================================================
--- demo/CMakeLists.txt	(revision 225)
+++ demo/CMakeLists.txt	(revision 475)
@@ -1,3 +1,6 @@
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}
+  ${CMAKE_BINARY_DIR}
+)
 
 LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
Index: demo/arg_parser_demo.cc
===================================================================
--- demo/arg_parser_demo.cc	(revision 311)
+++ demo/arg_parser_demo.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: demo/graph_to_eps_demo.cc
===================================================================
--- demo/graph_to_eps_demo.cc	(revision 313)
+++ demo/graph_to_eps_demo.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -86,5 +86,5 @@
     coords(coords).
     title("Sample .eps figure").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     run();
 
@@ -93,5 +93,5 @@
     coords(coords).
     title("Sample .eps figure").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     absoluteNodeSizes().absoluteArcWidths().
     nodeScale(2).nodeSizes(sizes).
@@ -106,5 +106,5 @@
   graphToEps(g,"graph_to_eps_demo_out_3_arr.eps").
     title("Sample .eps figure (with arrowheads)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     absoluteNodeSizes().absoluteArcWidths().
     nodeColors(composeMap(palette,colors)).
@@ -133,5 +133,5 @@
   graphToEps(g,"graph_to_eps_demo_out_4_par.eps").
     title("Sample .eps figure (parallel arcs)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     absoluteNodeSizes().absoluteArcWidths().
     nodeShapes(shapes).
@@ -148,5 +148,5 @@
   graphToEps(g,"graph_to_eps_demo_out_5_par_arr.eps").
     title("Sample .eps figure (parallel arcs and arrowheads)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     absoluteNodeSizes().absoluteArcWidths().
     nodeScale(2).nodeSizes(sizes).
@@ -164,5 +164,5 @@
   graphToEps(g,"graph_to_eps_demo_out_6_par_arr_a4.eps").
     title("Sample .eps figure (fits to A4)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     scaleToA4().
     absoluteNodeSizes().absoluteArcWidths().
@@ -194,5 +194,5 @@
     scale(60).
     title("Sample .eps figure (Palette demo)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     coords(hcoords).
     absoluteNodeSizes().absoluteArcWidths().
Index: demo/lgf_demo.cc
===================================================================
--- demo/lgf_demo.cc	(revision 294)
+++ demo/lgf_demo.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/CMakeLists.txt
===================================================================
--- doc/CMakeLists.txt	(revision 335)
+++ doc/CMakeLists.txt	(revision 518)
@@ -10,4 +10,5 @@
 
 IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
+  FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
   IF(UNIX)
     ADD_CUSTOM_TARGET(html
@@ -36,8 +37,7 @@
       WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
   ENDIF(UNIX)
+  INSTALL(
+    DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
+    DESTINATION share/doc
+    COMPONENT html_documentation)
 ENDIF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
-
-INSTALL(
-  DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
-  DESTINATION doc
-  COMPONENT html_documentation)
Index: doc/coding_style.dox
===================================================================
--- doc/coding_style.dox	(revision 210)
+++ doc/coding_style.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/dirs.dox
===================================================================
--- doc/dirs.dox	(revision 318)
+++ doc/dirs.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -72,5 +72,5 @@
 \brief Auxiliary tools for implementation.
 
-This directory contains some auxiliary classes for implementing graphs, 
+This directory contains some auxiliary classes for implementing graphs,
 maps and some other classes.
 As a user you typically don't have to deal with these files.
Index: doc/groups.dox
===================================================================
--- doc/groups.dox	(revision 418)
+++ doc/groups.dox	(revision 455)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -63,10 +63,12 @@
 
 /**
-@defgroup graph_adaptors Adaptor Classes for graphs
+@defgroup graph_adaptors Adaptor Classes for Graphs
 @ingroup graphs
-\brief This group contains several adaptor classes for digraphs and 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 these, and graph
+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
@@ -74,5 +76,5 @@
 
 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
+instance \c g of a directed graph type, say ListDigraph and an algorithm
 \code
 template <typename Digraph>
@@ -82,11 +84,11 @@
 (in time or in memory usage) to copy \c g with the reversed
 arcs.  In this case, an adaptor class is used, which (according
-to LEMON digraph concepts) works as a digraph.  The adaptor uses the
-original digraph structure and digraph operations when methods of the
-reversed oriented graph are called.  This means that the adaptor have
-minor memory usage, and do not perform sophisticated algorithmic
+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 arc-set or
+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
@@ -97,14 +99,14 @@
 \code
 ListDigraph g;
-ReverseDigraph<ListGraph> rg(g);
+ReverseDigraph<ListDigraph> rg(g);
 int result = algorithm(rg);
 \endcode
-After running the algorithm, the original graph \c g is untouched.
-This techniques gives rise to an elegant code, and based on stable
+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 bipartite matching problems, the residual
+In flow, circulation and matching problems, the residual
 graph is of particular importance. Combining an adaptor implementing
-this, shortest path algorithms and minimum mean cycle algorithms,
+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
@@ -113,21 +115,22 @@
 The behavior of graph adaptors can be very different. Some of them keep
 capabilities of the original graph while in other cases this would be
-meaningless. This means that the concepts that they are models of depend
-on the graph adaptor, and the wrapped graph(s).
-If an arc of \c rg is deleted, this is carried out by deleting the
-corresponding arc of \c g, thus the adaptor modifies the original graph.
-
-But for a residual graph, this operation has no sense.
+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.
-RevGraphAdaptor has constructor
+ReverseDigraph has constructor
 \code
 ReverseDigraph(Digraph& digraph);
 \endcode
-This means that in a situation, when a <tt>const ListDigraph&</tt>
+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>.
+<tt>Digraph=const %ListDigraph</tt>.
 \code
 int algorithm1(const ListDigraph& g) {
-  RevGraphAdaptor<const ListDigraph> rg(g);
+  ReverseDigraph<const ListDigraph> rg(g);
   return algorithm2(rg);
 }
Index: doc/lgf.dox
===================================================================
--- doc/lgf.dox	(revision 313)
+++ doc/lgf.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/license.dox
===================================================================
--- doc/license.dox	(revision 209)
+++ doc/license.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/mainpage.dox
===================================================================
--- doc/mainpage.dox	(revision 314)
+++ doc/mainpage.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/migration.dox
===================================================================
--- doc/migration.dox	(revision 343)
+++ doc/migration.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/named-param.dox
===================================================================
--- doc/named-param.dox	(revision 269)
+++ doc/named-param.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/namespaces.dox
===================================================================
--- doc/namespaces.dox	(revision 209)
+++ doc/namespaces.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/template.h
===================================================================
--- doc/template.h	(revision 209)
+++ doc/template.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/CMakeLists.txt
===================================================================
--- lemon/CMakeLists.txt	(revision 225)
+++ lemon/CMakeLists.txt	(revision 515)
@@ -1,9 +1,33 @@
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}
+  ${CMAKE_BINARY_DIR}
+)
 
-ADD_LIBRARY(lemon
+CONFIGURE_FILE(
+  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/config.h
+)
+
+SET(LEMON_SOURCES
   arg_parser.cc
   base.cc
   color.cc
-  random.cc)
+  lp_base.cc
+  lp_skeleton.cc
+  random.cc
+  bits/windows.cc
+)
+
+IF(HAVE_GLPK)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
+  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIR})
+  IF(WIN32)
+    INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
+    INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
+    INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
+  ENDIF(WIN32)
+ENDIF(HAVE_GLPK)
+
+ADD_LIBRARY(lemon ${LEMON_SOURCES})
 
 INSTALL(
Index: lemon/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 490)
+++ lemon/Makefile.am	(revision 528)
@@ -8,32 +8,67 @@
 
 lemon_libemon_la_SOURCES = \
-        lemon/arg_parser.cc \
-        lemon/base.cc \
-        lemon/color.cc \
-        lemon/random.cc
+	lemon/arg_parser.cc \
+	lemon/base.cc \
+	lemon/color.cc \
+	lemon/lp_base.cc \
+	lemon/lp_skeleton.cc \
+        lemon/random.cc \
+	lemon/bits/windows.cc
 
-#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS) $(AM_CXXFLAGS)
-#lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
+
+lemon_libemon_la_CXXFLAGS = \
+	$(GLPK_CFLAGS) \
+	$(CPLEX_CFLAGS) \
+	$(SOPLEX_CXXFLAGS) \
+	$(CLP_CXXFLAGS)
+
+lemon_libemon_la_LDFLAGS = \
+	$(GLPK_LIBS) \
+	$(CPLEX_LIBS) \
+	$(SOPLEX_LIBS) \
+	$(CLP_LIBS)
+
+if HAVE_GLPK
+lemon_libemon_la_SOURCES += lemon/glpk.cc
+endif
+
+if HAVE_CPLEX
+lemon_libemon_la_SOURCES += lemon/cplex.cc
+endif
+
+if HAVE_SOPLEX
+lemon_libemon_la_SOURCES += lemon/soplex.cc
+endif
+
+if HAVE_CLP
+lemon_libemon_la_SOURCES += lemon/clp.cc
+endif
 
 lemon_HEADERS += \
 	lemon/adaptors.h \
-        lemon/arg_parser.h \
+	lemon/arg_parser.h \
 	lemon/assert.h \
-        lemon/bfs.h \
-        lemon/bin_heap.h \
-        lemon/circulation.h \
-        lemon/color.h \
+	lemon/bfs.h \
+	lemon/bin_heap.h \
+	lemon/circulation.h \
+	lemon/clp.h \
+	lemon/color.h \
 	lemon/concept_check.h \
-        lemon/counter.h \
+	lemon/connectivity.h \
+	lemon/counter.h \
 	lemon/core.h \
-        lemon/dfs.h \
-        lemon/dijkstra.h \
-        lemon/dim2.h \
-        lemon/dimacs.h \
+	lemon/cplex.h \
+	lemon/dfs.h \
+	lemon/dijkstra.h \
+	lemon/dim2.h \
+	lemon/dimacs.h \
+	lemon/edge_set.h \
 	lemon/elevator.h \
 	lemon/error.h \
+	lemon/euler.h \
 	lemon/full_graph.h \
-        lemon/graph_to_eps.h \
-        lemon/grid_graph.h \
+	lemon/glpk.h \
+	lemon/graph_to_eps.h \
+	lemon/grid_graph.h \
 	lemon/hypercube_graph.h \
 	lemon/kruskal.h \
@@ -41,4 +76,8 @@
 	lemon/lgf_reader.h \
 	lemon/lgf_writer.h \
+	lemon/list_graph.h \
+	lemon/lp.h \
+	lemon/lp_base.h \
+	lemon/lp_skeleton.h \
 	lemon/list_graph.h \
 	lemon/maps.h \
@@ -49,10 +88,13 @@
 	lemon/path.h \
 	lemon/preflow.h \
-        lemon/random.h \
+	lemon/radix_sort.h \
+	lemon/random.h \
 	lemon/smart_graph.h \
+	lemon/soplex.h \
 	lemon/suurballe.h \
-        lemon/time_measure.h \
-        lemon/tolerance.h \
-	lemon/unionfind.h
+	lemon/time_measure.h \
+	lemon/tolerance.h \
+	lemon/unionfind.h \
+	lemon/bits/windows.h
 
 bits_HEADERS += \
@@ -60,11 +102,13 @@
 	lemon/bits/array_map.h \
 	lemon/bits/base_extender.h \
-        lemon/bits/bezier.h \
+	lemon/bits/bezier.h \
 	lemon/bits/default_map.h \
-        lemon/bits/enable_if.h \
+	lemon/bits/edge_set_extender.h \
+	lemon/bits/enable_if.h \
 	lemon/bits/graph_adaptor_extender.h \
 	lemon/bits/graph_extender.h \
 	lemon/bits/map_extender.h \
 	lemon/bits/path_dump.h \
+	lemon/bits/solver_bits.h \
 	lemon/bits/traits.h \
 	lemon/bits/variant.h \
Index: lemon/adaptors.h
===================================================================
--- lemon/adaptors.h	(revision 416)
+++ lemon/adaptors.h	(revision 519)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -22,5 +22,5 @@
 /// \ingroup graph_adaptors
 /// \file
-/// \brief Several graph adaptors
+/// \brief Adaptor classes for digraphs and graphs
 ///
 /// This file contains several useful adaptors for digraphs and graphs.
@@ -31,4 +31,5 @@
 
 #include <lemon/bits/graph_adaptor_extender.h>
+#include <lemon/bits/map_extender.h>
 #include <lemon/tolerance.h>
 
@@ -37,21 +38,26 @@
 namespace lemon {
 
-  template<typename _Digraph>
+#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 _Digraph Digraph;
+    typedef DGR Digraph;
     typedef DigraphAdaptorBase Adaptor;
-    typedef Digraph ParentDigraph;
 
   protected:
-    Digraph* _digraph;
+    DGR* _digraph;
     DigraphAdaptorBase() : _digraph(0) { }
-    void setDigraph(Digraph& digraph) { _digraph = &digraph; }
-
-  public:
-    DigraphAdaptorBase(Digraph& digraph) : _digraph(&digraph) { }
-
-    typedef typename Digraph::Node Node;
-    typedef typename Digraph::Arc Arc;
+    void 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); }
@@ -68,12 +74,12 @@
     Node target(const Arc& a) const { return _digraph->target(a); }
 
-    typedef NodeNumTagIndicator<Digraph> NodeNumTag;
+    typedef NodeNumTagIndicator<DGR> NodeNumTag;
     int nodeNum() const { return _digraph->nodeNum(); }
 
-    typedef EdgeNumTagIndicator<Digraph> EdgeNumTag;
+    typedef ArcNumTagIndicator<DGR> ArcNumTag;
     int arcNum() const { return _digraph->arcNum(); }
 
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
-    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) {
+    typedef FindArcTagIndicator<DGR> FindArcTag;
+    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const {
       return _digraph->findArc(u, v, prev);
     }
@@ -82,8 +88,8 @@
     Arc addArc(const Node& u, const Node& v) { return _digraph->addArc(u, v); }
 
-    void erase(const Node& n) const { _digraph->erase(n); }
-    void erase(const Arc& a) const { _digraph->erase(a); }
-
-    void clear() const { _digraph->clear(); }
+    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); }
@@ -96,20 +102,20 @@
     int maxArcId() const { return _digraph->maxArcId(); }
 
-    typedef typename ItemSetTraits<Digraph, Node>::ItemNotifier NodeNotifier;
+    typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
     NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
 
-    typedef typename ItemSetTraits<Digraph, Arc>::ItemNotifier ArcNotifier;
+    typedef typename ItemSetTraits<DGR, Arc>::ItemNotifier ArcNotifier;
     ArcNotifier& notifier(Arc) const { return _digraph->notifier(Arc()); }
 
-    template <typename _Value>
-    class NodeMap : public Digraph::template NodeMap<_Value> {
+    template <typename V>
+    class NodeMap : public DGR::template NodeMap<V> {
     public:
 
-      typedef typename Digraph::template NodeMap<_Value> Parent;
+      typedef typename DGR::template NodeMap<V> Parent;
 
       explicit NodeMap(const Adaptor& adaptor)
         : Parent(*adaptor._digraph) {}
 
-      NodeMap(const Adaptor& adaptor, const _Value& value)
+      NodeMap(const Adaptor& adaptor, const V& value)
         : Parent(*adaptor._digraph, value) { }
 
@@ -127,14 +133,14 @@
     };
 
-    template <typename _Value>
-    class ArcMap : public Digraph::template ArcMap<_Value> {
+    template <typename V>
+    class ArcMap : public DGR::template ArcMap<V> {
     public:
 
-      typedef typename Digraph::template ArcMap<_Value> Parent;
-
-      explicit ArcMap(const Adaptor& adaptor)
+      typedef typename DGR::template ArcMap<V> Parent;
+
+      explicit ArcMap(const DigraphAdaptorBase<DGR>& adaptor)
         : Parent(*adaptor._digraph) {}
 
-      ArcMap(const Adaptor& adaptor, const _Value& value)
+      ArcMap(const DigraphAdaptorBase<DGR>& adaptor, const V& value)
         : Parent(*adaptor._digraph, value) {}
 
@@ -154,23 +160,22 @@
   };
 
-  template<typename _Graph>
+  template<typename GR>
   class GraphAdaptorBase {
   public:
-    typedef _Graph Graph;
-    typedef Graph ParentGraph;
+    typedef GR Graph;
 
   protected:
-    Graph* _graph;
+    GR* _graph;
 
     GraphAdaptorBase() : _graph(0) {}
 
-    void setGraph(Graph& graph) { _graph = &graph; }
-
-  public:
-    GraphAdaptorBase(Graph& graph) : _graph(&graph) {}
-
-    typedef typename Graph::Node Node;
-    typedef typename Graph::Arc Arc;
-    typedef typename Graph::Edge Edge;
+    void 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); }
@@ -199,13 +204,19 @@
     int nodeNum() const { return _graph->nodeNum(); }
 
+    typedef ArcNumTagIndicator<Graph> ArcNumTag;
+    int arcNum() const { return _graph->arcNum(); }
+
     typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
-    int arcNum() const { return _graph->arcNum(); }
     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;
-    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) {
-      return _graph->findArc(u, v, prev);
-    }
-    Edge findEdge(const Node& u, const Node& v, const Edge& prev = INVALID) {
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
       return _graph->findEdge(u, v, prev);
     }
@@ -234,20 +245,20 @@
     int maxEdgeId() const { return _graph->maxEdgeId(); }
 
-    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
+    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
     NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
 
-    typedef typename ItemSetTraits<Graph, Arc>::ItemNotifier ArcNotifier;
+    typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
     ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
 
-    typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
+    typedef typename ItemSetTraits<GR, Edge>::ItemNotifier EdgeNotifier;
     EdgeNotifier& notifier(Edge) const { return _graph->notifier(Edge()); }
 
-    template <typename _Value>
-    class NodeMap : public Graph::template NodeMap<_Value> {
+    template <typename V>
+    class NodeMap : public GR::template NodeMap<V> {
     public:
-      typedef typename Graph::template NodeMap<_Value> Parent;
-      explicit NodeMap(const GraphAdaptorBase<Graph>& adapter)
+      typedef typename GR::template NodeMap<V> Parent;
+      explicit NodeMap(const GraphAdaptorBase<GR>& adapter)
         : Parent(*adapter._graph) {}
-      NodeMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
+      NodeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
         : Parent(*adapter._graph, value) {}
 
@@ -265,11 +276,11 @@
     };
 
-    template <typename _Value>
-    class ArcMap : public Graph::template ArcMap<_Value> {
+    template <typename V>
+    class ArcMap : public GR::template ArcMap<V> {
     public:
-      typedef typename Graph::template ArcMap<_Value> Parent;
-      explicit ArcMap(const GraphAdaptorBase<Graph>& adapter)
+      typedef typename GR::template ArcMap<V> Parent;
+      explicit ArcMap(const GraphAdaptorBase<GR>& adapter)
         : Parent(*adapter._graph) {}
-      ArcMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
+      ArcMap(const GraphAdaptorBase<GR>& adapter, const V& value)
         : Parent(*adapter._graph, value) {}
 
@@ -286,11 +297,11 @@
     };
 
-    template <typename _Value>
-    class EdgeMap : public Graph::template EdgeMap<_Value> {
+    template <typename V>
+    class EdgeMap : public GR::template EdgeMap<V> {
     public:
-      typedef typename Graph::template EdgeMap<_Value> Parent;
-      explicit EdgeMap(const GraphAdaptorBase<Graph>& adapter)
+      typedef typename GR::template EdgeMap<V> Parent;
+      explicit EdgeMap(const GraphAdaptorBase<GR>& adapter)
         : Parent(*adapter._graph) {}
-      EdgeMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
+      EdgeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
         : Parent(*adapter._graph, value) {}
 
@@ -309,9 +320,9 @@
   };
 
-  template <typename _Digraph>
-  class ReverseDigraphBase : public DigraphAdaptorBase<_Digraph> {
-  public:
-    typedef _Digraph Digraph;
-    typedef DigraphAdaptorBase<_Digraph> Parent;
+  template <typename DGR>
+  class ReverseDigraphBase : public DigraphAdaptorBase<DGR> {
+  public:
+    typedef DGR Digraph;
+    typedef DigraphAdaptorBase<DGR> Parent;
   protected:
     ReverseDigraphBase() : Parent() { }
@@ -331,7 +342,7 @@
     Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); }
 
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    typedef FindArcTagIndicator<DGR> FindArcTag;
     Arc findArc(const Node& u, const Node& v,
-                const Arc& prev = INVALID) {
+                const Arc& prev = INVALID) const {
       return Parent::findArc(v, u, prev);
     }
@@ -341,19 +352,31 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief A digraph adaptor which reverses the orientation of the arcs.
-  ///
-  /// ReverseDigraph reverses the arcs in the adapted digraph. The
-  /// SubDigraph is conform to the \ref concepts::Digraph
-  /// "Digraph concept".
-  ///
-  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
-  /// "Digraph concept". The type can be specified to be const.
-  template<typename _Digraph>
+  /// \brief Adaptor class for reversing the orientation of the arcs in
+  /// a digraph.
+  ///
+  /// ReverseDigraph can be used for reversing the arcs in a digraph.
+  /// It conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam 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<_Digraph> > {
-  public:
-    typedef _Digraph Digraph;
-    typedef DigraphAdaptorExtender<
-      ReverseDigraphBase<_Digraph> > Parent;
+    public DigraphAdaptorExtender<ReverseDigraphBase<DGR> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef DGR Digraph;
+    typedef DigraphAdaptorExtender<ReverseDigraphBase<DGR> > Parent;
   protected:
     ReverseDigraph() { }
@@ -362,39 +385,40 @@
     /// \brief Constructor
     ///
-    /// Creates a reverse digraph adaptor for the given digraph
-    explicit ReverseDigraph(Digraph& digraph) {
-      Parent::setDigraph(digraph);
+    /// Creates a reverse digraph adaptor for the given digraph.
+    explicit ReverseDigraph(DGR& digraph) {
+      Parent::initialize(digraph);
     }
   };
 
-  /// \brief Just gives back a reverse digraph adaptor
-  ///
-  /// Just gives back a reverse digraph adaptor
-  template<typename Digraph>
-  ReverseDigraph<const Digraph> reverseDigraph(const Digraph& digraph) {
-    return ReverseDigraph<const Digraph>(digraph);
+  /// \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 _Digraph, typename _NodeFilterMap,
-            typename _ArcFilterMap, bool _checked = true>
-  class SubDigraphBase : public DigraphAdaptorBase<_Digraph> {
-  public:
-    typedef _Digraph Digraph;
-    typedef _NodeFilterMap NodeFilterMap;
-    typedef _ArcFilterMap ArcFilterMap;
+
+  template <typename DGR, typename NF, typename AF, bool ch = true>
+  class SubDigraphBase : public DigraphAdaptorBase<DGR> {
+  public:
+    typedef DGR Digraph;
+    typedef NF NodeFilterMap;
+    typedef AF ArcFilterMap;
 
     typedef SubDigraphBase Adaptor;
-    typedef DigraphAdaptorBase<_Digraph> Parent;
+    typedef DigraphAdaptorBase<DGR> Parent;
   protected:
-    NodeFilterMap* _node_filter;
-    ArcFilterMap* _arc_filter;
+    NF* _node_filter;
+    AF* _arc_filter;
     SubDigraphBase()
       : Parent(), _node_filter(0), _arc_filter(0) { }
 
-    void setNodeFilterMap(NodeFilterMap& node_filter) {
+    void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
+      Parent::initialize(digraph);
       _node_filter = &node_filter;
-    }
-    void setArcFilterMap(ArcFilterMap& arc_filter) {
-      _arc_filter = &arc_filter;
+      _arc_filter = &arc_filter;      
     }
 
@@ -458,19 +482,16 @@
     }
 
-    void hide(const Node& n) const { _node_filter->set(n, false); }
-    void hide(const Arc& a) const { _arc_filter->set(a, false); }
-
-    void unHide(const Node& n) const { _node_filter->set(n, true); }
-    void unHide(const Arc& a) const { _arc_filter->set(a, true); }
-
-    bool hidden(const Node& n) const { return !(*_node_filter)[n]; }
-    bool hidden(const Arc& a) const { return !(*_arc_filter)[a]; }
+    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 EdgeNumTag;
-
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    typedef False ArcNumTag;
+
+    typedef FindArcTagIndicator<DGR> FindArcTag;
     Arc findArc(const Node& source, const Node& target,
-                const Arc& prev = INVALID) {
+                const Arc& prev = INVALID) const {
       if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
         return INVALID;
@@ -483,16 +504,19 @@
     }
 
-    template <typename _Value>
-    class NodeMap : public SubMapExtender<Adaptor,
-      typename Parent::template NodeMap<_Value> > {
+  public:
+
+    template <typename V>
+    class NodeMap 
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 
+	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template NodeMap<Value> > MapParent;
-
-      NodeMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-      NodeMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+	    LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
+
+      NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
+        : Parent(adaptor) {}
+      NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -503,21 +527,22 @@
       template <typename CMap>
       NodeMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
     };
 
-    template <typename _Value>
-    class ArcMap : public SubMapExtender<Adaptor,
-      typename Parent::template ArcMap<_Value> > {
+    template <typename V>
+    class ArcMap 
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template ArcMap<Value> > MapParent;
-
-      ArcMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-      ArcMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
+
+      ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
+        : Parent(adaptor) {}
+      ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -528,5 +553,5 @@
       template <typename CMap>
       ArcMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
@@ -535,25 +560,24 @@
   };
 
-  template <typename _Digraph, typename _NodeFilterMap, typename _ArcFilterMap>
-  class SubDigraphBase<_Digraph, _NodeFilterMap, _ArcFilterMap, false>
-    : public DigraphAdaptorBase<_Digraph> {
-  public:
-    typedef _Digraph Digraph;
-    typedef _NodeFilterMap NodeFilterMap;
-    typedef _ArcFilterMap ArcFilterMap;
+  template <typename DGR, typename NF, typename AF>
+  class SubDigraphBase<DGR, NF, AF, false>
+    : public DigraphAdaptorBase<DGR> {
+  public:
+    typedef DGR Digraph;
+    typedef NF NodeFilterMap;
+    typedef AF ArcFilterMap;
 
     typedef SubDigraphBase Adaptor;
     typedef DigraphAdaptorBase<Digraph> Parent;
   protected:
-    NodeFilterMap* _node_filter;
-    ArcFilterMap* _arc_filter;
+    NF* _node_filter;
+    AF* _arc_filter;
     SubDigraphBase()
       : Parent(), _node_filter(0), _arc_filter(0) { }
 
-    void setNodeFilterMap(NodeFilterMap& node_filter) {
+    void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
+      Parent::initialize(digraph);
       _node_filter = &node_filter;
-    }
-    void setArcFilterMap(ArcFilterMap& arc_filter) {
-      _arc_filter = &arc_filter;
+      _arc_filter = &arc_filter;      
     }
 
@@ -601,19 +625,16 @@
     }
 
-    void hide(const Node& n) const { _node_filter->set(n, false); }
-    void hide(const Arc& e) const { _arc_filter->set(e, false); }
-
-    void unHide(const Node& n) const { _node_filter->set(n, true); }
-    void unHide(const Arc& e) const { _arc_filter->set(e, true); }
-
-    bool hidden(const Node& n) const { return !(*_node_filter)[n]; }
-    bool hidden(const Arc& e) const { return !(*_arc_filter)[e]; }
+    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 EdgeNumTag;
-
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    typedef False ArcNumTag;
+
+    typedef FindArcTagIndicator<DGR> FindArcTag;
     Arc findArc(const Node& source, const Node& target,
-                const Arc& prev = INVALID) {
+                const Arc& prev = INVALID) const {
       if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
         return INVALID;
@@ -626,16 +647,17 @@
     }
 
-    template <typename _Value>
-    class NodeMap : public SubMapExtender<Adaptor,
-      typename Parent::template NodeMap<_Value> > {
+    template <typename V>
+    class NodeMap 
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template NodeMap<Value> > MapParent;
-
-      NodeMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-      NodeMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
+
+      NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
+        : Parent(adaptor) {}
+      NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -646,21 +668,22 @@
       template <typename CMap>
       NodeMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
     };
 
-    template <typename _Value>
-    class ArcMap : public SubMapExtender<Adaptor,
-      typename Parent::template ArcMap<_Value> > {
+    template <typename V>
+    class ArcMap 
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template ArcMap<Value> > MapParent;
-
-      ArcMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-      ArcMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
+
+      ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
+        : Parent(adaptor) {}
+      ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -671,5 +694,5 @@
       template <typename CMap>
       ArcMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
@@ -680,40 +703,55 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief An adaptor for hiding nodes and arcs in a digraph
-  ///
-  /// SubDigraph hides nodes and arcs in a digraph. A bool node map
-  /// and a bool arc map must be specified, which define the filters
-  /// for nodes and arcs. Just the nodes and arcs with true value are
-  /// shown in the subdigraph. The SubDigraph is conform to the \ref
-  /// concepts::Digraph "Digraph concept". If the \c _checked parameter
-  /// is true, then the arcs incident to filtered nodes are also
-  /// filtered out.
-  ///
-  /// \tparam _Digraph It must be conform to the \ref
-  /// concepts::Digraph "Digraph concept". The type can be specified
-  /// to const.
-  /// \tparam _NodeFilterMap A bool valued node map of the the adapted digraph.
-  /// \tparam _ArcFilterMap A bool valued arc map of the the adapted digraph.
-  /// \tparam _checked If the parameter is false then the arc filtering
-  /// is not checked with respect to node filter. Otherwise, each arc
-  /// is automatically filtered, which is incident to a filtered node.
+  /// \brief Adaptor class for hiding nodes and arcs in a digraph
+  ///
+  /// SubDigraph can be used for hiding nodes and arcs in a digraph.
+  /// A \c bool node map and a \c bool arc map must be specified, which
+  /// define the filters for nodes and arcs.
+  /// Only the nodes and arcs with \c true filter value are
+  /// shown in the subdigraph. The arcs that are incident to hidden
+  /// nodes are also filtered out.
+  /// This adaptor conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam 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
-  template<typename _Digraph,
-           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
-           typename _ArcFilterMap = typename _Digraph::template ArcMap<bool>,
-           bool _checked = true>
-  class SubDigraph
-    : public DigraphAdaptorExtender<
-      SubDigraphBase<_Digraph, _NodeFilterMap, _ArcFilterMap, _checked> > {
-  public:
-    typedef _Digraph Digraph;
-    typedef _NodeFilterMap NodeFilterMap;
-    typedef _ArcFilterMap ArcFilterMap;
-
-    typedef DigraphAdaptorExtender<
-      SubDigraphBase<Digraph, NodeFilterMap, ArcFilterMap, _checked> >
-    Parent;
+#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;
@@ -726,110 +764,123 @@
     /// \brief Constructor
     ///
-    /// Creates a subdigraph for the given digraph with
-    /// given node and arc map filters.
-    SubDigraph(Digraph& digraph, NodeFilterMap& node_filter,
-               ArcFilterMap& arc_filter) {
-      setDigraph(digraph);
-      setNodeFilterMap(node_filter);
-      setArcFilterMap(arc_filter);
-    }
-
-    /// \brief Hides the node of the graph
-    ///
-    /// This function hides \c n in the digraph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c n
-    /// to be false in the corresponding node-map.
-    void hide(const Node& n) const { Parent::hide(n); }
-
-    /// \brief Hides the arc of the graph
-    ///
-    /// This function hides \c a in the digraph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c a
-    /// to be false in the corresponding arc-map.
-    void hide(const Arc& a) const { Parent::hide(a); }
-
-    /// \brief Unhides the node of the graph
-    ///
-    /// The value of \c n is set to be true in the node-map which stores
-    /// hide information. If \c n was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Node& n) const { Parent::unHide(n); }
-
-    /// \brief Unhides the arc of the graph
-    ///
-    /// The value of \c a is set to be true in the arc-map which stores
-    /// hide information. If \c a was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Arc& a) const { Parent::unHide(a); }
-
-    /// \brief Returns true if \c n is hidden.
-    ///
-    /// Returns true if \c n is hidden.
-    ///
-    bool hidden(const Node& n) const { return Parent::hidden(n); }
-
-    /// \brief Returns true if \c a is hidden.
-    ///
-    /// Returns true if \c a is hidden.
-    ///
-    bool hidden(const Arc& a) const { return Parent::hidden(a); }
+    /// 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 Just gives back a subdigraph
-  ///
-  /// Just gives back a subdigraph
-  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
-  SubDigraph<const Digraph, NodeFilterMap, ArcFilterMap>
-  subDigraph(const Digraph& digraph, NodeFilterMap& nfm, ArcFilterMap& afm) {
-    return SubDigraph<const Digraph, NodeFilterMap, ArcFilterMap>
-      (digraph, nfm, afm);
+  /// \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 Digraph, typename NodeFilterMap, typename ArcFilterMap>
-  SubDigraph<const Digraph, const NodeFilterMap, ArcFilterMap>
-  subDigraph(const Digraph& digraph,
-             const NodeFilterMap& nfm, ArcFilterMap& afm) {
-    return SubDigraph<const Digraph, const NodeFilterMap, ArcFilterMap>
-      (digraph, nfm, afm);
+  template<typename 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 Digraph, typename NodeFilterMap, typename ArcFilterMap>
-  SubDigraph<const Digraph, NodeFilterMap, const ArcFilterMap>
-  subDigraph(const Digraph& digraph,
-             NodeFilterMap& nfm, const ArcFilterMap& afm) {
-    return SubDigraph<const Digraph, NodeFilterMap, const ArcFilterMap>
-      (digraph, nfm, afm);
+  template<typename 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 Digraph, typename NodeFilterMap, typename ArcFilterMap>
-  SubDigraph<const Digraph, const NodeFilterMap, const ArcFilterMap>
-  subDigraph(const Digraph& digraph,
-             const NodeFilterMap& nfm, const ArcFilterMap& afm) {
-    return SubDigraph<const Digraph, const NodeFilterMap,
-      const ArcFilterMap>(digraph, nfm, afm);
+  template<typename 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 _Graph, typename NodeFilterMap,
-            typename EdgeFilterMap, bool _checked = true>
-  class SubGraphBase : public GraphAdaptorBase<_Graph> {
-  public:
-    typedef _Graph Graph;
+  template <typename GR, typename NF, typename EF, bool ch = true>
+  class SubGraphBase : public GraphAdaptorBase<GR> {
+  public:
+    typedef GR Graph;
+    typedef NF NodeFilterMap;
+    typedef EF EdgeFilterMap;
+
     typedef SubGraphBase Adaptor;
-    typedef GraphAdaptorBase<_Graph> Parent;
+    typedef GraphAdaptorBase<GR> Parent;
   protected:
 
-    NodeFilterMap* _node_filter_map;
-    EdgeFilterMap* _edge_filter_map;
+    NF* _node_filter;
+    EF* _edge_filter;
 
     SubGraphBase()
-      : Parent(), _node_filter_map(0), _edge_filter_map(0) { }
-
-    void setNodeFilterMap(NodeFilterMap& node_filter_map) {
-      _node_filter_map=&node_filter_map;
-    }
-    void setEdgeFilterMap(EdgeFilterMap& edge_filter_map) {
-      _edge_filter_map=&edge_filter_map;
+      : 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;
     }
 
@@ -842,12 +893,12 @@
     void first(Node& i) const {
       Parent::first(i);
-      while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
     }
 
     void first(Arc& i) const {
       Parent::first(i);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::source(i)]
-                            || !(*_node_filter_map)[Parent::target(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::source(i)]
+                            || !(*_node_filter)[Parent::target(i)]))
         Parent::next(i);
     }
@@ -855,7 +906,7 @@
     void first(Edge& i) const {
       Parent::first(i);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::u(i)]
-                            || !(*_node_filter_map)[Parent::v(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::u(i)]
+                            || !(*_node_filter)[Parent::v(i)]))
         Parent::next(i);
     }
@@ -863,6 +914,6 @@
     void firstIn(Arc& i, const Node& n) const {
       Parent::firstIn(i, n);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::source(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::source(i)]))
         Parent::nextIn(i);
     }
@@ -870,6 +921,6 @@
     void firstOut(Arc& i, const Node& n) const {
       Parent::firstOut(i, n);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::target(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::target(i)]))
         Parent::nextOut(i);
     }
@@ -877,7 +928,7 @@
     void firstInc(Edge& i, bool& d, const Node& n) const {
       Parent::firstInc(i, d, n);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::u(i)]
-                            || !(*_node_filter_map)[Parent::v(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::u(i)]
+                            || !(*_node_filter)[Parent::v(i)]))
         Parent::nextInc(i, d);
     }
@@ -885,12 +936,12 @@
     void next(Node& i) const {
       Parent::next(i);
-      while (i!=INVALID && !(*_node_filter_map)[i]) 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_map)[i]
-                            || !(*_node_filter_map)[Parent::source(i)]
-                            || !(*_node_filter_map)[Parent::target(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::source(i)]
+                            || !(*_node_filter)[Parent::target(i)]))
         Parent::next(i);
     }
@@ -898,7 +949,7 @@
     void next(Edge& i) const {
       Parent::next(i);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::u(i)]
-                            || !(*_node_filter_map)[Parent::v(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::u(i)]
+                            || !(*_node_filter)[Parent::v(i)]))
         Parent::next(i);
     }
@@ -906,6 +957,6 @@
     void nextIn(Arc& i) const {
       Parent::nextIn(i);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::source(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::source(i)]))
         Parent::nextIn(i);
     }
@@ -913,6 +964,6 @@
     void nextOut(Arc& i) const {
       Parent::nextOut(i);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::target(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::target(i)]))
         Parent::nextOut(i);
     }
@@ -920,41 +971,41 @@
     void nextInc(Edge& i, bool& d) const {
       Parent::nextInc(i, d);
-      while (i!=INVALID && (!(*_edge_filter_map)[i]
-                            || !(*_node_filter_map)[Parent::u(i)]
-                            || !(*_node_filter_map)[Parent::v(i)]))
+      while (i!=INVALID && (!(*_edge_filter)[i]
+                            || !(*_node_filter)[Parent::u(i)]
+                            || !(*_node_filter)[Parent::v(i)]))
         Parent::nextInc(i, d);
     }
 
-    void hide(const Node& n) const { _node_filter_map->set(n, false); }
-    void hide(const Edge& e) const { _edge_filter_map->set(e, false); }
-
-    void unHide(const Node& n) const { _node_filter_map->set(n, true); }
-    void unHide(const Edge& e) const { _edge_filter_map->set(e, true); }
-
-    bool hidden(const Node& n) const { return !(*_node_filter_map)[n]; }
-    bool hidden(const Edge& e) const { return !(*_edge_filter_map)[e]; }
+    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;
-    Arc findArc(const Node& u, const Node& v,
-                const Arc& prev = INVALID) {
-      if (!(*_node_filter_map)[u] || !(*_node_filter_map)[v]) {
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
+      if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
         return INVALID;
       }
-      Arc arc = Parent::findArc(u, v, prev);
-      while (arc != INVALID && !(*_edge_filter_map)[arc]) {
-        arc = Parent::findArc(u, v, arc);
-      }
-      return arc;
-    }
-    Edge findEdge(const Node& u, const Node& v,
-                  const Edge& prev = INVALID) {
-      if (!(*_node_filter_map)[u] || !(*_node_filter_map)[v]) {
-        return INVALID;
-      }
       Edge edge = Parent::findEdge(u, v, prev);
-      while (edge != INVALID && !(*_edge_filter_map)[edge]) {
+      while (edge != INVALID && !(*_edge_filter)[edge]) {
         edge = Parent::findEdge(u, v, edge);
       }
@@ -962,16 +1013,17 @@
     }
 
-    template <typename _Value>
-    class NodeMap : public SubMapExtender<Adaptor,
-      typename Parent::template NodeMap<_Value> > {
+    template <typename V>
+    class NodeMap 
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template NodeMap<Value> > MapParent;
-
-      NodeMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-      NodeMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
+
+      NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
+        : Parent(adaptor) {}
+      NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -982,21 +1034,22 @@
       template <typename CMap>
       NodeMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
     };
 
-    template <typename _Value>
-    class ArcMap : public SubMapExtender<Adaptor,
-      typename Parent::template ArcMap<_Value> > {
+    template <typename V>
+    class ArcMap 
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template ArcMap<Value> > MapParent;
-
-      ArcMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-      ArcMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
+
+      ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
+        : Parent(adaptor) {}
+      ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -1007,22 +1060,23 @@
       template <typename CMap>
       ArcMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
     };
 
-    template <typename _Value>
-    class EdgeMap : public SubMapExtender<Adaptor,
-      typename Parent::template EdgeMap<_Value> > {
+    template <typename V>
+    class EdgeMap 
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template EdgeMap<Value> > MapParent;
-
-      EdgeMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-
-      EdgeMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
+
+      EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
+        : Parent(adaptor) {}
+
+      EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -1033,5 +1087,5 @@
       template <typename CMap>
       EdgeMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
@@ -1040,22 +1094,24 @@
   };
 
-  template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
-  class SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap, false>
-    : public GraphAdaptorBase<_Graph> {
-  public:
-    typedef _Graph Graph;
+  template <typename GR, typename NF, typename EF>
+  class SubGraphBase<GR, NF, EF, false>
+    : public GraphAdaptorBase<GR> {
+  public:
+    typedef GR Graph;
+    typedef NF NodeFilterMap;
+    typedef EF EdgeFilterMap;
+
     typedef SubGraphBase Adaptor;
-    typedef GraphAdaptorBase<_Graph> Parent;
+    typedef GraphAdaptorBase<GR> Parent;
   protected:
-    NodeFilterMap* _node_filter_map;
-    EdgeFilterMap* _edge_filter_map;
-    SubGraphBase() : Parent(),
-                     _node_filter_map(0), _edge_filter_map(0) { }
-
-    void setNodeFilterMap(NodeFilterMap& node_filter_map) {
-      _node_filter_map=&node_filter_map;
-    }
-    void setEdgeFilterMap(EdgeFilterMap& edge_filter_map) {
-      _edge_filter_map=&edge_filter_map;
+    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;
     }
 
@@ -1068,83 +1124,83 @@
     void first(Node& i) const {
       Parent::first(i);
-      while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
     }
 
     void first(Arc& i) const {
       Parent::first(i);
-      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
     }
 
     void first(Edge& i) const {
       Parent::first(i);
-      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(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_map)[i]) Parent::nextIn(i);
+      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_map)[i]) Parent::nextOut(i);
+      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_map)[i]) Parent::nextInc(i, d);
+      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
     }
 
     void next(Node& i) const {
       Parent::next(i);
-      while (i!=INVALID && !(*_node_filter_map)[i]) 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_map)[i]) 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_map)[i]) 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_map)[i]) 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_map)[i]) 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_map)[i]) Parent::nextInc(i, d);
-    }
-
-    void hide(const Node& n) const { _node_filter_map->set(n, false); }
-    void hide(const Edge& e) const { _edge_filter_map->set(e, false); }
-
-    void unHide(const Node& n) const { _node_filter_map->set(n, true); }
-    void unHide(const Edge& e) const { _edge_filter_map->set(e, true); }
-
-    bool hidden(const Node& n) const { return !(*_node_filter_map)[n]; }
-    bool hidden(const Edge& e) const { return !(*_edge_filter_map)[e]; }
+      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;
-    Arc findArc(const Node& u, const Node& v,
-                const Arc& prev = INVALID) {
-      Arc arc = Parent::findArc(u, v, prev);
-      while (arc != INVALID && !(*_edge_filter_map)[arc]) {
-        arc = Parent::findArc(u, v, arc);
-      }
-      return arc;
-    }
     Edge findEdge(const Node& u, const Node& v,
-                  const Edge& prev = INVALID) {
+                  const Edge& prev = INVALID) const {
       Edge edge = Parent::findEdge(u, v, prev);
-      while (edge != INVALID && !(*_edge_filter_map)[edge]) {
+      while (edge != INVALID && !(*_edge_filter)[edge]) {
         edge = Parent::findEdge(u, v, edge);
       }
@@ -1152,16 +1208,17 @@
     }
 
-    template <typename _Value>
-    class NodeMap : public SubMapExtender<Adaptor,
-      typename Parent::template NodeMap<_Value> > {
+    template <typename V>
+    class NodeMap 
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template NodeMap<Value> > MapParent;
-
-      NodeMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-      NodeMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
+
+      NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
+        : Parent(adaptor) {}
+      NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -1172,21 +1229,22 @@
       template <typename CMap>
       NodeMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
     };
 
-    template <typename _Value>
-    class ArcMap : public SubMapExtender<Adaptor,
-      typename Parent::template ArcMap<_Value> > {
+    template <typename V>
+    class ArcMap 
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template ArcMap<Value> > MapParent;
-
-      ArcMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-      ArcMap(const Adaptor& adaptor, const Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
+
+      ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
+        : Parent(adaptor) {}
+      ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -1197,22 +1255,23 @@
       template <typename CMap>
       ArcMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
     };
 
-    template <typename _Value>
-    class EdgeMap : public SubMapExtender<Adaptor,
-      typename Parent::template EdgeMap<_Value> > {
+    template <typename V>
+    class EdgeMap 
+      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, typename Parent::
-                             template EdgeMap<Value> > MapParent;
-
-      EdgeMap(const Adaptor& adaptor)
-        : MapParent(adaptor) {}
-
-      EdgeMap(const Adaptor& adaptor, const _Value& value)
-        : MapParent(adaptor, value) {}
+      typedef V Value;
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
+		  LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
+
+      EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
+        : Parent(adaptor) {}
+
+      EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
+        : Parent(adaptor, value) {}
 
     private:
@@ -1223,5 +1282,5 @@
       template <typename CMap>
       EdgeMap& operator=(const CMap& cmap) {
-        MapParent::operator=(cmap);
+        Parent::operator=(cmap);
         return *this;
       }
@@ -1232,35 +1291,56 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief A graph adaptor for hiding nodes and edges in an
-  /// undirected graph.
-  ///
-  /// SubGraph hides nodes and edges in a graph. A bool node map and a
-  /// bool edge map must be specified, which define the filters for
-  /// nodes and edges. Just the nodes and edges with true value are
-  /// shown in the subgraph. The SubGraph is conform to the \ref
-  /// concepts::Graph "Graph concept". If the \c _checked parameter is
-  /// true, then the edges incident to filtered nodes are also
-  /// filtered out.
-  ///
-  /// \tparam _Graph It must be conform to the \ref
-  /// concepts::Graph "Graph concept". The type can be specified
-  /// to const.
-  /// \tparam _NodeFilterMap A bool valued node map of the the adapted graph.
-  /// \tparam _EdgeFilterMap A bool valued edge map of the the adapted graph.
-  /// \tparam _checked If the parameter is false then the edge filtering
-  /// is not checked with respect to node filter. Otherwise, each edge
-  /// is automatically filtered, which is incident to a filtered node.
+  /// \brief Adaptor class for hiding nodes and edges in an undirected
+  /// graph.
+  ///
+  /// SubGraph can be used for hiding nodes and edges in a graph.
+  /// A \c bool node map and a \c bool edge map must be specified, which
+  /// define the filters for nodes and edges.
+  /// Only the nodes and edges with \c true filter value are
+  /// shown in the subgraph. The edges that are incident to hidden
+  /// nodes are also filtered out.
+  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
+  /// \tparam EF The type of the edge filter map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
+  /// adapted graph are convertible to each other.
   ///
   /// \see FilterNodes
   /// \see FilterEdges
-  template<typename _Graph, typename NodeFilterMap,
-           typename EdgeFilterMap, bool _checked = true>
-  class SubGraph
-    : public GraphAdaptorExtender<
-      SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap, _checked> > {
-  public:
-    typedef _Graph Graph;
-    typedef GraphAdaptorExtender<
-      SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
+#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;
@@ -1273,139 +1353,152 @@
     /// \brief Constructor
     ///
-    /// Creates a subgraph for the given graph with given node and
-    /// edge map filters.
-    SubGraph(Graph& _graph, NodeFilterMap& node_filter_map,
-             EdgeFilterMap& edge_filter_map) {
-      setGraph(_graph);
-      setNodeFilterMap(node_filter_map);
-      setEdgeFilterMap(edge_filter_map);
-    }
-
-    /// \brief Hides the node of the graph
-    ///
-    /// This function hides \c n in the graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c n
-    /// to be false in the corresponding node-map.
-    void hide(const Node& n) const { Parent::hide(n); }
-
-    /// \brief Hides the edge of the graph
-    ///
-    /// This function hides \c e in the graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c e
-    /// to be false in the corresponding edge-map.
-    void hide(const Edge& e) const { Parent::hide(e); }
-
-    /// \brief Unhides the node of the graph
-    ///
-    /// The value of \c n is set to be true in the node-map which stores
-    /// hide information. If \c n was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Node& n) const { Parent::unHide(n); }
-
-    /// \brief Unhides the edge of the graph
-    ///
-    /// The value of \c e is set to be true in the edge-map which stores
-    /// hide information. If \c e was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Edge& e) const { Parent::unHide(e); }
-
-    /// \brief Returns true if \c n is hidden.
-    ///
-    /// Returns true if \c n is hidden.
-    ///
-    bool hidden(const Node& n) const { return Parent::hidden(n); }
-
-    /// \brief Returns true if \c e is hidden.
-    ///
-    /// Returns true if \c e is hidden.
-    ///
-    bool hidden(const Edge& e) const { return Parent::hidden(e); }
+    /// Creates a subgraph for the given graph with the given node
+    /// and edge filter maps.
+    SubGraph(GR& graph, NF& node_filter, EF& edge_filter) {
+      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 Just gives back a subgraph
-  ///
-  /// Just gives back a subgraph
-  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
-  SubGraph<const Graph, NodeFilterMap, ArcFilterMap>
-  subGraph(const Graph& graph, NodeFilterMap& nfm, ArcFilterMap& efm) {
-    return SubGraph<const Graph, NodeFilterMap, ArcFilterMap>(graph, nfm, efm);
+  /// \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 Graph, typename NodeFilterMap, typename ArcFilterMap>
-  SubGraph<const Graph, const NodeFilterMap, ArcFilterMap>
-  subGraph(const Graph& graph,
-           const NodeFilterMap& nfm, ArcFilterMap& efm) {
-    return SubGraph<const Graph, const NodeFilterMap, ArcFilterMap>
-      (graph, nfm, efm);
+  template<typename 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 Graph, typename NodeFilterMap, typename ArcFilterMap>
-  SubGraph<const Graph, NodeFilterMap, const ArcFilterMap>
-  subGraph(const Graph& graph,
-           NodeFilterMap& nfm, const ArcFilterMap& efm) {
-    return SubGraph<const Graph, NodeFilterMap, const ArcFilterMap>
-      (graph, nfm, efm);
+  template<typename 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 Graph, typename NodeFilterMap, typename ArcFilterMap>
-  SubGraph<const Graph, const NodeFilterMap, const ArcFilterMap>
-  subGraph(const Graph& graph,
-           const NodeFilterMap& nfm, const ArcFilterMap& efm) {
-    return SubGraph<const Graph, const NodeFilterMap, const ArcFilterMap>
-      (graph, nfm, efm);
+  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 An adaptor for hiding nodes from a digraph or a graph.
-  ///
-  /// FilterNodes adaptor hides nodes in a graph or a digraph. A bool
-  /// node map must be specified, which defines the filters for
-  /// nodes. Just the unfiltered nodes and the arcs or edges incident
-  /// to unfiltered nodes are shown in the subdigraph or subgraph. The
-  /// FilterNodes is conform to the \ref concepts::Digraph
-  /// "Digraph concept" or \ref concepts::Graph "Graph concept" depending
-  /// on the \c _Digraph template parameter. If the \c _checked
-  /// parameter is true, then the arc or edges incident to filtered nodes
-  /// are also filtered out.
-  ///
-  /// \tparam _Digraph It must be conform to the \ref
-  /// concepts::Digraph "Digraph concept" or \ref concepts::Graph
-  /// "Graph concept". The type can be specified to be const.
-  /// \tparam _NodeFilterMap A bool valued node map of the the adapted graph.
-  /// \tparam _checked If the parameter is false then the arc or edge
-  /// filtering is not checked with respect to node filter. In this
-  /// case just isolated nodes can be filtered out from the
-  /// graph.
+  /// \brief Adaptor class for hiding nodes in a digraph or a graph.
+  ///
+  /// FilterNodes adaptor can be used for hiding nodes in a digraph or a
+  /// graph. A \c bool node map must be specified, which defines the filter
+  /// for the nodes. Only the nodes with \c true filter value and the
+  /// arcs/edges incident to nodes both with \c true filter value are shown
+  /// in the subgraph. This adaptor conforms to the \ref concepts::Digraph
+  /// "Digraph" concept or the \ref concepts::Graph "Graph" concept
+  /// depending on the \c GR template parameter.
+  ///
+  /// The adapted (di)graph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs/edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph or graph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept
+  /// or the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted (di)graph. The default type is
+  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
+  ///
+  /// \note The \c Node and <tt>Arc/Edge</tt> types of this adaptor and the
+  /// adapted (di)graph are convertible to each other.
 #ifdef DOXYGEN
-  template<typename _Digraph,
-           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
-           bool _checked = true>
+  template<typename GR, typename NF>
+  class FilterNodes {
 #else
-  template<typename _Digraph,
-           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
-           bool _checked = true,
+  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
-  class FilterNodes
-    : public SubDigraph<_Digraph, _NodeFilterMap,
-                        ConstMap<typename _Digraph::Arc, bool>, _checked> {
-  public:
-
-    typedef _Digraph Digraph;
-    typedef _NodeFilterMap NodeFilterMap;
-
-    typedef SubDigraph<Digraph, NodeFilterMap,
-                       ConstMap<typename Digraph::Arc, bool>, _checked>
-    Parent;
+  public:
+
+    typedef GR Digraph;
+    typedef NF NodeFilterMap;
+
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >, 
+                     true> > Parent;
 
     typedef typename Parent::Node Node;
 
   protected:
-    ConstMap<typename Digraph::Arc, bool> const_true_map;
-
-    FilterNodes() : const_true_map(true) {
-      Parent::setArcFilterMap(const_true_map);
-    }
+    ConstMap<typename Digraph::Arc, Const<bool, true> > const_true_map;
+
+    FilterNodes() : const_true_map() {}
 
   public:
@@ -1413,117 +1506,144 @@
     /// \brief Constructor
     ///
-    /// Creates an adaptor for the given digraph or graph with
+    /// Creates a subgraph for the given digraph or graph with the
     /// given node filter map.
-    FilterNodes(Digraph& _digraph, NodeFilterMap& node_filter) :
-      Parent(), const_true_map(true) {
-      Parent::setDigraph(_digraph);
-      Parent::setNodeFilterMap(node_filter);
-      Parent::setArcFilterMap(const_true_map);
-    }
-
-    /// \brief Hides the node of the graph
-    ///
-    /// This function hides \c n in the digraph or graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c n
-    /// to be false in the corresponding node map.
-    void hide(const Node& n) const { Parent::hide(n); }
-
-    /// \brief Unhides the node of the graph
-    ///
-    /// The value of \c n is set to be true in the node-map which stores
-    /// hide information. If \c n was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Node& n) const { Parent::unHide(n); }
-
-    /// \brief Returns true if \c n is hidden.
-    ///
-    /// Returns true if \c n is hidden.
-    ///
-    bool hidden(const Node& n) const { return Parent::hidden(n); }
+    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 _Graph, typename _NodeFilterMap, bool _checked>
-  class FilterNodes<_Graph, _NodeFilterMap, _checked,
-                    typename enable_if<UndirectedTagIndicator<_Graph> >::type>
-    : public SubGraph<_Graph, _NodeFilterMap,
-                      ConstMap<typename _Graph::Edge, bool>, _checked> {
-  public:
-    typedef _Graph Graph;
-    typedef _NodeFilterMap NodeFilterMap;
-    typedef SubGraph<Graph, NodeFilterMap,
-                     ConstMap<typename Graph::Edge, bool> > Parent;
+  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> > {
+
+  public:
+    typedef GR Graph;
+    typedef NF NodeFilterMap;
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
+                   true> > Parent;
 
     typedef typename Parent::Node Node;
   protected:
-    ConstMap<typename Graph::Edge, bool> const_true_map;
-
-    FilterNodes() : const_true_map(true) {
-      Parent::setEdgeFilterMap(const_true_map);
-    }
-
-  public:
-
-    FilterNodes(Graph& _graph, NodeFilterMap& node_filter_map) :
-      Parent(), const_true_map(true) {
-      Parent::setGraph(_graph);
-      Parent::setNodeFilterMap(node_filter_map);
-      Parent::setEdgeFilterMap(const_true_map);
-    }
-
-    void hide(const Node& n) const { Parent::hide(n); }
-    void unHide(const Node& n) const { Parent::unHide(n); }
-    bool hidden(const Node& n) const { return Parent::hidden(n); }
+    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 Just gives back a FilterNodes adaptor
-  ///
-  /// Just gives back a FilterNodes adaptor
-  template<typename Digraph, typename NodeFilterMap>
-  FilterNodes<const Digraph, NodeFilterMap>
-  filterNodes(const Digraph& digraph, NodeFilterMap& nfm) {
-    return FilterNodes<const Digraph, NodeFilterMap>(digraph, nfm);
+  /// \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 Digraph, typename NodeFilterMap>
-  FilterNodes<const Digraph, const NodeFilterMap>
-  filterNodes(const Digraph& digraph, const NodeFilterMap& nfm) {
-    return FilterNodes<const Digraph, const NodeFilterMap>(digraph, nfm);
+  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 An adaptor for hiding arcs from a digraph.
-  ///
-  /// FilterArcs adaptor hides arcs in a digraph. A bool arc map must
-  /// be specified, which defines the filters for arcs. Just the
-  /// unfiltered arcs are shown in the subdigraph. The FilterArcs is
-  /// conform to the \ref concepts::Digraph "Digraph concept".
-  ///
-  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
-  /// "Digraph concept". The type can be specified to be const.
-  /// \tparam _ArcFilterMap A bool valued arc map of the the adapted
-  /// graph.
-  template<typename _Digraph, typename _ArcFilterMap>
+  /// \brief Adaptor class for hiding arcs in a digraph.
+  ///
+  /// FilterArcs adaptor can be used for hiding arcs in a digraph.
+  /// A \c bool arc map must be specified, which defines the filter for
+  /// the arcs. Only the arcs with \c true filter value are shown in the
+  /// subdigraph. This adaptor conforms to the \ref concepts::Digraph
+  /// "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam 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 SubDigraph<_Digraph, ConstMap<typename _Digraph::Node, bool>,
-                      _ArcFilterMap, false> {
-  public:
-    typedef _Digraph Digraph;
-    typedef _ArcFilterMap ArcFilterMap;
-
-    typedef SubDigraph<Digraph, ConstMap<typename Digraph::Node, bool>,
-                       ArcFilterMap, false> Parent;
+    public DigraphAdaptorExtender<
+      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
+                     AF, false> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef DGR Digraph;
+    /// The type of the arc filter map.
+    typedef AF ArcFilterMap;
+
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >, 
+                     AF, false> > Parent;
 
     typedef typename Parent::Arc Arc;
 
   protected:
-    ConstMap<typename Digraph::Node, bool> const_true_map;
-
-    FilterArcs() : const_true_map(true) {
-      Parent::setNodeFilterMap(const_true_map);
-    }
+    ConstMap<typename DGR::Node, Const<bool, true> > const_true_map;
+
+    FilterArcs() : const_true_map() {}
 
   public:
@@ -1531,75 +1651,106 @@
     /// \brief Constructor
     ///
-    /// Creates a FilterArcs adaptor for the given graph with
-    /// given arc map filter.
-    FilterArcs(Digraph& digraph, ArcFilterMap& arc_filter)
-      : Parent(), const_true_map(true) {
-      Parent::setDigraph(digraph);
-      Parent::setNodeFilterMap(const_true_map);
-      Parent::setArcFilterMap(arc_filter);
-    }
-
-    /// \brief Hides the arc of the graph
-    ///
-    /// This function hides \c a in the graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c a
-    /// to be false in the corresponding arc map.
-    void hide(const Arc& a) const { Parent::hide(a); }
-
-    /// \brief Unhides the arc of the graph
-    ///
-    /// The value of \c a is set to be true in the arc-map which stores
-    /// hide information. If \c a was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Arc& a) const { Parent::unHide(a); }
-
-    /// \brief Returns true if \c a is hidden.
-    ///
-    /// Returns true if \c a is hidden.
-    ///
-    bool hidden(const Arc& a) const { return Parent::hidden(a); }
+    /// 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 Just gives back an FilterArcs adaptor
-  ///
-  /// Just gives back an FilterArcs adaptor
-  template<typename Digraph, typename ArcFilterMap>
-  FilterArcs<const Digraph, ArcFilterMap>
-  filterArcs(const Digraph& digraph, ArcFilterMap& afm) {
-    return FilterArcs<const Digraph, ArcFilterMap>(digraph, afm);
+  /// \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 Digraph, typename ArcFilterMap>
-  FilterArcs<const Digraph, const ArcFilterMap>
-  filterArcs(const Digraph& digraph, const ArcFilterMap& afm) {
-    return FilterArcs<const Digraph, const ArcFilterMap>(digraph, afm);
+  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 An adaptor for hiding edges from a graph.
-  ///
-  /// FilterEdges adaptor hides edges in a digraph. A bool edge map must
-  /// be specified, which defines the filters for edges. Just the
-  /// unfiltered edges are shown in the subdigraph. The FilterEdges is
-  /// conform to the \ref concepts::Graph "Graph concept".
-  ///
-  /// \tparam _Graph It must be conform to the \ref concepts::Graph
-  /// "Graph concept". The type can be specified to be const.
-  /// \tparam _EdgeFilterMap A bool valued edge map of the the adapted
-  /// graph.
-  template<typename _Graph, typename _EdgeFilterMap>
+  /// \brief Adaptor class for hiding edges in a graph.
+  ///
+  /// FilterEdges adaptor can be used for hiding edges in a graph.
+  /// A \c bool edge map must be specified, which defines the filter for
+  /// the edges. Only the edges with \c true filter value are shown in the
+  /// subgraph. This adaptor conforms to the \ref concepts::Graph
+  /// "Graph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam EF The type of the edge filter map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
+  /// adapted graph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename EF>
+  class FilterEdges {
+#else
+  template<typename GR,
+           typename EF = typename GR::template EdgeMap<bool> >
   class FilterEdges :
-    public SubGraph<_Graph, ConstMap<typename _Graph::Node,bool>,
-                    _EdgeFilterMap, false> {
-  public:
-    typedef _Graph Graph;
-    typedef _EdgeFilterMap EdgeFilterMap;
-    typedef SubGraph<Graph, ConstMap<typename Graph::Node,bool>,
-                     EdgeFilterMap, false> Parent;
+    public GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >, 
+                   EF, false> > {
+#endif
+  public:
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the edge filter map.
+    typedef EF EdgeFilterMap;
+
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >, 
+                   EF, false> > Parent;
+
     typedef typename Parent::Edge Edge;
+
   protected:
-    ConstMap<typename Graph::Node, bool> const_true_map;
+    ConstMap<typename GR::Node, Const<bool, true> > const_true_map;
 
     FilterEdges() : const_true_map(true) {
@@ -1611,54 +1762,61 @@
     /// \brief Constructor
     ///
-    /// Creates a FilterEdges adaptor for the given graph with
-    /// given edge map filters.
-    FilterEdges(Graph& _graph, EdgeFilterMap& edge_filter_map) :
-      Parent(), const_true_map(true) {
-      Parent::setGraph(_graph);
-      Parent::setNodeFilterMap(const_true_map);
-      Parent::setEdgeFilterMap(edge_filter_map);
-    }
-
-    /// \brief Hides the edge of the graph
-    ///
-    /// This function hides \c e in the graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c e
-    /// to be false in the corresponding edge-map.
-    void hide(const Edge& e) const { Parent::hide(e); }
-
-    /// \brief Unhides the edge of the graph
-    ///
-    /// The value of \c e is set to be true in the edge-map which stores
-    /// hide information. If \c e was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Edge& e) const { Parent::unHide(e); }
-
-    /// \brief Returns true if \c e is hidden.
-    ///
-    /// Returns true if \c e is hidden.
-    ///
-    bool hidden(const Edge& e) const { return Parent::hidden(e); }
+    /// 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 Just gives back a FilterEdges adaptor
-  ///
-  /// Just gives back a FilterEdges adaptor
-  template<typename Graph, typename EdgeFilterMap>
-  FilterEdges<const Graph, EdgeFilterMap>
-  filterEdges(const Graph& graph, EdgeFilterMap& efm) {
-    return FilterEdges<const Graph, EdgeFilterMap>(graph, efm);
+  /// \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 Graph, typename EdgeFilterMap>
-  FilterEdges<const Graph, const EdgeFilterMap>
-  filterEdges(const Graph& graph, const EdgeFilterMap& efm) {
-    return FilterEdges<const Graph, const EdgeFilterMap>(graph, efm);
+  template<typename 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 _Digraph>
+
+  template <typename DGR>
   class UndirectorBase {
   public:
-    typedef _Digraph Digraph;
+    typedef DGR Digraph;
     typedef UndirectorBase Adaptor;
 
@@ -1695,6 +1853,4 @@
       }
     };
-
-
 
     void first(Node& n) const {
@@ -1846,10 +2002,13 @@
 
     typedef NodeNumTagIndicator<Digraph> NodeNumTag;
-    int nodeNum() const { return 2 * _digraph->arcNum(); }
-    typedef EdgeNumTagIndicator<Digraph> EdgeNumTag;
+    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 FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
     Arc findArc(Node s, Node t, Arc p = INVALID) const {
       if (p == INVALID) {
@@ -1870,4 +2029,5 @@
     }
 
+    typedef FindArcTag FindEdgeTag;
     Edge findEdge(Node s, Node t, Edge p = INVALID) const {
       if (s != t) {
@@ -1877,5 +2037,5 @@
           arc = _digraph->findArc(t, s);
           if (arc != INVALID) return arc;
-        } else if (_digraph->s(p) == s) {
+        } else if (_digraph->source(p) == s) {
           Edge arc = _digraph->findArc(s, t, p);
           if (arc != INVALID) return arc;
@@ -1894,9 +2054,9 @@
   private:
 
-    template <typename _Value>
+    template <typename V>
     class ArcMapBase {
     private:
 
-      typedef typename Digraph::template ArcMap<_Value> MapImpl;
+      typedef typename DGR::template ArcMap<V> MapImpl;
 
     public:
@@ -1904,23 +2064,27 @@
       typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
 
-      typedef _Value Value;
+      typedef V Value;
       typedef Arc Key;
-
-      ArcMapBase(const Adaptor& adaptor) :
+      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 Adaptor& adaptor, const Value& v)
-        : _forward(*adaptor._digraph, v), _backward(*adaptor._digraph, v) {}
-
-      void set(const Arc& a, const Value& v) {
+      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, v);
+          _forward.set(a, value);
         } else {
-          _backward.set(a, v);
+          _backward.set(a, value);
         }
       }
 
-      typename MapTraits<MapImpl>::ConstReturnValue
-      operator[](const Arc& a) const {
+      ConstReturnValue operator[](const Arc& a) const {
         if (direction(a)) {
           return _forward[a];
@@ -1930,6 +2094,5 @@
       }
 
-      typename MapTraits<MapImpl>::ReturnValue
-      operator[](const Arc& a) {
+      ReturnValue operator[](const Arc& a) {
         if (direction(a)) {
           return _forward[a];
@@ -1947,15 +2110,15 @@
   public:
 
-    template <typename _Value>
-    class NodeMap : public Digraph::template NodeMap<_Value> {
+    template <typename V>
+    class NodeMap : public DGR::template NodeMap<V> {
     public:
 
-      typedef _Value Value;
-      typedef typename Digraph::template NodeMap<Value> Parent;
-
-      explicit NodeMap(const Adaptor& adaptor)
+      typedef V Value;
+      typedef typename DGR::template NodeMap<Value> Parent;
+
+      explicit NodeMap(const UndirectorBase<DGR>& adaptor)
         : Parent(*adaptor._digraph) {}
 
-      NodeMap(const Adaptor& adaptor, const _Value& value)
+      NodeMap(const UndirectorBase<DGR>& adaptor, const V& value)
         : Parent(*adaptor._digraph, value) { }
 
@@ -1973,16 +2136,16 @@
     };
 
-    template <typename _Value>
+    template <typename V>
     class ArcMap
-      : public SubMapExtender<Adaptor, ArcMapBase<_Value> >
+      : public SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> >
     {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, ArcMapBase<Value> > Parent;
-
-      ArcMap(const Adaptor& adaptor)
+      typedef V Value;
+      typedef SubMapExtender<Adaptor, ArcMapBase<V> > Parent;
+
+      explicit ArcMap(const UndirectorBase<DGR>& adaptor)
         : Parent(adaptor) {}
 
-      ArcMap(const Adaptor& adaptor, const Value& value)
+      ArcMap(const UndirectorBase<DGR>& adaptor, const V& value)
         : Parent(adaptor, value) {}
 
@@ -1999,15 +2162,15 @@
     };
 
-    template <typename _Value>
-    class EdgeMap : public Digraph::template ArcMap<_Value> {
+    template <typename V>
+    class EdgeMap : public Digraph::template ArcMap<V> {
     public:
 
-      typedef _Value Value;
-      typedef typename Digraph::template ArcMap<Value> Parent;
-
-      explicit EdgeMap(const Adaptor& adaptor)
+      typedef V Value;
+      typedef typename Digraph::template ArcMap<V> Parent;
+
+      explicit EdgeMap(const UndirectorBase<DGR>& adaptor)
         : Parent(*adaptor._digraph) {}
 
-      EdgeMap(const Adaptor& adaptor, const Value& value)
+      EdgeMap(const UndirectorBase<DGR>& adaptor, const V& value)
         : Parent(*adaptor._digraph, value) {}
 
@@ -2025,14 +2188,17 @@
     };
 
-    typedef typename ItemSetTraits<Digraph, Node>::ItemNotifier NodeNotifier;
+    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()); }
+
   protected:
 
     UndirectorBase() : _digraph(0) {}
 
-    Digraph* _digraph;
-
-    void setDigraph(Digraph& digraph) {
+    DGR* _digraph;
+
+    void initialize(DGR& digraph) {
       _digraph = &digraph;
     }
@@ -2042,20 +2208,36 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief Undirect the graph
-  ///
-  /// This adaptor makes an undirected graph from a directed
-  /// graph. All arcs of the underlying digraph will be showed in the
-  /// adaptor as an edge. The Orienter adaptor is conform to the \ref
-  /// concepts::Graph "Graph concept".
-  ///
-  /// \tparam _Digraph It must be conform to the \ref
-  /// concepts::Digraph "Digraph concept". The type can be specified
-  /// to const.
-  template<typename _Digraph>
-  class Undirector
-    : public GraphAdaptorExtender<UndirectorBase<_Digraph> > {
-  public:
-    typedef _Digraph Digraph;
-    typedef GraphAdaptorExtender<UndirectorBase<Digraph> > Parent;
+  /// \brief Adaptor class for viewing a digraph as an undirected graph.
+  ///
+  /// Undirector adaptor can be used for viewing a digraph as an undirected
+  /// graph. All arcs of the underlying digraph are showed in the
+  /// adaptor as an edge (and also as a pair of arcs, of course).
+  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam 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
+  public:
+    /// The type of the adapted digraph.
+    typedef DGR Digraph;
+    typedef GraphAdaptorExtender<UndirectorBase<DGR> > Parent;
   protected:
     Undirector() { }
@@ -2064,35 +2246,36 @@
     /// \brief Constructor
     ///
-    /// Creates a undirected graph from the given digraph
-    Undirector(_Digraph& digraph) {
-      setDigraph(digraph);
-    }
-
-    /// \brief ArcMap combined from two original ArcMap
-    ///
-    /// This class adapts two original digraph ArcMap to
-    /// get an arc map on the undirected graph.
-    template <typename _ForwardMap, typename _BackwardMap>
+    /// Creates an undirected graph from the given digraph.
+    Undirector(DGR& digraph) {
+      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 %ForwardMap).
+    template <typename ForwardMap, typename BackwardMap>
     class CombinedArcMap {
     public:
 
-      typedef _ForwardMap ForwardMap;
-      typedef _BackwardMap BackwardMap;
+      /// The key type of the map
+      typedef typename Parent::Arc Key;
+      /// The value type of the map
+      typedef typename ForwardMap::Value Value;
 
       typedef typename MapTraits<ForwardMap>::ReferenceMapTag ReferenceMapTag;
 
-      typedef typename ForwardMap::Value Value;
-      typedef typename Parent::Arc Key;
-
-      /// \brief Constructor
-      ///
+      typedef typename MapTraits<ForwardMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ForwardMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ForwardMap>::ReturnValue Reference;
+      typedef typename MapTraits<ForwardMap>::ConstReturnValue ConstReference;
+
       /// Constructor
       CombinedArcMap(ForwardMap& forward, BackwardMap& backward)
         : _forward(&forward), _backward(&backward) {}
 
-
-      /// \brief Sets the value associated with a key.
-      ///
-      /// Sets the value associated with a key.
+      /// Sets the value associated with the given key.
       void set(const Key& e, const Value& a) {
         if (Parent::direction(e)) {
@@ -2103,9 +2286,6 @@
       }
 
-      /// \brief Returns the value associated with a key.
-      ///
-      /// Returns the value associated with a key.
-      typename MapTraits<ForwardMap>::ConstReturnValue
-      operator[](const Key& e) const {
+      /// Returns the value associated with the given key.
+      ConstReturnValue operator[](const Key& e) const {
         if (Parent::direction(e)) {
           return (*_forward)[e];
@@ -2115,9 +2295,6 @@
       }
 
-      /// \brief Returns the value associated with a key.
-      ///
-      /// Returns the value associated with a key.
-      typename MapTraits<ForwardMap>::ReturnValue
-      operator[](const Key& e) {
+      /// Returns a reference to the value associated with the given key.
+      ReturnValue operator[](const Key& e) {
         if (Parent::direction(e)) {
           return (*_forward)[e];
@@ -2134,7 +2311,7 @@
     };
 
-    /// \brief Just gives back a combined arc map
-    ///
-    /// Just gives back a combined arc map
+    /// \brief Returns a combined arc map
+    ///
+    /// This function just returns a combined arc map.
     template <typename ForwardMap, typename BackwardMap>
     static CombinedArcMap<ForwardMap, BackwardMap>
@@ -2166,22 +2343,24 @@
   };
 
-  /// \brief Just gives back an undirected view of the given digraph
-  ///
-  /// Just gives back an undirected view of the given digraph
-  template<typename Digraph>
-  Undirector<const Digraph>
-  undirector(const Digraph& digraph) {
-    return Undirector<const Digraph>(digraph);
+  /// \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 _Graph, typename _DirectionMap>
+
+  template <typename GR, typename DM>
   class OrienterBase {
   public:
 
-    typedef _Graph Graph;
-    typedef _DirectionMap DirectionMap;
-
-    typedef typename Graph::Node Node;
-    typedef typename Graph::Edge Arc;
+    typedef GR Graph;
+    typedef DM DirectionMap;
+
+    typedef typename GR::Node Node;
+    typedef typename GR::Edge Arc;
 
     void reverseArc(const Arc& arc) {
@@ -2192,10 +2371,10 @@
     void first(Arc& i) const { _graph->first(i); }
     void firstIn(Arc& i, const Node& n) const {
-      bool d;
+      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;
+      bool d = true;
       _graph->firstInc(i, d, n);
       while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
@@ -2225,22 +2404,13 @@
     int nodeNum() const { return _graph->nodeNum(); }
 
-    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
+    typedef EdgeNumTagIndicator<Graph> ArcNumTag;
     int arcNum() const { return _graph->edgeNum(); }
 
-    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    typedef FindEdgeTagIndicator<Graph> FindArcTag;
     Arc findArc(const Node& u, const Node& v,
-                const Arc& prev = INVALID) {
-      Arc arc = prev;
-      bool d = arc == INVALID ? true : (*_direction)[arc];
-      if (d) {
+                const Arc& prev = INVALID) const {
+      Arc arc = _graph->findEdge(u, v, prev);
+      while (arc != INVALID && source(arc) != u) {
         arc = _graph->findEdge(u, v, arc);
-        while (arc != INVALID && !(*_direction)[arc]) {
-          _graph->findEdge(u, v, arc);
-        }
-        if (arc != INVALID) return arc;
-      }
-      _graph->findEdge(v, u, arc);
-      while (arc != INVALID && (*_direction)[arc]) {
-        _graph->findEdge(u, v, arc);
       }
       return arc;
@@ -2252,6 +2422,6 @@
 
     Arc addArc(const Node& u, const Node& v) {
-      Arc arc = _graph->addArc(u, v);
-      _direction->set(arc, _graph->source(arc) == u);
+      Arc arc = _graph->addEdge(u, v);
+      _direction->set(arc, _graph->u(arc) == u);
       return arc;
     }
@@ -2271,20 +2441,20 @@
     int maxArcId() const { return _graph->maxEdgeId(); }
 
-    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
+    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
     NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
 
-    typedef typename ItemSetTraits<Graph, Arc>::ItemNotifier ArcNotifier;
+    typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
     ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
 
-    template <typename _Value>
-    class NodeMap : public _Graph::template NodeMap<_Value> {
+    template <typename V>
+    class NodeMap : public GR::template NodeMap<V> {
     public:
 
-      typedef typename _Graph::template NodeMap<_Value> Parent;
-
-      explicit NodeMap(const OrienterBase& adapter)
+      typedef typename GR::template NodeMap<V> Parent;
+
+      explicit NodeMap(const OrienterBase<GR, DM>& adapter)
         : Parent(*adapter._graph) {}
 
-      NodeMap(const OrienterBase& adapter, const _Value& value)
+      NodeMap(const OrienterBase<GR, DM>& adapter, const V& value)
         : Parent(*adapter._graph, value) {}
 
@@ -2302,14 +2472,14 @@
     };
 
-    template <typename _Value>
-    class ArcMap : public _Graph::template EdgeMap<_Value> {
+    template <typename V>
+    class ArcMap : public GR::template EdgeMap<V> {
     public:
 
-      typedef typename Graph::template EdgeMap<_Value> Parent;
-
-      explicit ArcMap(const OrienterBase& adapter)
+      typedef typename Graph::template EdgeMap<V> Parent;
+
+      explicit ArcMap(const OrienterBase<GR, DM>& adapter)
         : Parent(*adapter._graph) { }
 
-      ArcMap(const OrienterBase& adapter, const _Value& value)
+      ArcMap(const OrienterBase<GR, DM>& adapter, const V& value)
         : Parent(*adapter._graph, value) { }
 
@@ -2330,40 +2500,58 @@
   protected:
     Graph* _graph;
-    DirectionMap* _direction;
-
-    void setDirectionMap(DirectionMap& direction) {
+    DM* _direction;
+
+    void initialize(GR& graph, DM& direction) {
+      _graph = &graph;
       _direction = &direction;
     }
 
-    void setGraph(Graph& graph) {
-      _graph = &graph;
-    }
-
   };
 
   /// \ingroup graph_adaptors
   ///
-  /// \brief Orients the edges of the graph to get a digraph
-  ///
-  /// This adaptor orients each edge in the undirected graph. The
-  /// direction of the arcs stored in an edge node map.  The arcs can
-  /// be easily reverted by the \c reverseArc() member function in the
-  /// adaptor. The Orienter adaptor is conform to the \ref
-  /// concepts::Digraph "Digraph concept".
-  ///
-  /// \tparam _Graph It must be conform to the \ref concepts::Graph
-  /// "Graph concept". The type can be specified to be const.
-  /// \tparam _DirectionMap A bool valued edge map of the the adapted
-  /// graph.
-  ///
-  /// \sa orienter
-  template<typename _Graph,
-           typename DirectionMap = typename _Graph::template EdgeMap<bool> >
+  /// \brief Adaptor class for orienting the edges of a graph to get a digraph
+  ///
+  /// Orienter adaptor can be used for orienting the edges of a graph to
+  /// get a digraph. A \c bool edge map of the underlying graph must be
+  /// specified, which define the direction of the arcs in the adaptor.
+  /// The arcs can be easily reversed by the \c reverseArc() member function
+  /// of the adaptor.
+  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam DM The type of the direction map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node type of this adaptor and the adapted graph are
+  /// convertible to each other, moreover the \c Arc type of the adaptor
+  /// and the \c Edge type of the adapted graph are also convertible to
+  /// each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename DM>
+  class Orienter {
+#else
+  template<typename GR,
+           typename DM = typename GR::template EdgeMap<bool> >
   class Orienter :
-    public DigraphAdaptorExtender<OrienterBase<_Graph, DirectionMap> > {
-  public:
-    typedef _Graph Graph;
-    typedef DigraphAdaptorExtender<
-      OrienterBase<_Graph, DirectionMap> > Parent;
+    public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
+#endif
+  public:
+
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the direction edge map.
+    typedef DM DirectionMap;
+
+    typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
     typedef typename Parent::Arc Arc;
   protected:
@@ -2371,15 +2559,16 @@
   public:
 
-    /// \brief Constructor of the adaptor
-    ///
-    /// Constructor of the adaptor
-    Orienter(Graph& graph, DirectionMap& direction) {
-      setGraph(graph);
-      setDirectionMap(direction);
-    }
-
-    /// \brief Reverse arc
-    ///
-    /// It reverse the given arc. It simply negate the direction in the map.
+    /// \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);
@@ -2387,80 +2576,67 @@
   };
 
-  /// \brief Just gives back a Orienter
-  ///
-  /// Just gives back a Orienter
-  template<typename Graph, typename DirectionMap>
-  Orienter<const Graph, DirectionMap>
-  orienter(const Graph& graph, DirectionMap& dm) {
-    return Orienter<const Graph, DirectionMap>(graph, dm);
+  /// \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 Graph, typename DirectionMap>
-  Orienter<const Graph, const DirectionMap>
-  orienter(const Graph& graph, const DirectionMap& dm) {
-    return Orienter<const Graph, const DirectionMap>(graph, dm);
+  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 _Digraph,
-             typename _CapacityMap = typename _Digraph::template ArcMap<int>,
-             typename _FlowMap = _CapacityMap,
-             typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
+    template <typename DGR, typename CM, typename FM, typename TL>
     class ResForwardFilter {
     public:
 
-      typedef _Digraph Digraph;
-      typedef _CapacityMap CapacityMap;
-      typedef _FlowMap FlowMap;
-      typedef _Tolerance Tolerance;
-
-      typedef typename Digraph::Arc Key;
+      typedef typename DGR::Arc Key;
       typedef bool Value;
 
     private:
 
-      const CapacityMap* _capacity;
-      const FlowMap* _flow;
-      Tolerance _tolerance;
+      const CM* _capacity;
+      const FM* _flow;
+      TL _tolerance;
+
     public:
 
-      ResForwardFilter(const CapacityMap& capacity, const FlowMap& flow,
-                       const Tolerance& tolerance = Tolerance())
+      ResForwardFilter(const CM& capacity, const FM& flow,
+                       const TL& tolerance = TL())
         : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
 
-      bool operator[](const typename Digraph::Arc& a) const {
+      bool operator[](const typename DGR::Arc& a) const {
         return _tolerance.positive((*_capacity)[a] - (*_flow)[a]);
       }
     };
 
-    template<typename _Digraph,
-             typename _CapacityMap = typename _Digraph::template ArcMap<int>,
-             typename _FlowMap = _CapacityMap,
-             typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
+    template<typename DGR,typename CM, typename FM, typename TL>
     class ResBackwardFilter {
     public:
 
-      typedef _Digraph Digraph;
-      typedef _CapacityMap CapacityMap;
-      typedef _FlowMap FlowMap;
-      typedef _Tolerance Tolerance;
-
-      typedef typename Digraph::Arc Key;
+      typedef typename DGR::Arc Key;
       typedef bool Value;
 
     private:
 
-      const CapacityMap* _capacity;
-      const FlowMap* _flow;
-      Tolerance _tolerance;
+      const CM* _capacity;
+      const FM* _flow;
+      TL _tolerance;
 
     public:
 
-      ResBackwardFilter(const CapacityMap& capacity, const FlowMap& flow,
-                        const Tolerance& tolerance = Tolerance())
+      ResBackwardFilter(const CM& capacity, const FM& flow,
+                        const TL& tolerance = TL())
         : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
 
-      bool operator[](const typename Digraph::Arc& a) const {
+      bool operator[](const typename DGR::Arc& a) const {
         return _tolerance.positive((*_flow)[a]);
       }
@@ -2471,51 +2647,73 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief An adaptor for composing the residual graph for directed
+  /// \brief Adaptor class for composing the residual digraph for directed
   /// flow and circulation problems.
   ///
-  /// An adaptor for composing the residual graph for directed flow and
-  /// circulation problems.  Let \f$ G=(V, A) \f$ be a directed graph
-  /// and let \f$ F \f$ be a number type. Let moreover \f$ f,c:A\to F \f$,
-  /// be functions on the arc-set.
-  ///
-  /// Then Residual implements the digraph structure with
-  /// node-set \f$ V \f$ and arc-set \f$ A_{forward}\cup A_{backward} \f$,
-  /// where \f$ A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\} \f$ and
-  /// \f$ A_{backward}=\{vu : uv\in A, f(uv)>0\} \f$, i.e. the so
-  /// called residual graph.  When we take the union
-  /// \f$ A_{forward}\cup A_{backward} \f$, multiplicities are counted,
-  /// i.e.  if an arc is in both \f$ A_{forward} \f$ and
-  /// \f$ A_{backward} \f$, then in the adaptor it appears in both
-  /// orientation.
-  ///
-  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
-  /// "Digraph concept". The type is implicitly const.
-  /// \tparam _CapacityMap An arc map of some numeric type, it defines
-  /// the capacities in the flow problem. The map is implicitly const.
-  /// \tparam _FlowMap An arc map of some numeric type, it defines
-  /// the capacities in the flow problem.
-  /// \tparam _Tolerance Handler for inexact computation.
-  template<typename _Digraph,
-           typename _CapacityMap = typename _Digraph::template ArcMap<int>,
-           typename _FlowMap = _CapacityMap,
-           typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
-  class Residual :
-    public FilterArcs<
-    Undirector<const _Digraph>,
-    typename Undirector<const _Digraph>::template CombinedArcMap<
-      _adaptor_bits::ResForwardFilter<const _Digraph, _CapacityMap,
-                                      _FlowMap, _Tolerance>,
-      _adaptor_bits::ResBackwardFilter<const _Digraph, _CapacityMap,
-                                       _FlowMap, _Tolerance> > >
+  /// 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.
+  ///
+  /// \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:
 
-    typedef _Digraph Digraph;
-    typedef _CapacityMap CapacityMap;
-    typedef _FlowMap FlowMap;
-    typedef _Tolerance Tolerance;
+    /// 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 Residual Adaptor;
+    typedef ResidualDigraph Adaptor;
 
   protected:
@@ -2523,14 +2721,16 @@
     typedef Undirector<const Digraph> Undirected;
 
-    typedef _adaptor_bits::ResForwardFilter<const Digraph, CapacityMap,
-                                            FlowMap, Tolerance> ForwardFilter;
-
-    typedef _adaptor_bits::ResBackwardFilter<const Digraph, CapacityMap,
-                                             FlowMap, Tolerance> BackwardFilter;
+    typedef 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 FilterArcs<Undirected, ArcFilter> Parent;
+      template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
+
+    typedef SubDigraph<Undirected, NodeFilter, ArcFilter> Parent;
 
     const CapacityMap* _capacity;
@@ -2538,4 +2738,5 @@
 
     Undirected _graph;
+    NodeFilter _node_filter;
     ForwardFilter _forward_filter;
     BackwardFilter _backward_filter;
@@ -2544,24 +2745,24 @@
   public:
 
-    /// \brief Constructor of the residual digraph.
-    ///
-    /// Constructor of the residual graph. The parameters are the digraph,
-    /// the flow map, the capacity map and a tolerance object.
-    Residual(const Digraph& digraph, const CapacityMap& capacity,
-             FlowMap& flow, const Tolerance& tolerance = Tolerance())
-      : Parent(), _capacity(&capacity), _flow(&flow), _graph(digraph),
+    /// \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::setDigraph(_graph);
-      Parent::setArcFilterMap(_arc_filter);
+      Parent::initialize(_graph, _node_filter, _arc_filter);
     }
 
     typedef typename Parent::Arc Arc;
 
-    /// \brief Gives back the residual capacity of the arc.
-    ///
-    /// Gives back the residual capacity of the 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)) {
@@ -2572,9 +2773,9 @@
     }
 
-    /// \brief Augment on the given arc in the residual graph.
-    ///
-    /// Augment on the given arc in the residual graph. It increase
-    /// or decrease the flow on the original arc depend on the direction
-    /// of the residual arc.
+    /// \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)) {
@@ -2585,28 +2786,32 @@
     }
 
-    /// \brief Returns the direction of the arc.
-    ///
-    /// Returns true when the arc is same oriented as the original arc.
+    /// \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 the direction of the arc.
-    ///
-    /// Returns true when the arc is opposite oriented as the original arc.
+    /// \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 Gives back the forward oriented residual arc.
-    ///
-    /// Gives back the forward oriented residual arc.
+    /// \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 Gives back the backward oriented residual arc.
-    ///
-    /// Gives back the backward oriented residual arc.
+    /// \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);
@@ -2615,19 +2820,21 @@
     /// \brief Residual capacity map.
     ///
-    /// In generic residual graph the residual capacity can be obtained
-    /// as a 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
+      /// The key type of the map
       typedef Arc Key;
-      /// The Value type
-      typedef typename _CapacityMap::Value Value;
+      /// The value type of the map
+      typedef typename CapacityMap::Value Value;
 
       /// Constructor
-      ResidualCapacity(const Adaptor& adaptor) : _adaptor(&adaptor) {}
-
-      /// \e
+      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);
@@ -2636,16 +2843,35 @@
     };
 
+    /// \brief Returns a residual capacity map
+    ///
+    /// This function just returns a residual capacity map.
+    ResidualCapacity residualCapacity() const {
+      return ResidualCapacity(*this);
+    }
+
   };
 
-  template <typename _Digraph>
+  /// \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 {
   public:
 
-    typedef _Digraph Digraph;
-    typedef DigraphAdaptorBase<const _Digraph> Parent;
+    typedef DGR Digraph;
+    typedef DigraphAdaptorBase<const DGR> Parent;
     typedef SplitNodesBase Adaptor;
 
-    typedef typename Digraph::Node DigraphNode;
-    typedef typename Digraph::Arc DigraphArc;
+    typedef typename DGR::Node DigraphNode;
+    typedef typename DGR::Arc DigraphArc;
 
     class Node;
@@ -2885,28 +3111,24 @@
 
     typedef True NodeNumTag;
-
     int nodeNum() const {
       return  2 * countNodes(*_digraph);
     }
 
-    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
     int arcNum() const {
       return countArcs(*_digraph) + countNodes(*_digraph);
     }
 
-    typedef True FindEdgeTag;
+    typedef True FindArcTag;
     Arc findArc(const Node& u, const Node& v,
                 const Arc& prev = INVALID) const {
-      if (inNode(u)) {
-        if (outNode(v)) {
-          if (static_cast<const DigraphNode&>(u) ==
-              static_cast<const DigraphNode&>(v) && prev == INVALID) {
-            return Arc(u);
-          }
+      if (inNode(u) && outNode(v)) {
+        if (static_cast<const DigraphNode&>(u) ==
+            static_cast<const DigraphNode&>(v) && prev == INVALID) {
+          return Arc(u);
         }
-      } else {
-        if (inNode(v)) {
-          return Arc(::lemon::findArc(*_digraph, u, v, prev));
-        }
+      }
+      else if (outNode(u) && inNode(v)) {
+        return Arc(::lemon::findArc(*_digraph, u, v, prev));
       }
       return INVALID;
@@ -2915,31 +3137,34 @@
   private:
 
-    template <typename _Value>
+    template <typename V>
     class NodeMapBase
-      : public MapTraits<typename Parent::template NodeMap<_Value> > {
-      typedef typename Parent::template NodeMap<_Value> NodeImpl;
+      : public MapTraits<typename Parent::template NodeMap<V> > {
+      typedef typename Parent::template NodeMap<V> NodeImpl;
     public:
       typedef Node Key;
-      typedef _Value Value;
-
-      NodeMapBase(const Adaptor& adaptor)
+      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 Adaptor& adaptor, const Value& value)
+      NodeMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
         : _in_map(*adaptor._digraph, value),
           _out_map(*adaptor._digraph, value) {}
 
-      void set(const Node& key, const Value& val) {
-        if (Adaptor::inNode(key)) { _in_map.set(key, val); }
+      void set(const Node& key, const V& val) {
+        if (SplitNodesBase<DGR>::inNode(key)) { _in_map.set(key, val); }
         else {_out_map.set(key, val); }
       }
 
-      typename MapTraits<NodeImpl>::ReturnValue
-      operator[](const Node& key) {
-        if (Adaptor::inNode(key)) { return _in_map[key]; }
+      ReturnValue operator[](const Node& key) {
+        if (SplitNodesBase<DGR>::inNode(key)) { return _in_map[key]; }
         else { return _out_map[key]; }
       }
 
-      typename MapTraits<NodeImpl>::ConstReturnValue
-      operator[](const Node& key) const {
+      ConstReturnValue operator[](const Node& key) const {
         if (Adaptor::inNode(key)) { return _in_map[key]; }
         else { return _out_map[key]; }
@@ -2950,42 +3175,45 @@
     };
 
-    template <typename _Value>
+    template <typename V>
     class ArcMapBase
-      : public MapTraits<typename Parent::template ArcMap<_Value> > {
-      typedef typename Parent::template ArcMap<_Value> ArcImpl;
-      typedef typename Parent::template NodeMap<_Value> NodeImpl;
+      : 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 _Value Value;
-
-      ArcMapBase(const Adaptor& adaptor)
+      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 Adaptor& adaptor, const Value& value)
+      ArcMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
         : _arc_map(*adaptor._digraph, value),
           _node_map(*adaptor._digraph, value) {}
 
-      void set(const Arc& key, const Value& val) {
-        if (Adaptor::origArc(key)) {
-          _arc_map.set(key._item.first(), val);
+      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(key._item.second(), val);
+          _node_map.set(static_cast<const DigraphNode&>(key), val);
         }
       }
 
-      typename MapTraits<ArcImpl>::ReturnValue
-      operator[](const Arc& key) {
-        if (Adaptor::origArc(key)) {
-          return _arc_map[key._item.first()];
+      ReturnValue operator[](const Arc& key) {
+        if (SplitNodesBase<DGR>::origArc(key)) {
+          return _arc_map[static_cast<const DigraphArc&>(key)];
         } else {
-          return _node_map[key._item.second()];
+          return _node_map[static_cast<const DigraphNode&>(key)];
         }
       }
 
-      typename MapTraits<ArcImpl>::ConstReturnValue
-      operator[](const Arc& key) const {
-        if (Adaptor::origArc(key)) {
-          return _arc_map[key._item.first()];
+      ConstReturnValue operator[](const Arc& key) const {
+        if (SplitNodesBase<DGR>::origArc(key)) {
+          return _arc_map[static_cast<const DigraphArc&>(key)];
         } else {
-          return _node_map[key._item.second()];
+          return _node_map[static_cast<const DigraphNode&>(key)];
         }
       }
@@ -2998,16 +3226,16 @@
   public:
 
-    template <typename _Value>
+    template <typename V>
     class NodeMap
-      : public SubMapExtender<Adaptor, NodeMapBase<_Value> >
+      : public SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> >
     {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, NodeMapBase<Value> > Parent;
-
-      NodeMap(const Adaptor& adaptor)
+      typedef V Value;
+      typedef SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<Value> > Parent;
+
+      NodeMap(const SplitNodesBase<DGR>& adaptor)
         : Parent(adaptor) {}
 
-      NodeMap(const Adaptor& adaptor, const Value& value)
+      NodeMap(const SplitNodesBase<DGR>& adaptor, const V& value)
         : Parent(adaptor, value) {}
 
@@ -3024,16 +3252,16 @@
     };
 
-    template <typename _Value>
+    template <typename V>
     class ArcMap
-      : public SubMapExtender<Adaptor, ArcMapBase<_Value> >
+      : public SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> >
     {
     public:
-      typedef _Value Value;
-      typedef SubMapExtender<Adaptor, ArcMapBase<Value> > Parent;
-
-      ArcMap(const Adaptor& adaptor)
+      typedef V Value;
+      typedef SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<Value> > Parent;
+
+      ArcMap(const SplitNodesBase<DGR>& adaptor)
         : Parent(adaptor) {}
 
-      ArcMap(const Adaptor& adaptor, const Value& value)
+      ArcMap(const SplitNodesBase<DGR>& adaptor, const V& value)
         : Parent(adaptor, value) {}
 
@@ -3054,7 +3282,7 @@
     SplitNodesBase() : _digraph(0) {}
 
-    Digraph* _digraph;
-
-    void setDigraph(Digraph& digraph) {
+    DGR* _digraph;
+
+    void initialize(Digraph& digraph) {
       _digraph = &digraph;
     }
@@ -3064,121 +3292,143 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief Split the nodes of a directed graph
-  ///
-  /// The SplitNodes adaptor splits each node into an in-node and an
-  /// out-node. Formaly, the adaptor replaces each \f$ u \f$ node in
-  /// the digraph with two nodes(namely node \f$ u_{in} \f$ and node
-  /// \f$ u_{out} \f$). If there is a \f$ (v, u) \f$ arc in the
-  /// original digraph the new target of the arc will be \f$ u_{in} \f$
-  /// and similarly the source of the original \f$ (u, v) \f$ arc
-  /// will be \f$ u_{out} \f$.  The adaptor will add for each node in
-  /// the original digraph an additional arc which connects
-  /// \f$ (u_{in}, u_{out}) \f$.
-  ///
-  /// The aim of this class is to run algorithm with node costs if the
-  /// algorithm can use directly just arc costs. In this case we should use
-  /// a \c SplitNodes and set the node cost of the graph to the
-  /// bind arc in the adapted graph.
-  ///
-  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
-  /// "Digraph concept". The type can be specified to be const.
-  template <typename _Digraph>
+  /// \brief Adaptor class for splitting the nodes of a digraph.
+  ///
+  /// SplitNodes adaptor can be used for splitting each node into an
+  /// \e in-node and an \e out-node in a digraph. Formaly, the adaptor
+  /// replaces each node \f$ u \f$ in the digraph with two nodes,
+  /// namely node \f$ u_{in} \f$ and node \f$ u_{out} \f$.
+  /// If there is a \f$ (v, u) \f$ arc in the original digraph, then the
+  /// new target of the arc will be \f$ u_{in} \f$ and similarly the
+  /// source of each original \f$ (u, v) \f$ arc will be \f$ u_{out} \f$.
+  /// The adaptor adds an additional \e bind \e arc from \f$ u_{in} \f$
+  /// to \f$ u_{out} \f$ for each node \f$ u \f$ of the original digraph.
+  ///
+  /// The aim of this class is running an algorithm with respect to node
+  /// costs or capacities if the algorithm considers only arc costs or
+  /// capacities directly.
+  /// In this case you can use \c SplitNodes adaptor, and set the node
+  /// costs/capacities of the original digraph to the \e bind \e arcs
+  /// in the adaptor.
+  ///
+  /// \tparam 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<_Digraph> > {
-  public:
-    typedef _Digraph Digraph;
-    typedef DigraphAdaptorExtender<SplitNodesBase<Digraph> > Parent;
-
-    typedef typename Digraph::Node DigraphNode;
-    typedef typename Digraph::Arc DigraphArc;
+    : public DigraphAdaptorExtender<SplitNodesBase<const DGR> > {
+#endif
+  public:
+    typedef DGR Digraph;
+    typedef DigraphAdaptorExtender<SplitNodesBase<const DGR> > Parent;
+
+    typedef typename DGR::Node DigraphNode;
+    typedef typename DGR::Arc DigraphArc;
 
     typedef typename Parent::Node Node;
     typedef typename Parent::Arc Arc;
 
-    /// \brief Constructor of the adaptor.
+    /// \brief Constructor
     ///
     /// Constructor of the adaptor.
-    SplitNodes(Digraph& g) {
-      Parent::setDigraph(g);
-    }
-
-    /// \brief Returns true when the node is in-node.
-    ///
-    /// Returns true when the node is in-node.
+    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 true when the node is out-node.
-    ///
-    /// Returns true when the node is out-node.
+    /// \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 true when the arc is arc in the original digraph.
-    ///
-    /// Returns true when the arc is arc in the original digraph.
+    /// \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 true when the arc binds an in-node and an out-node.
-    ///
-    /// Returns true when the arc binds an in-node and an out-node.
+    /// \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 Gives back the in-node created from the \c node.
-    ///
-    /// Gives back the in-node created from the \c node.
+    /// \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 Gives back the out-node created from the \c node.
-    ///
-    /// Gives back the out-node created from the \c node.
+    /// \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 Gives back the arc binds the two part of the node.
-    ///
-    /// Gives back the arc binds the two part of the node.
+    /// \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 Gives back the arc of the original arc.
-    ///
-    /// Gives back the arc of the original arc.
+    /// \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 NodeMap combined from two original NodeMap
-    ///
-    /// This class adapt two of the original digraph NodeMap to
-    /// get a node map on the adapted digraph.
+    /// \brief Node map combined from two original node maps
+    ///
+    /// This map adaptor class adapts two node maps of the original digraph
+    /// to get a node map of the split digraph.
+    /// Its value type is inherited from the first node map type
+    /// (\c InNodeMap).
     template <typename InNodeMap, typename OutNodeMap>
     class CombinedNodeMap {
     public:
 
+      /// The key type of the map
       typedef Node Key;
+      /// The value type of the map
       typedef typename InNodeMap::Value Value;
 
-      /// \brief Constructor
-      ///
-      /// Constructor.
+      typedef typename MapTraits<InNodeMap>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<InNodeMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<InNodeMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<InNodeMap>::ReturnValue Reference;
+      typedef typename MapTraits<InNodeMap>::ConstReturnValue ConstReference;
+
+      /// Constructor
       CombinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map)
         : _in_map(in_map), _out_map(out_map) {}
 
-      /// \brief The subscript operator.
-      ///
-      /// The subscript operator.
-      Value& operator[](const Key& key) {
-        if (Parent::inNode(key)) {
+      /// 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 {
@@ -3187,9 +3437,7 @@
       }
 
-      /// \brief The const subscript operator.
-      ///
-      /// The const subscript operator.
-      Value operator[](const Key& key) const {
-        if (Parent::inNode(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 {
@@ -3198,9 +3446,7 @@
       }
 
-      /// \brief The setter function of the map.
-      ///
-      /// The setter function of the map.
+      /// Sets the value associated with the given key.
       void set(const Key& key, const Value& value) {
-        if (Parent::inNode(key)) {
+        if (SplitNodesBase<const DGR>::inNode(key)) {
           _in_map.set(key, value);
         } else {
@@ -3217,7 +3463,7 @@
 
 
-    /// \brief Just gives back a combined node map
-    ///
-    /// Just gives back a combined node map
+    /// \brief Returns a combined node map
+    ///
+    /// This function just returns a combined node map.
     template <typename InNodeMap, typename OutNodeMap>
     static CombinedNodeMap<InNodeMap, OutNodeMap>
@@ -3245,26 +3491,51 @@
     }
 
-    /// \brief ArcMap combined from an original ArcMap and a NodeMap
-    ///
-    /// This class adapt an original ArcMap and a NodeMap to get an
-    /// arc map on the adapted digraph
-    template <typename DigraphArcMap, typename DigraphNodeMap>
+    /// \brief Arc map combined from an arc map and a node map of the
+    /// original digraph.
+    ///
+    /// This map adaptor class adapts an arc map and a node map of the
+    /// original digraph to get an arc map of the split digraph.
+    /// Its value type is inherited from the original arc map type
+    /// (\c ArcMap).
+    template <typename ArcMap, typename NodeMap>
     class CombinedArcMap {
     public:
 
+      /// The key type of the map
       typedef Arc Key;
-      typedef typename DigraphArcMap::Value Value;
-
-      /// \brief Constructor
-      ///
-      /// Constructor.
-      CombinedArcMap(DigraphArcMap& arc_map, DigraphNodeMap& node_map)
+      /// The value type of the map
+      typedef typename ArcMap::Value Value;
+
+      typedef typename MapTraits<ArcMap>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<ArcMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ArcMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ArcMap>::ReturnValue Reference;
+      typedef typename MapTraits<ArcMap>::ConstReturnValue ConstReference;
+
+      /// Constructor
+      CombinedArcMap(ArcMap& arc_map, NodeMap& node_map)
         : _arc_map(arc_map), _node_map(node_map) {}
 
-      /// \brief The subscript operator.
-      ///
-      /// The subscript operator.
+      /// 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 (Parent::origArc(arc)) {
+        if (SplitNodesBase<const DGR>::origArc(arc)) {
           _arc_map.set(arc, val);
         } else {
@@ -3273,73 +3544,50 @@
       }
 
-      /// \brief The const subscript operator.
-      ///
-      /// The const subscript operator.
-      Value operator[](const Key& arc) const {
-        if (Parent::origArc(arc)) {
-          return _arc_map[arc];
-        } else {
-          return _node_map[arc];
-        }
-      }
-
-      /// \brief The const subscript operator.
-      ///
-      /// The const subscript operator.
-      Value& operator[](const Key& arc) {
-        if (Parent::origArc(arc)) {
-          return _arc_map[arc];
-        } else {
-          return _node_map[arc];
-        }
-      }
-
     private:
-      DigraphArcMap& _arc_map;
-      DigraphNodeMap& _node_map;
+      ArcMap& _arc_map;
+      NodeMap& _node_map;
     };
 
-    /// \brief Just gives back a combined arc map
-    ///
-    /// Just gives back a combined arc map
-    template <typename DigraphArcMap, typename DigraphNodeMap>
-    static CombinedArcMap<DigraphArcMap, DigraphNodeMap>
-    combinedArcMap(DigraphArcMap& arc_map, DigraphNodeMap& node_map) {
-      return CombinedArcMap<DigraphArcMap, DigraphNodeMap>(arc_map, node_map);
-    }
-
-    template <typename DigraphArcMap, typename DigraphNodeMap>
-    static CombinedArcMap<const DigraphArcMap, DigraphNodeMap>
-    combinedArcMap(const DigraphArcMap& arc_map, DigraphNodeMap& node_map) {
-      return CombinedArcMap<const DigraphArcMap,
-        DigraphNodeMap>(arc_map, node_map);
-    }
-
-    template <typename DigraphArcMap, typename DigraphNodeMap>
-    static CombinedArcMap<DigraphArcMap, const DigraphNodeMap>
-    combinedArcMap(DigraphArcMap& arc_map, const DigraphNodeMap& node_map) {
-      return CombinedArcMap<DigraphArcMap,
-        const DigraphNodeMap>(arc_map, node_map);
-    }
-
-    template <typename DigraphArcMap, typename DigraphNodeMap>
-    static CombinedArcMap<const DigraphArcMap, const DigraphNodeMap>
-    combinedArcMap(const DigraphArcMap& arc_map,
-                   const DigraphNodeMap& node_map) {
-      return CombinedArcMap<const DigraphArcMap,
-        const DigraphNodeMap>(arc_map, node_map);
+    /// \brief 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 Just gives back a node splitter
-  ///
-  /// Just gives back a node splitter
-  template<typename Digraph>
-  SplitNodes<Digraph>
-  splitNodes(const Digraph& digraph) {
-    return SplitNodes<Digraph>(digraph);
+  /// \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
Index: lemon/arg_parser.cc
===================================================================
--- lemon/arg_parser.cc	(revision 311)
+++ lemon/arg_parser.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/arg_parser.h
===================================================================
--- lemon/arg_parser.h	(revision 311)
+++ lemon/arg_parser.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/assert.h
===================================================================
--- lemon/assert.h	(revision 290)
+++ lemon/assert.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/base.cc
===================================================================
--- lemon/base.cc	(revision 220)
+++ lemon/base.cc	(revision 507)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -24,5 +24,5 @@
 namespace lemon {
 
-  float Tolerance<float>::def_epsilon = 1e-4;
+  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;
Index: lemon/bfs.h
===================================================================
--- lemon/bfs.h	(revision 405)
+++ lemon/bfs.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -1742,5 +1742,5 @@
     /// \pre Either \ref run(Node) "run()" or \ref init()
     /// must be called before using this function.
-    bool reached(Node v) { return (*_reached)[v]; }
+    bool reached(Node v) const { return (*_reached)[v]; }
 
     ///@}
Index: lemon/bin_heap.h
===================================================================
--- lemon/bin_heap.h	(revision 209)
+++ lemon/bin_heap.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/alteration_notifier.h
===================================================================
--- lemon/bits/alteration_notifier.h	(revision 361)
+++ lemon/bits/alteration_notifier.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/array_map.h
===================================================================
--- lemon/bits/array_map.h	(revision 361)
+++ lemon/bits/array_map.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/base_extender.h
===================================================================
--- lemon/bits/base_extender.h	(revision 361)
+++ lemon/bits/base_extender.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/bezier.h
===================================================================
--- lemon/bits/bezier.h	(revision 314)
+++ lemon/bits/bezier.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/default_map.h
===================================================================
--- lemon/bits/default_map.h	(revision 314)
+++ lemon/bits/default_map.h	(revision 517)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -97,5 +97,5 @@
 
 
-#if defined __GNUC__ && !defined __STRICT_ANSI__
+#if defined HAVE_LONG_LONG
 
   // long long
Index: lemon/bits/edge_set_extender.h
===================================================================
--- lemon/bits/edge_set_extender.h	(revision 519)
+++ lemon/bits/edge_set_extender.h	(revision 519)
@@ -0,0 +1,630 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_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 {
+  public:
+
+    typedef Base Parent;
+    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;
+
+    /// \brief Gives back the arc alteration 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> > {
+    public:
+      typedef ArcSetExtender Digraph;
+      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
+
+      explicit ArcMap(const Digraph& _g) 
+	: Parent(_g) {}
+      ArcMap(const Digraph& _g, const _Value& _v) 
+	: Parent(_g, _v) {}
+
+      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 {
+
+  public:
+
+    typedef Base Parent;
+    typedef EdgeSetExtender Digraph;
+
+    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 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; 
+      }
+
+    };
+
+
+    class EdgeIt : public Parent::Edge { 
+      const Digraph* digraph;
+    public:
+
+      EdgeIt() { }
+
+      EdgeIt(Invalid i) : Edge(i) { }
+
+      explicit EdgeIt(const Digraph& _graph) : digraph(&_graph) {
+	_graph.first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const Digraph& _graph, const Edge& e) : 
+	Edge(e), digraph(&_graph) { }
+
+      EdgeIt& operator++() { 
+	digraph->next(*this);
+	return *this; 
+      }
+
+    };
+
+    class IncEdgeIt : public Parent::Edge {
+      friend class EdgeSetExtender;
+      const Digraph* digraph;
+      bool direction;
+    public:
+
+      IncEdgeIt() { }
+
+      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
+
+      IncEdgeIt(const Digraph& _graph, const Node &n) : digraph(&_graph) {
+	_graph.firstInc(*this, direction, n);
+      }
+
+      IncEdgeIt(const Digraph& _graph, const Edge &ue, const Node &n)
+	: digraph(&_graph), Edge(ue) {
+	direction = (_graph.source(ue) == n);
+      }
+
+      IncEdgeIt& operator++() {
+	digraph->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 ? u(e) : v(e);
+    }
+    /// Running node of the iterator
+    ///
+    /// Returns the running node of the iterator
+    Node runningNode(const IncEdgeIt &e) const {
+      return e.direction ? v(e) : u(e);
+    }
+
+
+    template <typename _Value>
+    class ArcMap 
+      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
+    public:
+      typedef EdgeSetExtender Digraph;
+      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
+
+      ArcMap(const Digraph& _g) 
+	: Parent(_g) {}
+      ArcMap(const Digraph& _g, const _Value& _v) 
+	: Parent(_g, _v) {}
+
+      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<Digraph, Edge, _Value> > {
+    public:
+      typedef EdgeSetExtender Digraph;
+      typedef MapExtender<DefaultMap<Digraph, Edge, _Value> > Parent;
+
+      EdgeMap(const Digraph& _g) 
+	: Parent(_g) {}
+
+      EdgeMap(const Digraph& _g, const _Value& _v) 
+	: Parent(_g, _v) {}
+
+      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
Index: lemon/bits/enable_if.h
===================================================================
--- lemon/bits/enable_if.h	(revision 314)
+++ lemon/bits/enable_if.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/graph_adaptor_extender.h
===================================================================
--- lemon/bits/graph_adaptor_extender.h	(revision 416)
+++ lemon/bits/graph_adaptor_extender.h	(revision 455)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -174,8 +174,4 @@
   };
 
-
-  /// \ingroup digraphbits
-  ///
-  /// \brief Extender for the GraphAdaptors
   template <typename _Graph>
   class GraphAdaptorExtender : public _Graph {
Index: lemon/bits/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 361)
+++ lemon/bits/graph_extender.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/map_extender.h
===================================================================
--- lemon/bits/map_extender.h	(revision 314)
+++ lemon/bits/map_extender.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/path_dump.h
===================================================================
--- lemon/bits/path_dump.h	(revision 209)
+++ lemon/bits/path_dump.h	(revision 519)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -19,4 +19,7 @@
 #ifndef LEMON_BITS_PRED_MAP_PATH_H
 #define LEMON_BITS_PRED_MAP_PATH_H
+
+#include <lemon/core.h>
+#include <lemon/concept_check.h>
 
 namespace lemon {
Index: lemon/bits/solver_bits.h
===================================================================
--- lemon/bits/solver_bits.h	(revision 519)
+++ lemon/bits/solver_bits.h	(revision 519)
@@ -0,0 +1,193 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_SOLVER_BITS_H
+#define LEMON_BITS_SOLVER_BITS_H
+
+#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;
+        first_free_item = -1;
+        items.clear();
+        cross.clear();
+      }
+
+      int addIndex(int idx) {
+        int n;
+        if (first_free_item == -1) {
+          n = items.size();
+          items.push_back(ItemT());
+        } else {
+          n = first_free_item;
+          first_free_item = items[n].next;
+          if (first_free_item != -1) {
+            items[first_free_item].prev = -1;
+          }
+        }
+        items[n].index = idx;
+        if (static_cast<int>(cross.size()) <= idx) {
+          cross.resize(idx + 1, -1);
+        }
+        cross[idx] = n;
+
+        items[n].prev = last_item;
+        items[n].next = -1;
+        if (last_item != -1) {
+          items[last_item].next = n;
+        } else {
+          first_item = n;
+        }
+        last_item = n;
+
+        return n;
+      }
+
+      int addIndex(int idx, int n) {
+        while (n >= static_cast<int>(items.size())) {
+          items.push_back(ItemT());
+          items.back().prev = -1;
+          items.back().next = first_free_item;
+          if (first_free_item != -1) {
+            items[first_free_item].prev = items.size() - 1;
+          }
+          first_free_item = items.size() - 1;
+        }
+        if (items[n].next != -1) {
+          items[items[n].next].prev = items[n].prev;
+        }
+        if (items[n].prev != -1) {
+          items[items[n].prev].next = items[n].next;
+        } else {
+          first_free_item = items[n].next;
+        }
+
+        items[n].index = idx;
+        if (static_cast<int>(cross.size()) <= idx) {
+          cross.resize(idx + 1, -1);
+        }
+        cross[idx] = n;
+
+        items[n].prev = last_item;
+        items[n].next = -1;
+        if (last_item != -1) {
+          items[last_item].next = n;
+        } else {
+          first_item = n;
+        }
+        last_item = n;
+
+        return n;
+      }
+
+      void eraseIndex(int idx) {
+        int n = cross[idx];
+
+        if (items[n].prev != -1) {
+          items[items[n].prev].next = items[n].next;
+        } else {
+          first_item = items[n].next;
+        }
+        if (items[n].next != -1) {
+          items[items[n].next].prev = items[n].prev;
+        } else {
+          last_item = items[n].prev;
+        }
+
+        if (first_free_item != -1) {
+          items[first_free_item].prev = n;
+        }
+        items[n].next = first_free_item;
+        items[n].prev = -1;
+        first_free_item = n;
+
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      int maxIndex() const {
+        return cross.size() - 1;
+      }
+
+      void shiftIndices(int idx) {
+        for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
+          cross[i - 1] = cross[i];
+          if (cross[i] != -1) {
+            --items[cross[i]].index;
+          }
+        }
+        cross.back() = -1;
+        cross.pop_back();
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      void relocateIndex(int idx, int jdx) {
+        cross[idx] = cross[jdx];
+        items[cross[jdx]].index = idx;
+        cross[jdx] = -1;
+
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      int operator[](int idx) const {
+        return cross[idx];
+      }
+
+      int operator()(int fdx) const {
+        return items[fdx].index;
+      }
+
+      void firstItem(int& fdx) const {
+        fdx = first_item;
+      }
+
+      void nextItem(int& fdx) const {
+        fdx = items[fdx].next;
+      }
+
+    };
+  }
+}
+
+#endif
Index: lemon/bits/traits.h
===================================================================
--- lemon/bits/traits.h	(revision 360)
+++ lemon/bits/traits.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/variant.h
===================================================================
--- lemon/bits/variant.h	(revision 416)
+++ lemon/bits/variant.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -22,6 +22,6 @@
 #include <lemon/assert.h>
 
-/// \file
-/// \brief Variant types
+// \file
+// \brief Variant types
 
 namespace lemon {
@@ -37,25 +37,25 @@
 
 
-  /// \brief Simple Variant type for two types
-  ///
-  /// Simple Variant type for two types. The Variant type is a type
-  /// safe union. The C++ has strong limitations for using unions, by
-  /// example we can not store type with non default constructor or
-  /// destructor in an union. This class always knowns the current
-  /// state of the variant and it cares for the proper construction
-  /// and destruction.
+  // \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.
+    // \brief The \c First type.
     typedef _First First;
-    /// \brief The \c Second type.
+    // \brief The \c Second type.
     typedef _Second Second;
 
-    /// \brief Constructor
-    ///
-    /// This constructor initalizes to the default value of the \c First
-    /// type.
+    // \brief Constructor
+    //
+    // This constructor initalizes to the default value of the \c First
+    // type.
     BiVariant() {
       flag = true;
@@ -63,8 +63,8 @@
     }
 
-    /// \brief Constructor
-    ///
-    /// This constructor initalizes to the given value of the \c First
-    /// type.
+    // \brief Constructor
+    //
+    // This constructor initalizes to the given value of the \c First
+    // type.
     BiVariant(const First& f) {
       flag = true;
@@ -72,8 +72,8 @@
     }
 
-    /// \brief Constructor
-    ///
-    /// This constructor initalizes to the given value of the \c
-    /// Second type.
+    // \brief Constructor
+    //
+    // This constructor initalizes to the given value of the \c
+    // Second type.
     BiVariant(const Second& s) {
       flag = false;
@@ -81,7 +81,7 @@
     }
 
-    /// \brief Copy constructor
-    ///
-    /// Copy constructor
+    // \brief Copy constructor
+    //
+    // Copy constructor
     BiVariant(const BiVariant& bivariant) {
       flag = bivariant.flag;
@@ -93,15 +93,15 @@
     }
 
-    /// \brief Destrcutor
-    ///
-    /// Destructor
+    // \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.
+    // \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();
@@ -111,8 +111,8 @@
     }
 
-    /// \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.
+    // \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();
@@ -122,8 +122,8 @@
     }
 
-    /// \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.
+    // \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();
@@ -133,8 +133,8 @@
     }
 
-    /// \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.
+    // \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();
@@ -144,15 +144,15 @@
     }
 
-    /// \brief Operator form of the \c setFirst()
+    // \brief Operator form of the \c setFirst()
     BiVariant& operator=(const First& f) {
       return setFirst(f);
     }
 
-    /// \brief Operator form of the \c setSecond()
+    // \brief Operator form of the \c setSecond()
     BiVariant& operator=(const Second& s) {
       return setSecond(s);
     }
 
-    /// \brief Assign operator
+    // \brief Assign operator
     BiVariant& operator=(const BiVariant& bivariant) {
       if (this == &bivariant) return *this;
@@ -167,58 +167,58 @@
     }
 
-    /// \brief Reference to the value
-    ///
-    /// Reference to the value of the \c First type.
-    /// \pre The BiVariant should store value of \c First type.
+    // \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 { 
+      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()
+      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()
+    // \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() { 
+    // \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 { 
+      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()
+      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()
+    // \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.
+    // \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.
+    // \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; }
 
@@ -290,38 +290,38 @@
   }
 
-  /// \brief Variant type
-  ///
-  /// Simple Variant type. The Variant type is a type safe union. The
-  /// C++ has strong limitations for using unions, for example we
-  /// 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
+  // \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 {
@@ -332,8 +332,8 @@
     typedef _TypeMap TypeMap;
 
-    /// \brief Constructor
-    ///
-    /// This constructor initalizes to the default value of the \c type
-    /// with 0 index.
+    // \brief Constructor
+    //
+    // This constructor initalizes to the default value of the \c type
+    // with 0 index.
     Variant() {
       flag = 0;
@@ -343,7 +343,7 @@
 
 
-    /// \brief Copy constructor
-    ///
-    /// Copy constructor
+    // \brief Copy constructor
+    //
+    // Copy constructor
     Variant(const Variant& variant) {
       flag = variant.flag;
@@ -351,7 +351,7 @@
     }
 
-    /// \brief Assign operator
-    ///
-    /// Assign operator
+    // \brief Assign operator
+    //
+    // Assign operator
     Variant& operator=(const Variant& variant) {
       if (this == &variant) return *this;
@@ -364,15 +364,15 @@
     }
 
-    /// \brief Destrcutor
-    ///
-    /// Destructor
+    // \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.
+    // \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() {
@@ -384,8 +384,8 @@
     }
 
-    /// \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.
+    // \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) {
@@ -397,7 +397,7 @@
     }
 
-    /// \brief Gets the current value of the type with \c _idx index.
-    ///
-    /// Gets the current value of the type with \c _idx index.
+    // \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 {
@@ -407,7 +407,7 @@
     }
 
-    /// \brief Gets the current value of the type with \c _idx index.
-    ///
-    /// Gets the current value of the type with \c _idx index.
+    // \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() {
@@ -417,7 +417,7 @@
     }
 
-    /// \brief Returns the current state of the variant.
-    ///
-    /// Returns the current state of the variant.
+    // \brief Returns the current state of the variant.
+    //
+    // Returns the current state of the variant.
     int state() const {
       return flag;
@@ -451,5 +451,5 @@
 
     template <int _idx, typename _T0, typename _T1, typename _T2,
-              typename _T3, typename _T5, typename _T4, typename _T6,
+              typename _T3, typename _T4, typename _T5, typename _T6,
               typename _T7, typename _T8, typename _T9>
     struct Mapper {
@@ -470,13 +470,13 @@
   }
 
-  /// \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
+  // \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 _T5 = void, typename _T4 = void, typename _T6 = void,
+    typename _T4 = void, typename _T5 = void, typename _T6 = void,
     typename _T7 = void, typename _T8 = void, typename _T9 = void>
   struct VariantTypeMap {
Index: lemon/bits/vector_map.h
===================================================================
--- lemon/bits/vector_map.h	(revision 361)
+++ lemon/bits/vector_map.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/windows.cc
===================================================================
--- lemon/bits/windows.cc	(revision 483)
+++ lemon/bits/windows.cc	(revision 483)
@@ -0,0 +1,132 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Some basic non-inline functions and static global data.
+
+#include<lemon/bits/windows.h>
+
+#ifdef WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#ifdef UNICODE
+#undef UNICODE
+#endif
+#include <windows.h>
+#ifdef LOCALE_INVARIANT
+#define MY_LOCALE LOCALE_INVARIANT
+#else
+#define MY_LOCALE LOCALE_NEUTRAL
+#endif
+#else
+#include <unistd.h>
+#include <ctime>
+#include <sys/times.h>
+#include <sys/time.h>
+#endif
+
+#include <cmath>
+#include <sstream>
+
+namespace lemon {
+  namespace bits {
+    void getWinProcTimes(double &rtime,
+                         double &utime, double &stime,
+                         double &cutime, double &cstime)
+    {
+#ifdef WIN32
+      static const double ch = 4294967296.0e-7;
+      static const double cl = 1.0e-7;
+
+      FILETIME system;
+      GetSystemTimeAsFileTime(&system);
+      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
+
+      FILETIME create, exit, kernel, user;
+      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
+        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
+        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
+        cutime = 0;
+        cstime = 0;
+      } else {
+        rtime = 0;
+        utime = 0;
+        stime = 0;
+        cutime = 0;
+        cstime = 0;
+      }
+#else
+      timeval tv;
+      gettimeofday(&tv, 0);
+      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
+
+      tms ts;
+      double tck=sysconf(_SC_CLK_TCK);
+      times(&ts);
+      utime=ts.tms_utime/tck;
+      stime=ts.tms_stime/tck;
+      cutime=ts.tms_cutime/tck;
+      cstime=ts.tms_cstime/tck;
+#endif
+    }
+
+    std::string getWinFormattedDate()
+    {
+      std::ostringstream os;
+#ifdef WIN32
+      SYSTEMTIME time;
+      GetSystemTime(&time);
+      char buf1[11], buf2[9], buf3[5];
+	  if (GetDateFormat(MY_LOCALE, 0, &time,
+                        ("ddd MMM dd"), buf1, 11) &&
+          GetTimeFormat(MY_LOCALE, 0, &time,
+                        ("HH':'mm':'ss"), buf2, 9) &&
+          GetDateFormat(MY_LOCALE, 0, &time,
+                        ("yyyy"), buf3, 5)) {
+        os << buf1 << ' ' << buf2 << ' ' << buf3;
+      }
+      else os << "unknown";
+#else
+      timeval tv;
+      gettimeofday(&tv, 0);
+
+      char cbuf[26];
+      ctime_r(&tv.tv_sec,cbuf);
+      os << cbuf;
+#endif
+      return os.str();
+    }
+
+    int getWinRndSeed()
+    {
+#ifdef WIN32
+      FILETIME time;
+      GetSystemTimeAsFileTime(&time);
+      return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
+#else
+      timeval tv;
+      gettimeofday(&tv, 0);
+      return getpid() + tv.tv_sec + tv.tv_usec;
+#endif
+    }
+  }
+}
Index: lemon/bits/windows.h
===================================================================
--- lemon/bits/windows.h	(revision 482)
+++ lemon/bits/windows.h	(revision 482)
@@ -0,0 +1,34 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_WINDOWS_H
+#define LEMON_WINDOWS_H
+
+#include <string>
+
+namespace lemon {
+  namespace bits {
+    void getWinProcTimes(double &rtime,
+                         double &utime, double &stime,
+                         double &cutime, double &cstime);
+    std::string getWinFormattedDate();
+    int getWinRndSeed();
+  }
+}
+
+#endif
Index: lemon/circulation.h
===================================================================
--- lemon/circulation.h	(revision 402)
+++ lemon/circulation.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -420,5 +420,5 @@
     /// \pre Either \ref run() or \ref init() must be called before
     /// using this function.
-    const Elevator& elevator() {
+    const Elevator& elevator() const {
       return *_level;
     }
@@ -645,5 +645,5 @@
     /// \pre Either \ref run() or \ref init() must be called before
     /// using this function.
-    const FlowMap& flowMap() {
+    const FlowMap& flowMap() const {
       return *_flow;
     }
@@ -670,5 +670,5 @@
        \sa checkBarrier()
     */
-    bool barrier(const Node& node)
+    bool barrier(const Node& node) const
     {
       return (*_level)[node] >= _el;
@@ -693,5 +693,5 @@
     /// \sa checkBarrier()
     template<class BarrierMap>
-    void barrierMap(BarrierMap &bar)
+    void barrierMap(BarrierMap &bar) const
     {
       for(NodeIt n(_g);n!=INVALID;++n)
@@ -713,5 +713,5 @@
     ///Check if the found flow is a feasible circulation,
     ///
-    bool checkFlow() {
+    bool checkFlow() const {
       for(ArcIt e(_g);e!=INVALID;++e)
         if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
@@ -731,5 +731,5 @@
     ///\sa barrier()
     ///\sa barrierMap()
-    bool checkBarrier()
+    bool checkBarrier() const
     {
       Value delta=0;
Index: lemon/clp.cc
===================================================================
--- lemon/clp.cc	(revision 462)
+++ lemon/clp.cc	(revision 462)
@@ -0,0 +1,437 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/clp.h>
+#include <coin/ClpSimplex.hpp>
+
+namespace lemon {
+
+  ClpLp::ClpLp() {
+    _prob = new ClpSimplex();
+    _init_temporals();
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  ClpLp::ClpLp(const ClpLp& other) {
+    _prob = new ClpSimplex(*other._prob);
+    rows = other.rows;
+    cols = other.cols;
+    _init_temporals();
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  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;
+  }
+
+
+  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();
+    rows.clear();
+    cols.clear();
+    _col_names_ref.clear();
+    _clear_temporals();
+  }
+
+  void ClpLp::messageLevel(MessageLevel m) {
+    _prob->setLogLevel(static_cast<int>(m));
+  }
+
+} //END OF NAMESPACE LEMON
Index: lemon/clp.h
===================================================================
--- lemon/clp.h	(revision 462)
+++ lemon/clp.h	(revision 462)
@@ -0,0 +1,179 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_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();
+
+  protected:
+
+    mutable double* _primal_ray;
+    mutable double* _dual_ray;
+
+    void _init_temporals();
+    void _clear_temporals();
+
+  protected:
+
+    virtual ClpLp* _newSolver() const;
+    virtual ClpLp* _cloneSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
+    virtual void _getObjCoeffs(InsertIterator) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual SolveExitStatus _solve();
+
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+    virtual void _clear();
+
+  public:
+
+    ///Solves LP with primal simplex method.
+    SolveExitStatus solvePrimal();
+
+    ///Solves LP with dual simplex method.
+    SolveExitStatus solveDual();
+
+    ///Solves LP with barrier method.
+    SolveExitStatus solveBarrier();
+
+    ///Returns the constraint identifier understood by CLP.
+    int clpRow(Row r) const { return rows(id(r)); }
+
+    ///Returns the variable identifier understood by CLP.
+    int clpCol(Col c) const { return cols(id(c)); }
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// print final solution
+      MESSAGE_FINAL_SOLUTION = 1,
+      /// print factorization
+      MESSAGE_FACTORIZATION = 2,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 3,
+      /// verbose output
+      MESSAGE_VERBOSE_OUTPUT = 4
+    };
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_CLP_H
+
Index: lemon/color.cc
===================================================================
--- lemon/color.cc	(revision 209)
+++ lemon/color.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/color.h
===================================================================
--- lemon/color.h	(revision 313)
+++ lemon/color.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concept_check.h
===================================================================
--- lemon/concept_check.h	(revision 285)
+++ lemon/concept_check.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/digraph.h
===================================================================
--- lemon/concepts/digraph.h	(revision 263)
+++ lemon/concepts/digraph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 263)
+++ lemon/concepts/graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/graph_components.h
===================================================================
--- lemon/concepts/graph_components.h	(revision 313)
+++ lemon/concepts/graph_components.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/heap.h
===================================================================
--- lemon/concepts/heap.h	(revision 290)
+++ lemon/concepts/heap.h	(revision 519)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -25,4 +25,5 @@
 
 #include <lemon/core.h>
+#include <lemon/concept_check.h>
 
 namespace lemon {
Index: lemon/concepts/maps.h
===================================================================
--- lemon/concepts/maps.h	(revision 314)
+++ lemon/concepts/maps.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/path.h
===================================================================
--- lemon/concepts/path.h	(revision 281)
+++ lemon/concepts/path.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/config.h.cmake
===================================================================
--- lemon/config.h.cmake	(revision 517)
+++ lemon/config.h.cmake	(revision 517)
@@ -0,0 +1,4 @@
+#cmakedefine HAVE_LONG_LONG 1
+#cmakedefine HAVE_LP 1
+#cmakedefine HAVE_MIP 1
+#cmakedefine HAVE_GLPK 1
Index: lemon/config.h.in
===================================================================
--- lemon/config.h.in	(revision 1)
+++ lemon/config.h.in	(revision 517)
@@ -1,2 +1,11 @@
+/* Define to 1 if you have long long */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have any LP solver. */
+#undef HAVE_LP
+
+/* Define to 1 if you have any MIP solver. */
+#undef HAVE_MIP
+
 /* Define to 1 if you have CPLEX. */
 #undef HAVE_CPLEX
@@ -4,2 +13,8 @@
 /* Define to 1 if you have GLPK. */
 #undef HAVE_GLPK
+
+/* Define to 1 if you have SOPLEX */
+#undef HAVE_SOPLEX
+
+/* Define to 1 if you have CLP */
+#undef HAVE_CLP
Index: lemon/connectivity.h
===================================================================
--- lemon/connectivity.h	(revision 417)
+++ lemon/connectivity.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -17,6 +17,6 @@
  */
 
-#ifndef LEMON_TOPOLOGY_H
-#define LEMON_TOPOLOGY_H
+#ifndef LEMON_CONNECTIVITY_H
+#define LEMON_CONNECTIVITY_H
 
 #include <lemon/dfs.h>
@@ -155,5 +155,5 @@
   }
 
-  namespace _topology_bits {
+  namespace _connectivity_bits {
 
     template <typename Digraph, typename Iterator >
@@ -189,17 +189,17 @@
 
     template <typename Digraph, typename ArcMap>
-    struct StronglyConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
+    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
     public:
       typedef typename Digraph::Node Node;
       typedef typename Digraph::Arc Arc;
 
-      StronglyConnectedCutEdgesVisitor(const Digraph& digraph,
-                                       ArcMap& cutMap,
-                                       int& cutNum)
+      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
+                                      ArcMap& cutMap,
+                                      int& cutNum)
         : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
-          _compMap(digraph), _num(0) {
-      }
-
-      void stop(const Node&) {
+          _compMap(digraph, -1), _num(-1) {
+      }
+
+      void start(const Node&) {
         ++_num;
       }
@@ -249,5 +249,5 @@
     if (source == INVALID) return true;
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef DfsVisitor<Digraph> Visitor;
@@ -266,4 +266,5 @@
 
     typedef ReverseDigraph<const Digraph> RDigraph;
+    typedef typename RDigraph::NodeIt RNodeIt;
     RDigraph rdigraph(digraph);
 
@@ -276,5 +277,5 @@
     rdfs.start();
 
-    for (NodeIt it(rdigraph); it != INVALID; ++it) {
+    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
       if (!rdfs.reached(it)) {
         return false;
@@ -295,5 +296,5 @@
   /// direction.
   ///
-  /// \param graph The graph.
+  /// \param digraph The graph.
   /// \return The number of components
   /// \note By definition, the empty graph has zero
@@ -303,5 +304,5 @@
     checkConcept<concepts::Digraph, Digraph>();
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef typename Digraph::Node Node;
@@ -375,5 +376,5 @@
     checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef std::vector<Node> Container;
@@ -439,5 +440,5 @@
     checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef std::vector<Node> Container;
@@ -464,5 +465,5 @@
     int cutNum = 0;
 
-    typedef StronglyConnectedCutEdgesVisitor<RDigraph, ArcMap> RVisitor;
+    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
     RVisitor rvisitor(rgraph, cutMap, cutNum);
 
@@ -479,5 +480,5 @@
   }
 
-  namespace _topology_bits {
+  namespace _connectivity_bits {
 
     template <typename Digraph>
@@ -731,5 +732,5 @@
     typedef typename Graph::NodeIt NodeIt;
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
@@ -774,5 +775,5 @@
     checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
@@ -814,5 +815,5 @@
     checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
@@ -833,5 +834,5 @@
   }
 
-  namespace _topology_bits {
+  namespace _connectivity_bits {
 
     template <typename Digraph>
@@ -1054,5 +1055,5 @@
     typedef typename Graph::NodeIt NodeIt;
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
@@ -1096,5 +1097,5 @@
     checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
@@ -1137,5 +1138,5 @@
     checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
 
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
@@ -1157,5 +1158,5 @@
 
 
-  namespace _topology_bits {
+  namespace _connectivity_bits {
 
     template <typename Digraph, typename IntNodeMap>
@@ -1194,5 +1195,5 @@
   template <typename Digraph, typename NodeMap>
   void topologicalSort(const Digraph& graph, NodeMap& order) {
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     checkConcept<concepts::Digraph, Digraph>();
@@ -1225,5 +1226,5 @@
   /// that the given graph is DAG.
   ///
-  /// \param graph The graph. It must be directed and acyclic.
+  /// \param digraph The graph. It must be directed and acyclic.
   /// \retval order A readable - writable node map. The values will be set
   /// from 0 to the number of the nodes in the graph minus one. Each values
@@ -1235,6 +1236,6 @@
   /// \see dag
   template <typename Digraph, typename NodeMap>
-  bool checkedTopologicalSort(const Digraph& graph, NodeMap& order) {
-    using namespace _topology_bits;
+  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
+    using namespace _connectivity_bits;
 
     checkConcept<concepts::Digraph, Digraph>();
@@ -1246,19 +1247,21 @@
     typedef typename Digraph::Arc Arc;
 
-    order = constMap<Node, int, -1>();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      order.set(it, -1);
+    }
 
     TopologicalSortVisitor<Digraph, NodeMap>
-      visitor(order, countNodes(graph));
+      visitor(order, countNodes(digraph));
 
     DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
-      dfs(graph, visitor);
+      dfs(digraph, visitor);
 
     dfs.init();
-    for (NodeIt it(graph); it != INVALID; ++it) {
+    for (NodeIt it(digraph); it != INVALID; ++it) {
       if (!dfs.reached(it)) {
         dfs.addSource(it);
         while (!dfs.emptyQueue()) {
-           Arc edge = dfs.nextArc();
-           Node target = graph.target(edge);
+           Arc arc = dfs.nextArc();
+           Node target = digraph.target(arc);
            if (dfs.reached(target) && order[target] == -1) {
              return false;
@@ -1280,5 +1283,5 @@
   /// \see acyclic
   template <typename Digraph>
-  bool dag(const Digraph& graph) {
+  bool dag(const Digraph& digraph) {
 
     checkConcept<concepts::Digraph, Digraph>();
@@ -1291,16 +1294,16 @@
 
     typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
-      Create dfs(graph);
-
-    ProcessedMap processed(graph);
+      Create dfs(digraph);
+
+    ProcessedMap processed(digraph);
     dfs.processedMap(processed);
 
     dfs.init();
-    for (NodeIt it(graph); it != INVALID; ++it) {
+    for (NodeIt it(digraph); it != INVALID; ++it) {
       if (!dfs.reached(it)) {
         dfs.addSource(it);
         while (!dfs.emptyQueue()) {
           Arc edge = dfs.nextArc();
-          Node target = graph.target(edge);
+          Node target = digraph.target(edge);
           if (dfs.reached(target) && !processed[target]) {
             return false;
@@ -1381,5 +1384,5 @@
   }
 
-  namespace _topology_bits {
+  namespace _connectivity_bits {
 
     template <typename Digraph>
@@ -1450,5 +1453,5 @@
   template<typename Graph>
   inline bool bipartite(const Graph &graph){
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     checkConcept<concepts::Graph, Graph>();
@@ -1490,5 +1493,5 @@
   template<typename Graph, typename NodeMap>
   inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
-    using namespace _topology_bits;
+    using namespace _connectivity_bits;
 
     checkConcept<concepts::Graph, Graph>();
@@ -1521,7 +1524,7 @@
   /// Returns true when there are not loop edges in the graph.
   template <typename Digraph>
-  bool loopFree(const Digraph& graph) {
-    for (typename Digraph::ArcIt it(graph); it != INVALID; ++it) {
-      if (graph.source(it) == graph.target(it)) return false;
+  bool loopFree(const Digraph& digraph) {
+    for (typename Digraph::ArcIt it(digraph); it != INVALID; ++it) {
+      if (digraph.source(it) == digraph.target(it)) return false;
     }
     return true;
@@ -1532,13 +1535,13 @@
   /// Returns true when there are not parallel edges in the graph.
   template <typename Digraph>
-  bool parallelFree(const Digraph& graph) {
-    typename Digraph::template NodeMap<bool> reached(graph, false);
-    for (typename Digraph::NodeIt n(graph); n != INVALID; ++n) {
-      for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
-        if (reached[graph.target(e)]) return false;
-        reached.set(graph.target(e), true);
-      }
-      for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
-        reached.set(graph.target(e), false);
+  bool parallelFree(const Digraph& digraph) {
+    typename Digraph::template NodeMap<bool> reached(digraph, false);
+    for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
+        if (reached[digraph.target(a)]) return false;
+        reached.set(digraph.target(a), true);
+      }
+      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
+        reached.set(digraph.target(a), false);
       }
     }
@@ -1552,14 +1555,14 @@
   /// the graph.
   template <typename Digraph>
-  bool simpleDigraph(const Digraph& graph) {
-    typename Digraph::template NodeMap<bool> reached(graph, false);
-    for (typename Digraph::NodeIt n(graph); n != INVALID; ++n) {
+  bool simpleDigraph(const Digraph& digraph) {
+    typename Digraph::template NodeMap<bool> reached(digraph, false);
+    for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
       reached.set(n, true);
-      for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
-        if (reached[graph.target(e)]) return false;
-        reached.set(graph.target(e), true);
-      }
-      for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
-        reached.set(graph.target(e), false);
+      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
+        if (reached[digraph.target(a)]) return false;
+        reached.set(digraph.target(a), true);
+      }
+      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
+        reached.set(digraph.target(a), false);
       }
       reached.set(n, false);
@@ -1570,3 +1573,3 @@
 } //namespace lemon
 
-#endif //LEMON_TOPOLOGY_H
+#endif //LEMON_CONNECTIVITY_H
Index: lemon/core.h
===================================================================
--- lemon/core.h	(revision 319)
+++ lemon/core.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -1171,6 +1171,6 @@
     /// Construct a new ConEdgeIt iterating on the edges that
     /// connects nodes \c u and \c v.
-    ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g) {
-      Parent::operator=(findEdge(_graph, u, v));
+    ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
+      Parent::operator=(findEdge(_graph, _u, _v));
     }
 
@@ -1184,10 +1184,10 @@
     /// It increments the iterator and gives back the next edge.
     ConEdgeIt& operator++() {
-      Parent::operator=(findEdge(_graph, _graph.u(*this),
-                                 _graph.v(*this), *this));
+      Parent::operator=(findEdge(_graph, _u, _v, *this));
       return *this;
     }
   private:
     const Graph& _graph;
+    Node _u, _v;
   };
 
Index: lemon/counter.h
===================================================================
--- lemon/counter.h	(revision 209)
+++ lemon/counter.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/cplex.cc
===================================================================
--- lemon/cplex.cc	(revision 462)
+++ lemon/cplex.cc	(revision 462)
@@ -0,0 +1,925 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <vector>
+#include <cstring>
+
+#include <lemon/cplex.h>
+
+extern "C" {
+#include <ilcplex/cplex.h>
+}
+
+
+///\file
+///\brief Implementation of the LEMON-CPLEX lp solver interface.
+namespace lemon {
+
+  CplexEnv::LicenseError::LicenseError(int status) {
+    if (!CPXgeterrorstring(0, status, _message)) {
+      std::strcpy(_message, "Cplex unknown error");
+    }
+  }
+
+  CplexEnv::CplexEnv() {
+    int status;
+    _cnt = new int;
+    _env = CPXopenCPLEX(&status);
+    if (_env == 0) {
+      delete _cnt;
+      _cnt = 0;
+      throw LicenseError(status);
+    }
+  }
+
+  CplexEnv::CplexEnv(const CplexEnv& other) {
+    _env = other._env;
+    _cnt = other._cnt;
+    ++(*_cnt);
+  }
+
+  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
+    _env = other._env;
+    _cnt = other._cnt;
+    ++(*_cnt);
+    return *this;
+  }
+
+  CplexEnv::~CplexEnv() {
+    --(*_cnt);
+    if (*_cnt == 0) {
+      delete _cnt;
+      CPXcloseCPLEX(&_env);
+    }
+  }
+
+  CplexBase::CplexBase() : LpBase() {
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+  }
+
+  CplexBase::CplexBase(const CplexEnv& env)
+    : LpBase(), _env(env) {
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+  }
+
+  CplexBase::CplexBase(const CplexBase& cplex)
+    : LpBase() {
+    int status;
+    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
+    rows = cplex.rows;
+    cols = cplex.cols;
+  }
+
+  CplexBase::~CplexBase() {
+    CPXfreeprob(cplexEnv(),&_prob);
+  }
+
+  int CplexBase::_addCol() {
+    int i = CPXgetnumcols(cplexEnv(), _prob);
+    double lb = -INF, ub = INF;
+    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
+    return i;
+  }
+
+
+  int CplexBase::_addRow() {
+    int i = CPXgetnumrows(cplexEnv(), _prob);
+    const double ub = INF;
+    const char s = 'L';
+    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
+    return i;
+  }
+
+
+  void CplexBase::_eraseCol(int i) {
+    CPXdelcols(cplexEnv(), _prob, i, i);
+  }
+
+  void CplexBase::_eraseRow(int i) {
+    CPXdelrows(cplexEnv(), _prob, i, i);
+  }
+
+  void CplexBase::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+  void CplexBase::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void CplexBase::_getColName(int col, std::string &name) const {
+    int size;
+    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
+    if (size == 0) {
+      name.clear();
+      return;
+    }
+
+    size *= -1;
+    std::vector<char> buf(size);
+    char *cname;
+    int tmp;
+    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
+                  &tmp, col, col);
+    name = cname;
+  }
+
+  void CplexBase::_setColName(int col, const std::string &name) {
+    char *cname;
+    cname = const_cast<char*>(name.c_str());
+    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
+  }
+
+  int CplexBase::_colByName(const std::string& name) const {
+    int index;
+    if (CPXgetcolindex(cplexEnv(), _prob,
+                       const_cast<char*>(name.c_str()), &index) == 0) {
+      return index;
+    }
+    return -1;
+  }
+
+  void CplexBase::_getRowName(int row, std::string &name) const {
+    int size;
+    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
+    if (size == 0) {
+      name.clear();
+      return;
+    }
+
+    size *= -1;
+    std::vector<char> buf(size);
+    char *cname;
+    int tmp;
+    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
+                  &tmp, row, row);
+    name = cname;
+  }
+
+  void CplexBase::_setRowName(int row, const std::string &name) {
+    char *cname;
+    cname = const_cast<char*>(name.c_str());
+    CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
+  }
+
+  int CplexBase::_rowByName(const std::string& name) const {
+    int index;
+    if (CPXgetrowindex(cplexEnv(), _prob,
+                       const_cast<char*>(name.c_str()), &index) == 0) {
+      return index;
+    }
+    return -1;
+  }
+
+  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
+                                      ExprIterator e)
+  {
+    std::vector<int> indices;
+    std::vector<int> rowlist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      rowlist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &rowlist.front(), &indices.front(), &values.front());
+  }
+
+  void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
+    int tmp1, tmp2, tmp3, length;
+    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
+               &indices.front(), &values.front(),
+               length, &tmp3, i, i);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+  }
+
+  void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
+    std::vector<int> indices;
+    std::vector<int> collist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      collist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &indices.front(), &collist.front(), &values.front());
+  }
+
+  void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
+
+    int tmp1, tmp2, tmp3, length;
+    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
+               &indices.front(), &values.front(),
+               length, &tmp3, i, i);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+
+  }
+
+  void CplexBase::_setCoeff(int row, int col, Value value) {
+    CPXchgcoef(cplexEnv(), _prob, row, col, value);
+  }
+
+  CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
+    CplexBase::Value value;
+    CPXgetcoef(cplexEnv(), _prob, row, col, &value);
+    return value;
+  }
+
+  void CplexBase::_setColLowerBound(int i, Value value) {
+    const char s = 'L';
+    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
+  }
+
+  CplexBase::Value CplexBase::_getColLowerBound(int i) const {
+    CplexBase::Value res;
+    CPXgetlb(cplexEnv(), _prob, &res, i, i);
+    return res <= -CPX_INFBOUND ? -INF : res;
+  }
+
+  void CplexBase::_setColUpperBound(int i, Value value)
+  {
+    const char s = 'U';
+    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
+  }
+
+  CplexBase::Value CplexBase::_getColUpperBound(int i) const {
+    CplexBase::Value res;
+    CPXgetub(cplexEnv(), _prob, &res, i, i);
+    return res >= CPX_INFBOUND ? INF : res;
+  }
+
+  CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
+    char s;
+    CPXgetsense(cplexEnv(), _prob, &s, i, i);
+    CplexBase::Value res;
+
+    switch (s) {
+    case 'G':
+    case 'R':
+    case 'E':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      return res <= -CPX_INFBOUND ? -INF : res;
+    default:
+      return -INF;
+    }
+  }
+
+  CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
+    char s;
+    CPXgetsense(cplexEnv(), _prob, &s, i, i);
+    CplexBase::Value res;
+
+    switch (s) {
+    case 'L':
+    case 'E':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      return res >= CPX_INFBOUND ? INF : res;
+    case 'R':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      {
+        double rng;
+        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
+        res += rng;
+      }
+      return res >= CPX_INFBOUND ? INF : res;
+    default:
+      return INF;
+    }
+  }
+
+  //This is easier to implement
+  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
+    if (lb == -INF) {
+      const char s = 'L';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
+    } else if (ub == INF) {
+      const char s = 'G';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+    } else if (lb == ub){
+      const char s = 'E';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+    } else {
+      const char s = 'R';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+      double len = ub - lb;
+      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
+    }
+  }
+
+  void CplexBase::_setRowLowerBound(int i, Value lb)
+  {
+    LEMON_ASSERT(lb != INF, "Invalid bound");
+    _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
+  }
+
+  void CplexBase::_setRowUpperBound(int i, Value ub)
+  {
+
+    LEMON_ASSERT(ub != -INF, "Invalid bound");
+    _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
+  }
+
+  void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
+  {
+    std::vector<int> indices;
+    std::vector<Value> values;
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+    }
+    CPXchgobj(cplexEnv(), _prob, values.size(),
+              &indices.front(), &values.front());
+
+  }
+
+  void CplexBase::_getObjCoeffs(InsertIterator b) const
+  {
+    int num = CPXgetnumcols(cplexEnv(), _prob);
+    std::vector<Value> x(num);
+
+    CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
+    for (int i = 0; i < num; ++i) {
+      if (x[i] != 0.0) {
+        *b = std::make_pair(i, x[i]);
+        ++b;
+      }
+    }
+  }
+
+  void CplexBase::_setObjCoeff(int i, Value obj_coef)
+  {
+    CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
+  }
+
+  CplexBase::Value CplexBase::_getObjCoeff(int i) const
+  {
+    Value x;
+    CPXgetobj(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  void CplexBase::_setSense(CplexBase::Sense sense) {
+    switch (sense) {
+    case MIN:
+      CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
+      break;
+    case MAX:
+      CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
+      break;
+    }
+  }
+
+  CplexBase::Sense CplexBase::_getSense() const {
+    switch (CPXgetobjsen(cplexEnv(), _prob)) {
+    case CPX_MIN:
+      return MIN;
+    case CPX_MAX:
+      return MAX;
+    default:
+      LEMON_ASSERT(false, "Invalid sense");
+      return CplexBase::Sense();
+    }
+  }
+
+  void CplexBase::_clear() {
+    CPXfreeprob(cplexEnv(),&_prob);
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+    rows.clear();
+    cols.clear();
+  }
+
+  // CplexLp members
+
+  CplexLp::CplexLp()
+    : LpBase(), CplexBase(), LpSolver() {}
+
+  CplexLp::CplexLp(const CplexEnv& env)
+    : LpBase(), CplexBase(env), LpSolver() {}
+
+  CplexLp::CplexLp(const CplexLp& other)
+    : LpBase(), CplexBase(other), LpSolver() {}
+
+  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();
+    return convertStatus(CPXlpopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solvePrimal() {
+    _clear_temporals();
+    return convertStatus(CPXprimopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solveDual() {
+    _clear_temporals();
+    return convertStatus(CPXdualopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solveBarrier() {
+    _clear_temporals();
+    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];
+  }
+
+  //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
+  // This table lists the statuses, returned by the CPXgetstat()
+  // routine, for solutions to LP problems or mixed integer problems. If
+  // no solution exists, the return value is zero.
+
+  // For Simplex, Barrier
+  // 1          CPX_OPTIMAL
+  //          Optimal solution found
+  // 2          CPX_INFEASIBLE
+  //          Problem infeasible
+  // 3    CPX_UNBOUNDED
+  //          Problem unbounded
+  // 4          CPX_OBJ_LIM
+  //          Objective limit exceeded in Phase II
+  // 5          CPX_IT_LIM_FEAS
+  //          Iteration limit exceeded in Phase II
+  // 6          CPX_IT_LIM_INFEAS
+  //          Iteration limit exceeded in Phase I
+  // 7          CPX_TIME_LIM_FEAS
+  //          Time limit exceeded in Phase II
+  // 8          CPX_TIME_LIM_INFEAS
+  //          Time limit exceeded in Phase I
+  // 9          CPX_NUM_BEST_FEAS
+  //          Problem non-optimal, singularities in Phase II
+  // 10         CPX_NUM_BEST_INFEAS
+  //          Problem non-optimal, singularities in Phase I
+  // 11         CPX_OPTIMAL_INFEAS
+  //          Optimal solution found, unscaled infeasibilities
+  // 12         CPX_ABORT_FEAS
+  //          Aborted in Phase II
+  // 13         CPX_ABORT_INFEAS
+  //          Aborted in Phase I
+  // 14          CPX_ABORT_DUAL_INFEAS
+  //          Aborted in barrier, dual infeasible
+  // 15          CPX_ABORT_PRIM_INFEAS
+  //          Aborted in barrier, primal infeasible
+  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
+  //          Aborted in barrier, primal and dual infeasible
+  // 17          CPX_ABORT_PRIM_DUAL_FEAS
+  //          Aborted in barrier, primal and dual feasible
+  // 18          CPX_ABORT_CROSSOVER
+  //          Aborted in crossover
+  // 19          CPX_INForUNBD
+  //          Infeasible or unbounded
+  // 20   CPX_PIVOT
+  //       User pivot used
+  //
+  //     Ezeket hova tegyem:
+  // ??case CPX_ABORT_DUAL_INFEAS
+  // ??case CPX_ABORT_CROSSOVER
+  // ??case CPX_INForUNBD
+  // ??case CPX_PIVOT
+
+  //Some more interesting stuff:
+
+  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
+  // 0 Automatic
+  // 1 Primal Simplex
+  // 2 Dual Simplex
+  // 3 Network Simplex
+  // 4 Standard Barrier
+  // Default: 0
+  // Description: Method for linear optimization.
+  // Determines which algorithm is used when CPXlpopt() (or "optimize"
+  // in the Interactive Optimizer) is called. Currently the behavior of
+  // the "Automatic" setting is that CPLEX simply invokes the dual
+  // simplex method, but this capability may be expanded in the future
+  // so that CPLEX chooses the method based on problem characteristics
+#if CPX_VERSION < 900
+  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
+    int lpmethod;
+    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
+    if (lpmethod==2){
+      if (stat==CPX_UNBOUNDED){
+        stat=CPX_INFEASIBLE;
+      }
+      else{
+        if (stat==CPX_INFEASIBLE)
+          stat=CPX_UNBOUNDED;
+      }
+    }
+  }
+#else
+  void statusSwitch(CPXENVptr,int&){}
+#endif
+
+  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);
+    //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
+    switch (stat) {
+    case 0:
+      return UNDEFINED; //Undefined
+    case CPX_OPTIMAL://Optimal
+      return OPTIMAL;
+    case CPX_UNBOUNDED://Unbounded
+      return INFEASIBLE;//In case of dual simplex
+      //return UNBOUNDED;
+    case CPX_INFEASIBLE://Infeasible
+      //    case CPX_IT_LIM_INFEAS:
+      //     case CPX_TIME_LIM_INFEAS:
+      //     case CPX_NUM_BEST_INFEAS:
+      //     case CPX_OPTIMAL_INFEAS:
+      //     case CPX_ABORT_INFEAS:
+      //     case CPX_ABORT_PRIM_INFEAS:
+      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
+      return UNBOUNDED;//In case of dual simplex
+      //return INFEASIBLE;
+      //     case CPX_OBJ_LIM:
+      //     case CPX_IT_LIM_FEAS:
+      //     case CPX_TIME_LIM_FEAS:
+      //     case CPX_NUM_BEST_FEAS:
+      //     case CPX_ABORT_FEAS:
+      //     case CPX_ABORT_PRIM_DUAL_FEAS:
+      //       return FEASIBLE;
+    default:
+      return UNDEFINED; //Everything else comes here
+      //FIXME error
+    }
+#endif
+  }
+
+  //9.0-as cplex verzio statusai
+  // CPX_STAT_ABORT_DUAL_OBJ_LIM
+  // CPX_STAT_ABORT_IT_LIM
+  // CPX_STAT_ABORT_OBJ_LIM
+  // CPX_STAT_ABORT_PRIM_OBJ_LIM
+  // CPX_STAT_ABORT_TIME_LIM
+  // CPX_STAT_ABORT_USER
+  // CPX_STAT_FEASIBLE_RELAXED
+  // CPX_STAT_INFEASIBLE
+  // CPX_STAT_INForUNBD
+  // CPX_STAT_NUM_BEST
+  // CPX_STAT_OPTIMAL
+  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
+  // CPX_STAT_OPTIMAL_INFEAS
+  // CPX_STAT_OPTIMAL_RELAXED
+  // CPX_STAT_UNBOUNDED
+
+  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(), CplexBase(), MipSolver() {
+
+#if CPX_VERSION < 800
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
+#else
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
+#endif
+  }
+
+  CplexMip::CplexMip(const CplexEnv& env)
+    : LpBase(), CplexBase(env), MipSolver() {
+
+#if CPX_VERSION < 800
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
+#else
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
+#endif
+
+  }
+
+  CplexMip::CplexMip(const CplexMip& other)
+    : LpBase(), CplexBase(other), MipSolver() {}
+
+  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;
+    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
+
Index: lemon/cplex.h
===================================================================
--- lemon/cplex.h	(revision 462)
+++ lemon/cplex.h	(revision 462)
@@ -0,0 +1,256 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_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 void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+  private:
+    void _set_row_bounds(int i, Value lb, Value ub);
+  protected:
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual void _clear();
+
+  public:
+
+    /// Returns the used \c CplexEnv instance
+    const CplexEnv& env() const { return _env; }
+    ///
+    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
+
+    cpxlp* cplexLp() { return _prob; }
+    const cpxlp* cplexLp() const { return _prob; }
+
+  };
+
+  /// \brief Interface for the CPLEX LP solver
+  ///
+  /// This class implements an interface for the CPLEX LP solver.
+  ///\ingroup lp_group
+  class CplexLp : public CplexBase, public LpSolver {
+  public:
+    /// \e
+    CplexLp();
+    /// \e
+    CplexLp(const CplexEnv&);
+    /// \e
+    CplexLp(const CplexLp&);
+    /// \e
+    virtual ~CplexLp();
+
+  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 CplexLp* _cloneSolver() const;
+    virtual CplexLp* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+    virtual Value _getPrimalValue() const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+  public:
+
+    /// Solve with primal simplex method
+    SolveExitStatus solvePrimal();
+
+    /// Solve with dual simplex method
+    SolveExitStatus solveDual();
+
+    /// Solve with barrier method
+    SolveExitStatus solveBarrier();
+
+  };
+
+  /// \brief Interface for the CPLEX MIP solver
+  ///
+  /// This class implements an interface for the CPLEX MIP solver.
+  ///\ingroup lp_group
+  class CplexMip : public CplexBase, public MipSolver {
+  public:
+    /// \e
+    CplexMip();
+    /// \e
+    CplexMip(const CplexEnv&);
+    /// \e
+    CplexMip(const CplexMip&);
+    /// \e
+    virtual ~CplexMip();
+
+  protected:
+
+    virtual CplexMip* _cloneSolver() const;
+    virtual CplexMip* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_CPLEX_H
+
Index: lemon/dfs.h
===================================================================
--- lemon/dfs.h	(revision 405)
+++ lemon/dfs.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -1411,4 +1411,5 @@
           } else {
             _visitor->leave(s);
+            _visitor->stop(s);
           }
         }
@@ -1626,5 +1627,5 @@
     /// \pre Either \ref run(Node) "run()" or \ref init()
     /// must be called before using this function.
-    bool reached(Node v) { return (*_reached)[v]; }
+    bool reached(Node v) const { return (*_reached)[v]; }
 
     ///@}
Index: lemon/dijkstra.h
===================================================================
--- lemon/dijkstra.h	(revision 408)
+++ lemon/dijkstra.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/dim2.h
===================================================================
--- lemon/dim2.h	(revision 314)
+++ lemon/dim2.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/dimacs.h
===================================================================
--- lemon/dimacs.h	(revision 388)
+++ lemon/dimacs.h	(revision 525)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -296,7 +296,22 @@
   }
 
-  /// DIMACS plain digraph reader function.
-  ///
-  /// This function reads a digraph without any designated nodes and
+  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);
+  }
+  
+  /// DIMACS plain (di)graph reader function.
+  ///
+  /// This function reads a (di)graph without any designated nodes and
   /// maps from DIMACS format, i.e. from DIMACS files having a line
   /// starting with
@@ -308,13 +323,36 @@
   /// If the file type was previously evaluated by dimacsType(), then
   /// the descriptor struct should be given by the \c dest parameter.
-  template<typename Digraph>
-  void readDimacsMat(std::istream& is, Digraph &g,
-                     DimacsDescriptor desc=DimacsDescriptor()) {
-    typename Digraph::Node u,v;
-    NullMap<typename Digraph::Arc, int> n;
+  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");
-    _readDimacs(is, g, n, u, v, desc);
+
+    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 (arc) definition line
+        is >> i >> j;
+        getline(is, str);
+        _addArcEdge(g,nodes[i], nodes[j]);
+        break;
+      }
+    }
   }
 
@@ -335,5 +373,5 @@
     typedef typename Digraph::ArcIt ArcIt;
 
-    if(!comment.empty()) 
+    if(!comment.empty())
       os << "c " << comment << std::endl;
     os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
Index: lemon/edge_set.h
===================================================================
--- lemon/edge_set.h	(revision 512)
+++ lemon/edge_set.h	(revision 512)
@@ -0,0 +1,1410 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_EDGE_SET_H
+#define LEMON_EDGE_SET_H
+
+#include <lemon/core.h>
+#include <lemon/bits/edge_set_extender.h>
+
+/// \ingroup semi_adaptors
+/// \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 GR Graph;
+    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) {}
+
+    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> {
+    public:
+
+      typedef typename GR::template NodeMap<V> Parent;
+
+      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 semi_adaptors
+  ///
+  /// \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.
+  ///
+  /// \param GR The type of the graph which shares its node set with
+  /// this class. Its interface must conform to the
+  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
+  /// concept.
+  ///
+  /// This class is fully conform to the \ref concepts::Digraph
+  /// "Digraph" concept.
+  template <typename GR>
+  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
+
+  public:
+
+    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    typedef GR Graph;
+
+
+    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 {
+    public:
+      typedef NodesImplBase Parent;
+
+      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 GR Graph;
+    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) {}
+
+    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> {
+    public:
+
+      typedef typename GR::template NodeMap<V> Parent;
+
+      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 semi_adaptors
+  ///
+  /// \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.
+  ///
+  /// \param GR The type of the graph which shares its node set
+  /// with this class. Its interface must conform to the
+  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
+  /// concept.
+  ///
+  /// This class is fully conform to the \ref concepts::Graph "Graph"
+  /// concept.
+  template <typename GR>
+  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
+
+  public:
+
+    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    typedef GR Graph;
+
+
+    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 {
+    public:
+      typedef NodesImplBase Parent;
+
+      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 GR Graph;
+    typedef typename Graph::Node Node;
+    typedef typename Graph::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() {}
+
+    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;
+    }
+
+    void next(Arc& arc) const {
+      --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> {
+    public:
+
+      typedef typename GR::template NodeMap<V> Parent;
+
+      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 semi_adaptors
+  ///
+  /// \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.
+  ///
+  /// \warning If a node is erased from the underlying graph and this
+  /// node is the source or target of one arc in the arc set, then
+  /// the arc set is invalidated, and it cannot be used anymore. The
+  /// validity can be checked with the \c valid() member function.
+  ///
+  /// This class is fully conform to the \ref concepts::Digraph
+  /// "Digraph" concept.
+  template <typename GR>
+  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
+
+  public:
+
+    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    typedef GR Graph;
+
+  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 {
+    public:
+      typedef NodesImplBase Parent;
+
+      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 GR Graph;
+    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() {}
+
+    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;
+    }
+
+    void next(Arc& arc) const {
+      --arc.id;
+    }
+
+    void first(Edge& arc) const {
+      arc.id = arcs.size() / 2 - 1;
+    }
+
+    void next(Edge& arc) const {
+      --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> {
+    public:
+
+      typedef typename GR::template NodeMap<V> Parent;
+
+      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 semi_adaptors
+  ///
+  /// \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.
+  ///
+  /// \warning If a node is erased from the underlying graph and this
+  /// node is incident to one edge in the edge set, then the edge set
+  /// is invalidated, and it cannot be used anymore. The validity can
+  /// be checked with the \c valid() member function.
+  ///
+  /// This class is fully conform to the \ref concepts::Graph
+  /// "Graph" concept.
+  template <typename GR>
+  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
+
+  public:
+
+    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    typedef GR Graph;
+
+  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 {
+    public:
+      typedef NodesImplBase Parent;
+
+      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
Index: lemon/elevator.h
===================================================================
--- lemon/elevator.h	(revision 383)
+++ lemon/elevator.h	(revision 519)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -28,4 +28,5 @@
 ///
 
+#include <lemon/core.h>
 #include <lemon/bits/traits.h>
 
Index: lemon/error.h
===================================================================
--- lemon/error.h	(revision 291)
+++ lemon/error.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/euler.h
===================================================================
--- lemon/euler.h	(revision 522)
+++ lemon/euler.h	(revision 522)
@@ -0,0 +1,264 @@
+/* -*- 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_EULER_H
+#define LEMON_EULER_H
+
+#include<lemon/core.h>
+#include<lemon/adaptors.h>
+#include<lemon/connectivity.h>
+#include <list>
+
+/// \ingroup graph_prop
+/// \file
+/// \brief Euler tour
+///
+///This file provides an Euler tour iterator and ways to check
+///if a digraph is euler.
+
+
+namespace lemon {
+
+  ///Euler iterator for digraphs.
+
+  /// \ingroup graph_prop
+  ///This iterator converts to the \c Arc type of the digraph and using
+  ///operator ++, it provides an Euler tour of a \e directed
+  ///graph (if there exists).
+  ///
+  ///For example
+  ///if the given digraph is Euler (i.e it has only one nontrivial component
+  ///and the in-degree is equal to the out-degree for all nodes),
+  ///the following code will put the arcs of \c g
+  ///to the vector \c et according to an
+  ///Euler tour of \c g.
+  ///\code
+  ///  std::vector<ListDigraph::Arc> et;
+  ///  for(DiEulerIt<ListDigraph> e(g),e!=INVALID;++e)
+  ///    et.push_back(e);
+  ///\endcode
+  ///If \c g is not Euler then the resulted tour will not be full or closed.
+  ///\sa EulerIt
+  template<class Digraph>
+  class DiEulerIt
+  {
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::ArcIt ArcIt;
+    typedef typename Digraph::OutArcIt OutArcIt;
+    typedef typename Digraph::InArcIt InArcIt;
+
+    const Digraph &g;
+    typename Digraph::template NodeMap<OutArcIt> nedge;
+    std::list<Arc> euler;
+
+  public:
+
+    ///Constructor
+
+    ///\param _g A digraph.
+    ///\param start The starting point of the tour. If it is not given
+    ///       the tour will start from the first node.
+    DiEulerIt(const Digraph &_g,typename Digraph::Node start=INVALID)
+      : g(_g), nedge(g)
+    {
+      if(start==INVALID) start=NodeIt(g);
+      for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
+      while(nedge[start]!=INVALID) {
+        euler.push_back(nedge[start]);
+        Node next=g.target(nedge[start]);
+        ++nedge[start];
+        start=next;
+      }
+    }
+
+    ///Arc Conversion
+    operator Arc() { return euler.empty()?INVALID:euler.front(); }
+    bool operator==(Invalid) { return euler.empty(); }
+    bool operator!=(Invalid) { return !euler.empty(); }
+
+    ///Next arc of the tour
+    DiEulerIt &operator++() {
+      Node s=g.target(euler.front());
+      euler.pop_front();
+      //This produces a warning.Strange.
+      //std::list<Arc>::iterator next=euler.begin();
+      typename std::list<Arc>::iterator next=euler.begin();
+      while(nedge[s]!=INVALID) {
+        euler.insert(next,nedge[s]);
+        Node n=g.target(nedge[s]);
+        ++nedge[s];
+        s=n;
+      }
+      return *this;
+    }
+    ///Postfix incrementation
+
+    ///\warning This incrementation
+    ///returns an \c Arc, not an \ref DiEulerIt, as one may
+    ///expect.
+    Arc operator++(int)
+    {
+      Arc e=*this;
+      ++(*this);
+      return e;
+    }
+  };
+
+  ///Euler iterator for graphs.
+
+  /// \ingroup graph_prop
+  ///This iterator converts to the \c Arc (or \c Edge)
+  ///type of the digraph and using
+  ///operator ++, it provides an Euler tour of an undirected
+  ///digraph (if there exists).
+  ///
+  ///For example
+  ///if the given digraph if Euler (i.e it has only one nontrivial component
+  ///and the degree of each node is even),
+  ///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 the iterator provides an Euler tour of an graph,
+  ///it still returns Arcs in order to indicate the direction of the tour.
+  ///(But Arc will convert to Edges, of course).
+  ///
+  ///If \c g is not Euler then the resulted tour will not be full or closed.
+  ///\sa EulerIt
+  template<class Digraph>
+  class EulerIt
+  {
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::Edge Edge;
+    typedef typename Digraph::ArcIt ArcIt;
+    typedef typename Digraph::OutArcIt OutArcIt;
+    typedef typename Digraph::InArcIt InArcIt;
+
+    const Digraph &g;
+    typename Digraph::template NodeMap<OutArcIt> nedge;
+    typename Digraph::template EdgeMap<bool> visited;
+    std::list<Arc> euler;
+
+  public:
+
+    ///Constructor
+
+    ///\param _g An graph.
+    ///\param start The starting point of the tour. If it is not given
+    ///       the tour will start from the first node.
+    EulerIt(const Digraph &_g,typename Digraph::Node start=INVALID)
+      : g(_g), nedge(g), visited(g,false)
+    {
+      if(start==INVALID) start=NodeIt(g);
+      for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
+      while(nedge[start]!=INVALID) {
+        euler.push_back(nedge[start]);
+        visited[nedge[start]]=true;
+        Node next=g.target(nedge[start]);
+        ++nedge[start];
+        start=next;
+        while(nedge[start]!=INVALID && visited[nedge[start]]) ++nedge[start];
+      }
+    }
+
+    ///Arc Conversion
+    operator Arc() const { return euler.empty()?INVALID:euler.front(); }
+    ///Arc Conversion
+    operator Edge() const { return euler.empty()?INVALID:euler.front(); }
+    ///\e
+    bool operator==(Invalid) const { return euler.empty(); }
+    ///\e
+    bool operator!=(Invalid) const { return !euler.empty(); }
+
+    ///Next arc of the tour
+    EulerIt &operator++() {
+      Node s=g.target(euler.front());
+      euler.pop_front();
+      typename std::list<Arc>::iterator next=euler.begin();
+
+      while(nedge[s]!=INVALID) {
+        while(nedge[s]!=INVALID && visited[nedge[s]]) ++nedge[s];
+        if(nedge[s]==INVALID) break;
+        else {
+          euler.insert(next,nedge[s]);
+          visited[nedge[s]]=true;
+          Node n=g.target(nedge[s]);
+          ++nedge[s];
+          s=n;
+        }
+      }
+      return *this;
+    }
+
+    ///Postfix incrementation
+
+    ///\warning This incrementation
+    ///returns an \c Arc, not an \ref EulerIt, as one may
+    ///expect.
+    Arc operator++(int)
+    {
+      Arc e=*this;
+      ++(*this);
+      return e;
+    }
+  };
+
+
+  ///Checks if the graph is Eulerian
+
+  /// \ingroup graph_prop
+  ///Checks if the graph is Eulerian. It works for both directed and undirected
+  ///graphs.
+  ///\note By definition, a digraph is called \e Eulerian if
+  ///and only if it is connected and the number of its incoming and outgoing
+  ///arcs are the same for each node.
+  ///Similarly, an undirected graph is called \e Eulerian if
+  ///and only if it is connected and the number of incident arcs is even
+  ///for each node. <em>Therefore, there are digraphs which are not Eulerian,
+  ///but still have an Euler tour</em>.
+  template<class Digraph>
+#ifdef DOXYGEN
+  bool
+#else
+  typename enable_if<UndirectedTagIndicator<Digraph>,bool>::type
+  eulerian(const Digraph &g)
+  {
+    for(typename Digraph::NodeIt n(g);n!=INVALID;++n)
+      if(countIncEdges(g,n)%2) return false;
+    return connected(g);
+  }
+  template<class Digraph>
+  typename disable_if<UndirectedTagIndicator<Digraph>,bool>::type
+#endif
+  eulerian(const Digraph &g)
+  {
+    for(typename Digraph::NodeIt n(g);n!=INVALID;++n)
+      if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
+    return connected(Undirector<const Digraph>(g));
+  }
+
+}
+
+#endif
Index: lemon/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 360)
+++ lemon/full_graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/glpk.cc
===================================================================
--- lemon/glpk.cc	(revision 462)
+++ lemon/glpk.cc	(revision 462)
@@ -0,0 +1,952 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
+
+#include <lemon/glpk.h>
+#include <glpk.h>
+
+#include <lemon/assert.h>
+
+namespace lemon {
+
+  // GlpkBase members
+
+  GlpkBase::GlpkBase() : LpBase() {
+    lp = glp_create_prob();
+    glp_create_index(lp);
+  }
+
+  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
+    lp = glp_create_prob();
+    glp_copy_prob(lp, other.lp, GLP_ON);
+    glp_create_index(lp);
+    rows = other.rows;
+    cols = other.cols;
+  }
+
+  GlpkBase::~GlpkBase() {
+    glp_delete_prob(lp);
+  }
+
+  int GlpkBase::_addCol() {
+    int i = glp_add_cols(lp, 1);
+    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  int GlpkBase::_addRow() {
+    int i = glp_add_rows(lp, 1);
+    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  void GlpkBase::_eraseCol(int i) {
+    int ca[2];
+    ca[1] = i;
+    glp_del_cols(lp, 1, ca);
+  }
+
+  void GlpkBase::_eraseRow(int i) {
+    int ra[2];
+    ra[1] = i;
+    glp_del_rows(lp, 1, ra);
+  }
+
+  void GlpkBase::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+
+  void GlpkBase::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void GlpkBase::_getColName(int c, std::string& name) const {
+    const char *str = glp_get_col_name(lp, c);
+    if (str) name = str;
+    else name.clear();
+  }
+
+  void GlpkBase::_setColName(int c, const std::string & name) {
+    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
+
+  }
+
+  int GlpkBase::_colByName(const std::string& name) const {
+    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
+    return k > 0 ? k : -1;
+  }
+
+  void GlpkBase::_getRowName(int r, std::string& name) const {
+    const char *str = glp_get_row_name(lp, r);
+    if (str) name = str;
+    else name.clear();
+  }
+
+  void GlpkBase::_setRowName(int r, const std::string & name) {
+    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
+
+  }
+
+  int GlpkBase::_rowByName(const std::string& name) const {
+    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
+    return k > 0 ? k : -1;
+  }
+
+  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    indexes.push_back(0);
+    values.push_back(0);
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    glp_set_mat_row(lp, i, values.size() - 1,
+                    &indexes.front(), &values.front());
+  }
+
+  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
+    int length = glp_get_mat_row(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i <= length; ++i) {
+      *b = std::make_pair(indexes[i], values[i]);
+      ++b;
+    }
+  }
+
+  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
+                                     ExprIterator e) {
+
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    indexes.push_back(0);
+    values.push_back(0);
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    glp_set_mat_col(lp, ix, values.size() - 1,
+                    &indexes.front(), &values.front());
+  }
+
+  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
+    int length = glp_get_mat_col(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i  <= length; ++i) {
+      *b = std::make_pair(indexes[i], values[i]);
+      ++b;
+    }
+  }
+
+  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
+
+    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
+
+      int length = glp_get_mat_row(lp, ix, 0, 0);
+
+      std::vector<int> indexes(length + 2);
+      std::vector<Value> values(length + 2);
+
+      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+      //The following code does not suppose that the elements of the
+      //array indexes are sorted
+      bool found = false;
+      for (int i = 1; i  <= length; ++i) {
+        if (indexes[i] == jx) {
+          found = true;
+          values[i] = value;
+          break;
+        }
+      }
+      if (!found) {
+        ++length;
+        indexes[length] = jx;
+        values[length] = value;
+      }
+
+      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
+
+    } else {
+
+      int length = glp_get_mat_col(lp, jx, 0, 0);
+
+      std::vector<int> indexes(length + 2);
+      std::vector<Value> values(length + 2);
+
+      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
+
+      //The following code does not suppose that the elements of the
+      //array indexes are sorted
+      bool found = false;
+      for (int i = 1; i <= length; ++i) {
+        if (indexes[i] == ix) {
+          found = true;
+          values[i] = value;
+          break;
+        }
+      }
+      if (!found) {
+        ++length;
+        indexes[length] = ix;
+        values[length] = value;
+      }
+
+      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
+
+    int length = glp_get_mat_row(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i  <= length; ++i) {
+      if (indexes[i] == jx) {
+        return values[i];
+      }
+    }
+
+    return 0;
+  }
+
+  void GlpkBase::_setColLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+
+    int b = glp_get_col_type(lp, i);
+    double up = glp_get_col_ub(lp, i);
+    if (lo == -INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_UP:
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
+    int b = glp_get_col_type(lp, i);
+    switch (b) {
+    case GLP_LO:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_col_lb(lp, i);
+    default:
+      return -INF;
+    }
+  }
+
+  void GlpkBase::_setColUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+
+    int b = glp_get_col_type(lp, i);
+    double lo = glp_get_col_lb(lp, i);
+    if (up == INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        break;
+      case GLP_UP:
+        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_UP:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_LO:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
+    int b = glp_get_col_type(lp, i);
+      switch (b) {
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        return glp_get_col_ub(lp, i);
+      default:
+        return INF;
+      }
+  }
+
+  void GlpkBase::_setRowLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+
+    int b = glp_get_row_type(lp, i);
+    double up = glp_get_row_ub(lp, i);
+    if (lo == -INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_UP:
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
+    int b = glp_get_row_type(lp, i);
+    switch (b) {
+    case GLP_LO:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_row_lb(lp, i);
+    default:
+      return -INF;
+    }
+  }
+
+  void GlpkBase::_setRowUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+
+    int b = glp_get_row_type(lp, i);
+    double lo = glp_get_row_lb(lp, i);
+    if (up == INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        break;
+      case GLP_UP:
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_UP:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_LO:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
+    int b = glp_get_row_type(lp, i);
+    switch (b) {
+    case GLP_UP:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_row_ub(lp, i);
+    default:
+      return INF;
+    }
+  }
+
+  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
+      glp_set_obj_coef(lp, i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      glp_set_obj_coef(lp, it->first, it->second);
+    }
+  }
+
+  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
+    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
+      Value val = glp_get_obj_coef(lp, i);
+      if (val != 0.0) {
+        *b = std::make_pair(i, val);
+        ++b;
+      }
+    }
+  }
+
+  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
+    //i = 0 means the constant term (shift)
+    glp_set_obj_coef(lp, i, obj_coef);
+  }
+
+  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
+    //i = 0 means the constant term (shift)
+    return glp_get_obj_coef(lp, i);
+  }
+
+  void GlpkBase::_setSense(GlpkBase::Sense sense) {
+    switch (sense) {
+    case MIN:
+      glp_set_obj_dir(lp, GLP_MIN);
+      break;
+    case MAX:
+      glp_set_obj_dir(lp, GLP_MAX);
+      break;
+    }
+  }
+
+  GlpkBase::Sense GlpkBase::_getSense() const {
+    switch(glp_get_obj_dir(lp)) {
+    case GLP_MIN:
+      return MIN;
+    case GLP_MAX:
+      return MAX;
+    default:
+      LEMON_ASSERT(false, "Wrong sense");
+      return GlpkBase::Sense();
+    }
+  }
+
+  void GlpkBase::_clear() {
+    glp_erase_prob(lp);
+    rows.clear();
+    cols.clear();
+  }
+
+  // GlpkLp members
+
+  GlpkLp::GlpkLp()
+    : LpBase(), GlpkBase(), LpSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  GlpkLp::GlpkLp(const GlpkLp& other)
+    : LpBase(other), GlpkBase(other), LpSolver(other) {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  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);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
+    _clear_temporals();
+
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+    smcp.meth = GLP_DUAL;
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+  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 b) {
+    lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
+  }
+
+  void GlpkLp::messageLevel(MessageLevel m) {
+    _message_level = m;
+  }
+
+  // GlpkMip members
+
+  GlpkMip::GlpkMip()
+    : LpBase(), GlpkBase(), MipSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  GlpkMip::GlpkMip(const GlpkMip& other)
+    : LpBase(), GlpkBase(other), MipSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  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);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+    smcp.meth = GLP_DUAL;
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
+
+    glp_iocp iocp;
+    glp_init_iocp(&iocp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      iocp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      iocp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      iocp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      iocp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+
+    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+
+  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"; }
+
+  void GlpkMip::messageLevel(MessageLevel m) {
+    _message_level = m;
+  }
+
+} //END OF NAMESPACE LEMON
Index: lemon/glpk.h
===================================================================
--- lemon/glpk.h	(revision 462)
+++ lemon/glpk.h	(revision 462)
@@ -0,0 +1,259 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_GLPK_H
+#define LEMON_GLPK_H
+
+///\file
+///\brief Header of the LEMON-GLPK lp solver interface.
+///\ingroup lp_group
+
+#include <lemon/lp_base.h>
+
+// forward declaration
+#ifndef _GLP_PROB
+#define _GLP_PROB
+typedef struct { double _prob; } glp_prob;
+/* LP/MIP problem object */
+#endif
+
+namespace lemon {
+
+
+  /// \brief Base interface for the GLPK LP and MIP solver
+  ///
+  /// This class implements the common interface of the GLPK LP and MIP solver.
+  /// \ingroup lp_group
+  class GlpkBase : virtual public LpBase {
+  protected:
+
+    typedef glp_prob LPX;
+    glp_prob* lp;
+
+    GlpkBase();
+    GlpkBase(const GlpkBase&);
+    virtual ~GlpkBase();
+
+  protected:
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense);
+    virtual Sense _getSense() const;
+
+    virtual void _clear();
+
+  public:
+
+    ///Pointer to the underlying GLPK data structure.
+    LPX *lpx() {return lp;}
+    ///Const pointer to the underlying GLPK data structure.
+    const LPX *lpx() const {return lp;}
+
+    ///Returns the constraint identifier understood by GLPK.
+    int lpxRow(Row r) const { return rows(id(r)); }
+
+    ///Returns the variable identifier understood by GLPK.
+    int lpxCol(Col c) const { return cols(id(c)); }
+
+  };
+
+  /// \brief Interface for the GLPK LP solver
+  ///
+  /// This class implements an interface for the GLPK LP solver.
+  ///\ingroup lp_group
+  class GlpkLp : public GlpkBase, public LpSolver {
+  public:
+
+    ///\e
+    GlpkLp();
+    ///\e
+    GlpkLp(const GlpkLp&);
+
+  private:
+
+    mutable std::vector<double> _primal_ray;
+    mutable std::vector<double> _dual_ray;
+
+    void _clear_temporals();
+
+  protected:
+
+    virtual GlpkLp* _cloneSolver() const;
+    virtual GlpkLp* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    ///\todo It should be clarified
+    ///
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+  public:
+
+    ///Solve with primal simplex
+    SolveExitStatus solvePrimal();
+
+    ///Solve with dual simplex
+    SolveExitStatus solveDual();
+
+    ///Turns on or off the presolver
+
+    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
+    ///
+    ///The presolver is off by default.
+    void presolver(bool b);
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// error messages only
+      MESSAGE_ERROR_MESSAGE = 1,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 2,
+      /// full output (includes informational messages)
+      MESSAGE_FULL_OUTPUT = 3
+    };
+
+  private:
+
+    MessageLevel _message_level;
+
+  public:
+
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+  };
+
+  /// \brief Interface for the GLPK MIP solver
+  ///
+  /// This class implements an interface for the GLPK MIP solver.
+  ///\ingroup lp_group
+  class GlpkMip : public GlpkBase, public MipSolver {
+  public:
+
+    ///\e
+    GlpkMip();
+    ///\e
+    GlpkMip(const GlpkMip&);
+
+  protected:
+
+    virtual GlpkMip* _cloneSolver() const;
+    virtual GlpkMip* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// error messages only
+      MESSAGE_ERROR_MESSAGE = 1,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 2,
+      /// full output (includes informational messages)
+      MESSAGE_FULL_OUTPUT = 3
+    };
+
+  private:
+
+    MessageLevel _message_level;
+
+  public:
+
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+  };
+
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_GLPK_H
+
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 313)
+++ lemon/graph_to_eps.h	(revision 515)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -30,7 +30,5 @@
 #include<ctime>
 #else
-#define WIN32_LEAN_AND_MEAN
-#define NOMINMAX
-#include<windows.h>
+#include<lemon/bits/windows.h>
 #endif
 
@@ -680,4 +678,5 @@
 
     {
+      os << "%%CreationDate: ";
 #ifndef WIN32
       timeval tv;
@@ -686,21 +685,10 @@
       char cbuf[26];
       ctime_r(&tv.tv_sec,cbuf);
-      os << "%%CreationDate: " << cbuf;
+      os << cbuf;
 #else
-      SYSTEMTIME time;
-      char buf1[11], buf2[9], buf3[5];
-
-      GetSystemTime(&time);
-      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
-                        "ddd MMM dd", buf1, 11) &&
-          GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
-                        "HH':'mm':'ss", buf2, 9) &&
-          GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
-                                "yyyy", buf3, 5)) {
-        os << "%%CreationDate: " << buf1 << ' '
-           << buf2 << ' ' << buf3 << std::endl;
-      }
+      os << bits::getWinFormattedDate();
 #endif
     }
+    os << std::endl;
 
     if (_autoArcWidthScale) {
Index: lemon/grid_graph.h
===================================================================
--- lemon/grid_graph.h	(revision 360)
+++ lemon/grid_graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/hao_orlin.h
===================================================================
--- lemon/hao_orlin.h	(revision 412)
+++ lemon/hao_orlin.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -239,5 +239,5 @@
           if (reached[t]) continue;
           _sets.push_front(std::list<int>());
-          
+
           queue[qlast++] = t;
           reached.set(t, true);
@@ -539,5 +539,5 @@
           if (reached[t]) continue;
           _sets.push_front(std::list<int>());
-          
+
           queue[qlast++] = t;
           reached.set(t, true);
Index: lemon/hypercube_graph.h
===================================================================
--- lemon/hypercube_graph.h	(revision 372)
+++ lemon/hypercube_graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/kruskal.h
===================================================================
--- lemon/kruskal.h	(revision 220)
+++ lemon/kruskal.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 319)
+++ lemon/lgf_reader.h	(revision 517)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -391,35 +391,11 @@
   class DigraphReader;
 
-  /// \brief Return a \ref DigraphReader class
-  ///
-  /// This function just returns a \ref DigraphReader class.
-  /// \relates DigraphReader
   template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph,
-                                       std::istream& is = std::cin) {
-    DigraphReader<Digraph> tmp(digraph, is);
-    return tmp;
-  }
-
-  /// \brief Return a \ref DigraphReader class
-  ///
-  /// This function just returns a \ref DigraphReader class.
-  /// \relates DigraphReader
+  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
+                                       std::istream& is = std::cin);
   template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph,
-                                       const std::string& fn) {
-    DigraphReader<Digraph> tmp(digraph, fn);
-    return tmp;
-  }
-
-  /// \brief Return a \ref DigraphReader class
-  ///
-  /// This function just returns a \ref DigraphReader class.
-  /// \relates DigraphReader
+  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
   template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
-    DigraphReader<Digraph> tmp(digraph, fn);
-    return tmp;
-  }
+  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
 
   /// \ingroup lemon_io
@@ -585,10 +561,11 @@
   private:
 
-    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
-                                                  std::istream& is);
-    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
-                                                  const std::string& fn);
-    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
-                                                  const char *fn);
+    template <typename DGR>
+    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
+    template <typename DGR>
+    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
+                                            const std::string& fn);
+    template <typename DGR>
+    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
 
     DigraphReader(DigraphReader& other)
@@ -871,5 +848,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -1211,36 +1190,45 @@
   };
 
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  /// \relates DigraphReader
+  template <typename Digraph>
+  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
+    DigraphReader<Digraph> tmp(digraph, is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  /// \relates DigraphReader
+  template <typename Digraph>
+  DigraphReader<Digraph> digraphReader(Digraph& digraph,
+                                       const std::string& fn) {
+    DigraphReader<Digraph> tmp(digraph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  /// \relates DigraphReader
+  template <typename Digraph>
+  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
+    DigraphReader<Digraph> tmp(digraph, fn);
+    return tmp;
+  }
+
   template <typename Graph>
   class GraphReader;
-
-  /// \brief Return a \ref GraphReader class
-  ///
-  /// This function just returns a \ref GraphReader class.
-  /// \relates GraphReader
+ 
   template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
-    GraphReader<Graph> tmp(graph, is);
-    return tmp;
-  }
-
-  /// \brief Return a \ref GraphReader class
-  ///
-  /// This function just returns a \ref GraphReader class.
-  /// \relates GraphReader
+  GraphReader<Graph> graphReader(Graph& graph, 
+                                 std::istream& is = std::cin);
   template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
-    GraphReader<Graph> tmp(graph, fn);
-    return tmp;
-  }
-
-  /// \brief Return a \ref GraphReader class
-  ///
-  /// This function just returns a \ref GraphReader class.
-  /// \relates GraphReader
+  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
   template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
-    GraphReader<Graph> tmp(graph, fn);
-    return tmp;
-  }
+  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
 
   /// \ingroup lemon_io
@@ -1369,8 +1357,10 @@
 
   private:
-    friend GraphReader<Graph> graphReader<>(Graph& graph, std::istream& is);
-    friend GraphReader<Graph> graphReader<>(Graph& graph,
-                                            const std::string& fn);
-    friend GraphReader<Graph> graphReader<>(Graph& graph, const char *fn);
+    template <typename GR>
+    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
+    template <typename GR>
+    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
+    template <typename GR>
+    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
 
     GraphReader(GraphReader& other)
@@ -1700,5 +1690,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -2041,4 +2033,34 @@
   };
 
+  /// \brief Return a \ref GraphReader class
+  ///
+  /// This function just returns a \ref GraphReader class.
+  /// \relates GraphReader
+  template <typename Graph>
+  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
+    GraphReader<Graph> tmp(graph, is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref GraphReader class
+  ///
+  /// This function just returns a \ref GraphReader class.
+  /// \relates GraphReader
+  template <typename Graph>
+  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
+    GraphReader<Graph> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref GraphReader class
+  ///
+  /// This function just returns a \ref GraphReader class.
+  /// \relates GraphReader
+  template <typename Graph>
+  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
+    GraphReader<Graph> tmp(graph, fn);
+    return tmp;
+  }
+
   class SectionReader;
 
@@ -2227,5 +2249,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -2568,5 +2592,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 319)
+++ lemon/lgf_writer.h	(revision 517)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -351,36 +351,15 @@
   class DigraphWriter;
 
-  /// \brief Return a \ref DigraphWriter class
-  ///
-  /// This function just returns a \ref DigraphWriter class.
-  /// \relates DigraphWriter
   template <typename Digraph>
   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       std::ostream& os = std::cout) {
-    DigraphWriter<Digraph> tmp(digraph, os);
-    return tmp;
-  }
-
-  /// \brief Return a \ref DigraphWriter class
-  ///
-  /// This function just returns a \ref DigraphWriter class.
-  /// \relates DigraphWriter
+                                       std::ostream& os = std::cout);
   template <typename Digraph>
   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       const std::string& fn) {
-    DigraphWriter<Digraph> tmp(digraph, fn);
-    return tmp;
-  }
-
-  /// \brief Return a \ref DigraphWriter class
-  ///
-  /// This function just returns a \ref DigraphWriter class.
-  /// \relates DigraphWriter
+                                       const std::string& fn);
+
   template <typename Digraph>
   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       const char* fn) {
-    DigraphWriter<Digraph> tmp(digraph, fn);
-    return tmp;
-  }
+                                       const char* fn);
+
 
   /// \ingroup lemon_io
@@ -527,10 +506,13 @@
   private:
 
-    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
-                                                  std::ostream& os);
-    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
-                                                  const std::string& fn);
-    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
-                                                  const char *fn);
+    template <typename DGR>
+    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
+                                            std::ostream& os);
+    template <typename DGR>
+    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
+                                            const std::string& fn);
+    template <typename DGR>
+    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
+                                            const char *fn);
 
     DigraphWriter(DigraphWriter& other)
@@ -934,37 +916,47 @@
   };
 
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  /// \relates DigraphWriter
+  template <typename Digraph>
+  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
+                                       std::ostream& os) {
+    DigraphWriter<Digraph> tmp(digraph, os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  /// \relates DigraphWriter
+  template <typename Digraph>
+  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
+                                       const std::string& fn) {
+    DigraphWriter<Digraph> tmp(digraph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  /// \relates DigraphWriter
+  template <typename Digraph>
+  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
+                                       const char* fn) {
+    DigraphWriter<Digraph> tmp(digraph, fn);
+    return tmp;
+  }
+
   template <typename Graph>
   class GraphWriter;
 
-  /// \brief Return a \ref GraphWriter class
-  ///
-  /// This function just returns a \ref GraphWriter class.
-  /// \relates GraphWriter
   template <typename Graph>
   GraphWriter<Graph> graphWriter(const Graph& graph,
-                                 std::ostream& os = std::cout) {
-    GraphWriter<Graph> tmp(graph, os);
-    return tmp;
-  }
-
-  /// \brief Return a \ref GraphWriter class
-  ///
-  /// This function just returns a \ref GraphWriter class.
-  /// \relates GraphWriter
+                                 std::ostream& os = std::cout);
   template <typename Graph>
-  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
-    GraphWriter<Graph> tmp(graph, fn);
-    return tmp;
-  }
-
-  /// \brief Return a \ref GraphWriter class
-  ///
-  /// This function just returns a \ref GraphWriter class.
-  /// \relates GraphWriter
+  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
   template <typename Graph>
-  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
-    GraphWriter<Graph> tmp(graph, fn);
-    return tmp;
-  }
+  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
 
   /// \ingroup lemon_io
@@ -1082,11 +1074,14 @@
   private:
 
-    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
-                                            std::ostream& os);
-    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
-                                            const std::string& fn);
-    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
-                                            const char *fn);
-
+    template <typename GR>
+    friend GraphWriter<GR> graphWriter(const GR& graph,
+                                       std::ostream& os);
+    template <typename GR>
+    friend GraphWriter<GR> graphWriter(const GR& graph,
+                                       const std::string& fn);
+    template <typename GR>
+    friend GraphWriter<GR> graphWriter(const GR& graph,
+                                       const char *fn);
+    
     GraphWriter(GraphWriter& other)
       : _os(other._os), local_os(other.local_os), _graph(other._graph),
@@ -1534,4 +1529,35 @@
     /// @}
   };
+
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  /// \relates GraphWriter
+  template <typename Graph>
+  GraphWriter<Graph> graphWriter(const Graph& graph,
+                                 std::ostream& os) {
+    GraphWriter<Graph> tmp(graph, os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  /// \relates GraphWriter
+  template <typename Graph>
+  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
+    GraphWriter<Graph> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  /// \relates GraphWriter
+  template <typename Graph>
+  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
+    GraphWriter<Graph> tmp(graph, fn);
+    return tmp;
+  }
 
   class SectionWriter;
Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 329)
+++ lemon/list_graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/lp.h
===================================================================
--- lemon/lp.h	(revision 462)
+++ lemon/lp.h	(revision 462)
@@ -0,0 +1,93 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_H
+#define LEMON_LP_H
+
+#include<lemon/config.h>
+
+
+#ifdef HAVE_GLPK
+#include <lemon/glpk.h>
+#elif HAVE_CPLEX
+#include <lemon/cplex.h>
+#elif HAVE_SOPLEX
+#include <lemon/soplex.h>
+#elif HAVE_CLP
+#include <lemon/clp.h>
+#endif
+
+///\file
+///\brief Defines a default LP solver
+///\ingroup lp_group
+namespace lemon {
+
+#ifdef DOXYGEN
+  ///The default LP solver identifier
+
+  ///The default LP solver identifier.
+  ///\ingroup lp_group
+  ///
+  ///Currently, the possible values are \c GLPK, \c CPLEX,
+  ///\c SOPLEX or \c 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 GLPK or \c CPLEX
+#define LEMON_DEFAULT_MIP SOLVER
+  ///The default MIP solver.
+
+  ///The default MIP solver.
+  ///\ingroup lp_group
+  ///
+  ///Currently, it is either \c GlpkMip or \c CplexMip
+  typedef GlpkMip Mip;
+#else
+#ifdef HAVE_GLPK
+# define LEMON_DEFAULT_LP GLPK
+  typedef GlpkLp Lp;
+# define LEMON_DEFAULT_MIP GLPK
+  typedef GlpkMip Mip;
+#elif HAVE_CPLEX
+# define LEMON_DEFAULT_LP CPLEX
+  typedef CplexLp Lp;
+# define LEMON_DEFAULT_MIP CPLEX
+  typedef CplexMip Mip;
+#elif HAVE_SOPLEX
+# define DEFAULT_LP SOPLEX
+  typedef SoplexLp Lp;
+#elif HAVE_CLP
+# define DEFAULT_LP CLP
+  typedef ClpLp Lp;  
+#endif
+#endif
+
+} //namespace lemon
+
+#endif //LEMON_LP_H
Index: lemon/lp_base.cc
===================================================================
--- lemon/lp_base.cc	(revision 510)
+++ lemon/lp_base.cc	(revision 510)
@@ -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-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief The implementation of the LP solver interface.
+
+#include <lemon/lp_base.h>
+namespace lemon {
+
+  const LpBase::Value LpBase::INF =
+    std::numeric_limits<LpBase::Value>::infinity();
+  const LpBase::Value LpBase::NaN =
+    std::numeric_limits<LpBase::Value>::quiet_NaN();
+
+} //namespace lemon
Index: lemon/lp_base.h
===================================================================
--- lemon/lp_base.h	(revision 514)
+++ lemon/lp_base.h	(revision 514)
@@ -0,0 +1,2080 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_BASE_H
+#define LEMON_LP_BASE_H
+
+#include<iostream>
+#include<vector>
+#include<map>
+#include<limits>
+#include<lemon/math.h>
+
+#include<lemon/error.h>
+#include<lemon/assert.h>
+
+#include<lemon/core.h>
+#include<lemon/bits/solver_bits.h>
+
+///\file
+///\brief The interface of the LP solver interface.
+///\ingroup lp_group
+namespace lemon {
+
+  ///Common base class for LP and MIP solvers
+
+  ///Usually this class is not used directly, please use one of the concrete
+  ///implementations of the solver interface.
+  ///\ingroup lp_group
+  class LpBase {
+
+  protected:
+
+    _solver_bits::VarIndex rows;
+    _solver_bits::VarIndex cols;
+
+  public:
+
+    ///Possible outcomes of an LP solving procedure
+    enum SolveExitStatus {
+      ///This means that the problem has been successfully solved: either
+      ///an optimal solution has been found or infeasibility/unboundedness
+      ///has been proved.
+      SOLVED = 0,
+      ///Any other case (including the case when some user specified
+      ///limit has been exceeded)
+      UNSOLVED = 1
+    };
+
+    ///Direction of the optimization
+    enum Sense {
+      /// Minimization
+      MIN,
+      /// Maximization
+      MAX
+    };
+
+    ///The floating point type used by the solver
+    typedef double Value;
+    ///The infinity constant
+    static const Value INF;
+    ///The not a number constant
+    static const Value NaN;
+
+    friend class Col;
+    friend class ColIt;
+    friend class Row;
+    friend class RowIt;
+
+    ///Refer to a column of the LP.
+
+    ///This type is used to refer to a column of the LP.
+    ///
+    ///Its value remains valid and correct even after the addition or erase of
+    ///other columns.
+    ///
+    ///\note This class is similar to other Item types in LEMON, like
+    ///Node and Arc types in digraph.
+    class Col {
+      friend class LpBase;
+    protected:
+      int _id;
+      explicit Col(int id) : _id(id) {}
+    public:
+      typedef Value ExprValue;
+      typedef True LpCol;
+      /// Default constructor
+      
+      /// \warning The default constructor sets the Col to an
+      /// undefined value.
+      Col() {}
+      /// Invalid constructor \& conversion.
+      
+      /// This constructor initializes the Col to be invalid.
+      /// \sa Invalid for more details.      
+      Col(const Invalid&) : _id(-1) {}
+      /// Equality operator
+
+      /// Two \ref Col "Col"s are equal if and only if they point to
+      /// the same LP column or both are invalid.
+      bool operator==(Col c) const  {return _id == c._id;}
+      /// Inequality operator
+
+      /// \sa operator==(Col c)
+      ///
+      bool operator!=(Col c) const  {return _id != c._id;}
+      /// Artificial ordering operator.
+
+      /// To allow the use of this object in std::map or similar
+      /// associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(Col c) const  {return _id < c._id;}
+    };
+
+    ///Iterator for iterate over the columns of an LP problem
+
+    /// Its usage is quite simple, for example you can count the number
+    /// of columns in an LP \c lp:
+    ///\code
+    /// int count=0;
+    /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
+    ///\endcode
+    class ColIt : public Col {
+      const LpBase *_solver;
+    public:
+      /// Default constructor
+      
+      /// \warning The default constructor sets the iterator
+      /// to an undefined value.
+      ColIt() {}
+      /// Sets the iterator to the first Col
+      
+      /// Sets the iterator to the first Col.
+      ///
+      ColIt(const LpBase &solver) : _solver(&solver)
+      {
+        _solver->cols.firstItem(_id);
+      }
+      /// Invalid constructor \& conversion
+      
+      /// Initialize the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ColIt(const Invalid&) : Col(INVALID) {}
+      /// Next column
+      
+      /// Assign the iterator to the next column.
+      ///
+      ColIt &operator++()
+      {
+        _solver->cols.nextItem(_id);
+        return *this;
+      }
+    };
+
+    /// \brief Returns the ID of the column.
+    static int id(const Col& col) { return col._id; }
+    /// \brief Returns the column with the given ID.
+    ///
+    /// \pre The argument should be a valid column ID in the LP problem.
+    static Col colFromId(int id) { return Col(id); }
+
+    ///Refer to a row of the LP.
+
+    ///This type is used to refer to a row of the LP.
+    ///
+    ///Its value remains valid and correct even after the addition or erase of
+    ///other rows.
+    ///
+    ///\note This class is similar to other Item types in LEMON, like
+    ///Node and Arc types in digraph.
+    class Row {
+      friend class LpBase;
+    protected:
+      int _id;
+      explicit Row(int id) : _id(id) {}
+    public:
+      typedef Value ExprValue;
+      typedef True LpRow;
+      /// Default constructor
+      
+      /// \warning The default constructor sets the Row to an
+      /// undefined value.
+      Row() {}
+      /// Invalid constructor \& conversion.
+      
+      /// This constructor initializes the Row to be invalid.
+      /// \sa Invalid for more details.      
+      Row(const Invalid&) : _id(-1) {}
+      /// Equality operator
+
+      /// Two \ref Row "Row"s are equal if and only if they point to
+      /// the same LP row or both are invalid.
+      bool operator==(Row r) const  {return _id == r._id;}
+      /// Inequality operator
+      
+      /// \sa operator==(Row r)
+      ///
+      bool operator!=(Row r) const  {return _id != r._id;}
+      /// Artificial ordering operator.
+
+      /// To allow the use of this object in std::map or similar
+      /// associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(Row r) const  {return _id < r._id;}
+    };
+
+    ///Iterator for iterate over the rows of an LP problem
+
+    /// Its usage is quite simple, for example you can count the number
+    /// of rows in an LP \c lp:
+    ///\code
+    /// int count=0;
+    /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
+    ///\endcode
+    class RowIt : public Row {
+      const LpBase *_solver;
+    public:
+      /// Default constructor
+      
+      /// \warning The default constructor sets the iterator
+      /// to an undefined value.
+      RowIt() {}
+      /// Sets the iterator to the first Row
+      
+      /// Sets the iterator to the first Row.
+      ///
+      RowIt(const LpBase &solver) : _solver(&solver)
+      {
+        _solver->rows.firstItem(_id);
+      }
+      /// Invalid constructor \& conversion
+      
+      /// Initialize the iterator to be invalid.
+      /// \sa Invalid for more details.
+      RowIt(const Invalid&) : Row(INVALID) {}
+      /// Next row
+      
+      /// Assign the iterator to the next row.
+      ///
+      RowIt &operator++()
+      {
+        _solver->rows.nextItem(_id);
+        return *this;
+      }
+    };
+
+    /// \brief Returns the ID of the row.
+    static int id(const Row& row) { return row._id; }
+    /// \brief Returns the row with the given ID.
+    ///
+    /// \pre The argument should be a valid row ID in the LP problem.
+    static Row rowFromId(int id) { return Row(id); }
+
+  public:
+
+    ///Linear expression of variables and a constant component
+
+    ///This data structure stores a linear expression of the variables
+    ///(\ref Col "Col"s) and also has a constant component.
+    ///
+    ///There are several ways to access and modify the contents of this
+    ///container.
+    ///\code
+    ///e[v]=5;
+    ///e[v]+=12;
+    ///e.erase(v);
+    ///\endcode
+    ///or you can also iterate through its elements.
+    ///\code
+    ///double s=0;
+    ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
+    ///  s+=*i * primal(i);
+    ///\endcode
+    ///(This code computes the primal value of the expression).
+    ///- Numbers (<tt>double</tt>'s)
+    ///and variables (\ref Col "Col"s) directly convert to an
+    ///\ref Expr and the usual linear operations are defined, so
+    ///\code
+    ///v+w
+    ///2*v-3.12*(v-w/2)+2
+    ///v*2.1+(3*v+(v*12+w+6)*3)/2
+    ///\endcode
+    ///are valid expressions.
+    ///The usual assignment operations are also defined.
+    ///\code
+    ///e=v+w;
+    ///e+=2*v-3.12*(v-w/2)+2;
+    ///e*=3.4;
+    ///e/=5;
+    ///\endcode
+    ///- The constant member can be set and read by dereference
+    ///  operator (unary *)
+    ///
+    ///\code
+    ///*e=12;
+    ///double c=*e;
+    ///\endcode
+    ///
+    ///\sa Constr
+    class Expr {
+      friend class LpBase;
+    public:
+      /// The key type of the expression
+      typedef LpBase::Col Key;
+      /// The value type of the expression
+      typedef LpBase::Value Value;
+
+    protected:
+      Value const_comp;
+      std::map<int, Value> comps;
+
+    public:
+      typedef True SolverExpr;
+      /// Default constructor
+      
+      /// Construct an empty expression, the coefficients and
+      /// the constant component are initialized to zero.
+      Expr() : const_comp(0) {}
+      /// Construct an expression from a column
+
+      /// Construct an expression, which has a term with \c c variable
+      /// and 1.0 coefficient.
+      Expr(const Col &c) : const_comp(0) {
+        typedef std::map<int, Value>::value_type pair_type;
+        comps.insert(pair_type(id(c), 1));
+      }
+      /// Construct an expression from a constant
+
+      /// Construct an expression, which's constant component is \c v.
+      ///
+      Expr(const Value &v) : const_comp(v) {}
+      /// Returns the coefficient of the column
+      Value operator[](const Col& c) const {
+        std::map<int, Value>::const_iterator it=comps.find(id(c));
+        if (it != comps.end()) {
+          return it->second;
+        } else {
+          return 0;
+        }
+      }
+      /// Returns the coefficient of the column
+      Value& operator[](const Col& c) {
+        return comps[id(c)];
+      }
+      /// Sets the coefficient of the column
+      void set(const Col &c, const Value &v) {
+        if (v != 0.0) {
+          typedef std::map<int, Value>::value_type pair_type;
+          comps.insert(pair_type(id(c), v));
+        } else {
+          comps.erase(id(c));
+        }
+      }
+      /// Returns the constant component of the expression
+      Value& operator*() { return const_comp; }
+      /// Returns the constant component of the expression
+      const Value& operator*() const { return const_comp; }
+      /// \brief Removes the coefficients which's absolute value does
+      /// not exceed \c epsilon. It also sets to zero the constant
+      /// component, if it does not exceed epsilon in absolute value.
+      void simplify(Value epsilon = 0.0) {
+        std::map<int, Value>::iterator it=comps.begin();
+        while (it != comps.end()) {
+          std::map<int, Value>::iterator jt=it;
+          ++jt;
+          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
+          it=jt;
+        }
+        if (std::fabs(const_comp) <= epsilon) const_comp = 0;
+      }
+
+      void simplify(Value epsilon = 0.0) const {
+        const_cast<Expr*>(this)->simplify(epsilon);
+      }
+
+      ///Sets all coefficients and the constant component to 0.
+      void clear() {
+        comps.clear();
+        const_comp=0;
+      }
+
+      ///Compound assignment
+      Expr &operator+=(const Expr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]+=it->second;
+        const_comp+=e.const_comp;
+        return *this;
+      }
+      ///Compound assignment
+      Expr &operator-=(const Expr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]-=it->second;
+        const_comp-=e.const_comp;
+        return *this;
+      }
+      ///Multiply with a constant
+      Expr &operator*=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second*=v;
+        const_comp*=v;
+        return *this;
+      }
+      ///Division with a constant
+      Expr &operator/=(const Value &c) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second/=c;
+        const_comp/=c;
+        return *this;
+      }
+
+      ///Iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * primal(i);
+      ///\endcode
+      class CoeffIt {
+      private:
+
+        std::map<int, Value>::iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        CoeffIt(Expr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the column of the term
+        operator Col() const {
+          return colFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        Value& operator*() { return _it->second; }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        CoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+      /// Const iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
+      ///  s+=*i * primal(i);
+      ///\endcode
+      class ConstCoeffIt {
+      private:
+
+        std::map<int, Value>::const_iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        ConstCoeffIt(const Expr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the column of the term
+        operator Col() const {
+          return colFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        ConstCoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+    };
+
+    ///Linear constraint
+
+    ///This data stucture represents a linear constraint in the LP.
+    ///Basically it is a linear expression with a lower or an upper bound
+    ///(or both). These parts of the constraint can be obtained by the member
+    ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
+    ///respectively.
+    ///There are two ways to construct a constraint.
+    ///- You can set the linear expression and the bounds directly
+    ///  by the functions above.
+    ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
+    ///  are defined between expressions, or even between constraints whenever
+    ///  it makes sense. Therefore if \c e and \c f are linear expressions and
+    ///  \c s and \c t are numbers, then the followings are valid expressions
+    ///  and thus they can be used directly e.g. in \ref addRow() whenever
+    ///  it makes sense.
+    ///\code
+    ///  e<=s
+    ///  e<=f
+    ///  e==f
+    ///  s<=e<=t
+    ///  e>=t
+    ///\endcode
+    ///\warning The validity of a constraint is checked only at run
+    ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
+    ///compile, but will fail an assertion.
+    class Constr
+    {
+    public:
+      typedef LpBase::Expr Expr;
+      typedef Expr::Key Key;
+      typedef Expr::Value Value;
+
+    protected:
+      Expr _expr;
+      Value _lb,_ub;
+    public:
+      ///\e
+      Constr() : _expr(), _lb(NaN), _ub(NaN) {}
+      ///\e
+      Constr(Value lb, const Expr &e, Value ub) :
+        _expr(e), _lb(lb), _ub(ub) {}
+      Constr(const Expr &e) :
+        _expr(e), _lb(NaN), _ub(NaN) {}
+      ///\e
+      void clear()
+      {
+        _expr.clear();
+        _lb=_ub=NaN;
+      }
+
+      ///Reference to the linear expression
+      Expr &expr() { return _expr; }
+      ///Cont reference to the linear expression
+      const Expr &expr() const { return _expr; }
+      ///Reference to the lower bound.
+
+      ///\return
+      ///- \ref INF "INF": the constraint is lower unbounded.
+      ///- \ref NaN "NaN": lower bound has not been set.
+      ///- finite number: the lower bound
+      Value &lowerBound() { return _lb; }
+      ///The const version of \ref lowerBound()
+      const Value &lowerBound() const { return _lb; }
+      ///Reference to the upper bound.
+
+      ///\return
+      ///- \ref INF "INF": the constraint is upper unbounded.
+      ///- \ref NaN "NaN": upper bound has not been set.
+      ///- finite number: the upper bound
+      Value &upperBound() { return _ub; }
+      ///The const version of \ref upperBound()
+      const Value &upperBound() const { return _ub; }
+      ///Is the constraint lower bounded?
+      bool lowerBounded() const {
+        return _lb != -INF && !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 LpBase* _newSolver() const = 0;
+    virtual LpBase* _cloneSolver() const = 0;
+
+    virtual int _addColId(int col) { return cols.addIndex(col); }
+    virtual int _addRowId(int row) { return rows.addIndex(row); }
+
+    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
+    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
+
+    virtual int _addCol() = 0;
+    virtual int _addRow() = 0;
+
+    virtual void _eraseCol(int col) = 0;
+    virtual void _eraseRow(int row) = 0;
+
+    virtual void _getColName(int col, std::string& name) const = 0;
+    virtual void _setColName(int col, const std::string& name) = 0;
+    virtual int _colByName(const std::string& name) const = 0;
+
+    virtual void _getRowName(int row, std::string& name) const = 0;
+    virtual void _setRowName(int row, const std::string& name) = 0;
+    virtual int _rowByName(const std::string& name) const = 0;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
+    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
+    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
+
+    virtual void _setCoeff(int row, int col, Value value) = 0;
+    virtual Value _getCoeff(int row, int col) const = 0;
+
+    virtual void _setColLowerBound(int i, Value value) = 0;
+    virtual Value _getColLowerBound(int i) const = 0;
+
+    virtual void _setColUpperBound(int i, Value value) = 0;
+    virtual Value _getColUpperBound(int i) const = 0;
+
+    virtual void _setRowLowerBound(int i, Value value) = 0;
+    virtual Value _getRowLowerBound(int i) const = 0;
+
+    virtual void _setRowUpperBound(int i, Value value) = 0;
+    virtual Value _getRowUpperBound(int i) const = 0;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
+    virtual void _getObjCoeffs(InsertIterator b) const = 0;
+
+    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
+    virtual Value _getObjCoeff(int i) const = 0;
+
+    virtual void _setSense(Sense) = 0;
+    virtual Sense _getSense() const = 0;
+
+    virtual void _clear() = 0;
+
+    virtual const char* _solverName() const = 0;
+
+    //Own protected stuff
+
+    //Constant component of the objective function
+    Value obj_const_comp;
+
+    LpBase() : rows(), cols(), obj_const_comp(0) {}
+
+  public:
+
+    /// Virtual destructor
+    virtual ~LpBase() {}
+
+    ///Creates a new LP problem
+    LpBase* newSolver() {return _newSolver();}
+    ///Makes a copy of the LP problem
+    LpBase* cloneSolver() {return _cloneSolver();}
+
+    ///Gives back the name of the solver.
+    const char* solverName() const {return _solverName();}
+
+    ///\name Build up and modify the LP
+
+    ///@{
+
+    ///Add a new empty column (i.e a new variable) to the LP
+    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
+
+    ///\brief Adds several new columns (i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument and fills
+    ///its elements with new columns (i.e. variables)
+    ///\param t can be
+    ///- a standard STL compatible iterable container with
+    ///\ref Col as its \c values_type like
+    ///\code
+    ///std::vector<LpBase::Col>
+    ///std::list<LpBase::Col>
+    ///\endcode
+    ///- a standard STL compatible iterable container with
+    ///\ref Col as its \c mapped_type like
+    ///\code
+    ///std::map<AnyType,LpBase::Col>
+    ///\endcode
+    ///- an iterable lemon \ref concepts::WriteMap "write map" like
+    ///\code
+    ///ListGraph::NodeMap<LpBase::Col>
+    ///ListGraph::ArcMap<LpBase::Col>
+    ///\endcode
+    ///\return The number of the created column.
+#ifdef DOXYGEN
+    template<class T>
+    int addColSet(T &t) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,int>::type
+    addColSet(T &t,dummy<0> = 0) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       int>::type
+    addColSet(T &t,dummy<1> = 1) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        i->second=addCol();
+        s++;
+      }
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       int>::type
+    addColSet(T &t,dummy<2> = 2) {
+      int s=0;
+      for(typename T::MapIt i(t); i!=INVALID; ++i)
+        {
+          i.set(addCol());
+          s++;
+        }
+      return s;
+    }
+#endif
+
+    ///Set a column (i.e a dual constraint) of the LP
+
+    ///\param c is the column to be modified
+    ///\param e is a dual linear expression (see \ref DualExpr)
+    ///a better one.
+    void col(Col c, const DualExpr &e) {
+      e.simplify();
+      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), 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=addRow();
+      row(r,l,e,u);
+      return r;
+    }
+
+    ///Add a new row (i.e a new constraint) to the LP
+
+    ///\param c is a linear expression (see \ref Constr)
+    ///\return The created row.
+    Row addRow(const Constr &c) {
+      Row r=addRow();
+      row(r,c);
+      return r;
+    }
+    ///Erase a column (i.e a variable) from the LP
+
+    ///\param c is the column to be deleted
+    void erase(Col c) {
+      _eraseCol(cols(id(c)));
+      _eraseColId(cols(id(c)));
+    }
+    ///Erase a row (i.e a constraint) from the LP
+
+    ///\param r is the row to be deleted
+    void erase(Row r) {
+      _eraseRow(rows(id(r)));
+      _eraseRowId(rows(id(r)));
+    }
+
+    /// Get the name of a column
+
+    ///\param c is the coresponding column
+    ///\return The name of the colunm
+    std::string colName(Col c) const {
+      std::string name;
+      _getColName(cols(id(c)), name);
+      return name;
+    }
+
+    /// Set the name of a column
+
+    ///\param c is the coresponding column
+    ///\param name The name to be given
+    void colName(Col c, const std::string& name) {
+      _setColName(cols(id(c)), name);
+    }
+
+    /// Get the column by its name
+
+    ///\param name The name of the column
+    ///\return the proper column or \c INVALID
+    Col colByName(const std::string& name) const {
+      int k = _colByName(name);
+      return k != -1 ? Col(cols[k]) : Col(INVALID);
+    }
+
+    /// Get the name of a row
+
+    ///\param r is the coresponding row
+    ///\return The name of the row
+    std::string rowName(Row r) const {
+      std::string name;
+      _getRowName(rows(id(r)), name);
+      return name;
+    }
+
+    /// Set the name of a row
+
+    ///\param r is the coresponding row
+    ///\param name The name to be given
+    void rowName(Row r, const std::string& name) {
+      _setRowName(rows(id(r)), name);
+    }
+
+    /// Get the row by its name
+
+    ///\param name The name of the row
+    ///\return the proper row or \c INVALID
+    Row rowByName(const std::string& name) const {
+      int k = _rowByName(name);
+      return k != -1 ? Row(rows[k]) : Row(INVALID);
+    }
+
+    /// Set an element of the coefficient matrix of the LP
+
+    ///\param r is the row of the element to be modified
+    ///\param c is the column of the element to be modified
+    ///\param val is the new value of the coefficient
+    void coeff(Row r, Col c, Value val) {
+      _setCoeff(rows(id(r)),cols(id(c)), val);
+    }
+
+    /// Get an element of the coefficient matrix of the LP
+
+    ///\param r is the row of the element
+    ///\param c is the column of the element
+    ///\return the corresponding coefficient
+    Value coeff(Row r, Col c) const {
+      return _getCoeff(rows(id(r)),cols(id(c)));
+    }
+
+    /// Set the lower bound of a column (i.e a variable)
+
+    /// The lower bound of a variable (column) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void colLowerBound(Col c, Value value) {
+      _setColLowerBound(cols(id(c)),value);
+    }
+
+    /// Get the lower bound of a column (i.e a variable)
+
+    /// This function returns the lower bound for column (variable) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The lower bound for column \c c
+    Value colLowerBound(Col c) const {
+      return _getColLowerBound(cols(id(c)));
+    }
+
+    ///\brief Set the lower bound of  several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    ///The lower bound of a variable (column) has to be given by an
+    ///extended number of type Value, i.e. a finite number of type
+    ///Value or -\ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colLowerBound(T &t, Value value) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,void>::type
+    colLowerBound(T &t, Value value,dummy<0> = 0) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colLowerBound(*i, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       void>::type
+    colLowerBound(T &t, Value value,dummy<1> = 1) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colLowerBound(i->second, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       void>::type
+    colLowerBound(T &t, Value value,dummy<2> = 2) {
+      for(typename T::MapIt i(t); i!=INVALID; ++i){
+        colLowerBound(*i, value);
+      }
+    }
+#endif
+
+    /// Set the upper bound of a column (i.e a variable)
+
+    /// The upper bound of a variable (column) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    void colUpperBound(Col c, Value value) {
+      _setColUpperBound(cols(id(c)),value);
+    };
+
+    /// Get the upper bound of a column (i.e a variable)
+
+    /// This function returns the upper bound for column (variable) \c c
+    /// (this might be \ref INF as well).
+    /// \return The upper bound for column \c c
+    Value colUpperBound(Col c) const {
+      return _getColUpperBound(cols(id(c)));
+    }
+
+    ///\brief Set the upper bound of  several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    ///The upper bound of a variable (column) has to be given by an
+    ///extended number of type Value, i.e. a finite number of type
+    ///Value or \ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colUpperBound(T &t, Value value) { return 0;}
+#else
+    template<class 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); }
+
+    ///Clears the problem
+    void clear() { _clear(); }
+
+    ///@}
+
+  };
+
+  /// Addition
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(a);
+    tmp+=b;
+    return tmp;
+  }
+  ///Substraction
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(a);
+    tmp-=b;
+    return tmp;
+  }
+  ///Multiply with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
+    LpBase::Expr tmp(a);
+    tmp*=b;
+    return tmp;
+  }
+
+  ///Multiply with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(b);
+    tmp*=a;
+    return tmp;
+  }
+  ///Divide with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
+    LpBase::Expr tmp(a);
+    tmp/=b;
+    return tmp;
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, f - e, LpBase::INF);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Value &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(e, f, LpBase::NaN);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(- LpBase::INF, e, f);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, e - f, LpBase::INF);
+  }
+
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Value &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(LpBase::NaN, f, e);
+  }
+
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(f, e, LpBase::INF);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator==(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(f, e, f);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator==(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, f - e, 0);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Value &n,
+                                   const LpBase::Constr &c) {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(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 {
+      ///Feasible solution hasn't been found (but may exist).
+      UNDEFINED = 0,
+      ///The problem has no feasible solution
+      INFEASIBLE = 1,
+      ///Feasible solution found
+      FEASIBLE = 2,
+      ///Optimal solution exists and found
+      OPTIMAL = 3,
+      ///The cost function is unbounded
+      UNBOUNDED = 4
+    };
+
+    ///The basis status of variables
+    enum VarStatus {
+      /// The variable is in the basis
+      BASIC, 
+      /// The variable is free, but not basic
+      FREE,
+      /// The variable has active lower bound 
+      LOWER,
+      /// The variable has active upper bound
+      UPPER,
+      /// The variable is non-basic and fixed
+      FIXED
+    };
+
+  protected:
+
+    virtual SolveExitStatus _solve() = 0;
+
+    virtual Value _getPrimal(int i) const = 0;
+    virtual Value _getDual(int i) const = 0;
+
+    virtual Value _getPrimalRay(int i) const = 0;
+    virtual Value _getDualRay(int i) const = 0;
+
+    virtual Value _getPrimalValue() const = 0;
+
+    virtual VarStatus _getColStatus(int i) const = 0;
+    virtual VarStatus _getRowStatus(int i) const = 0;
+
+    virtual ProblemType _getPrimalType() const = 0;
+    virtual ProblemType _getDualType() const = 0;
+
+  public:
+
+    ///\name Solve the LP
+
+    ///@{
+
+    ///\e Solve the LP problem at hand
+    ///
+    ///\return The result of the optimization procedure. Possible
+    ///values and their meanings can be found in the documentation of
+    ///\ref SolveExitStatus.
+    SolveExitStatus solve() { return _solve(); }
+
+    ///@}
+
+    ///\name Obtain the solution
+
+    ///@{
+
+    /// The type of the primal problem
+    ProblemType primalType() const {
+      return _getPrimalType();
+    }
+
+    /// The type of the dual problem
+    ProblemType dualType() const {
+      return _getDualType();
+    }
+
+    /// Return the primal value of the column
+
+    /// Return the primal value of the column.
+    /// \pre The problem is solved.
+    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
+
+    /// Return the primal value of the expression
+
+    /// Return the primal value of the expression, i.e. the dot
+    /// product of the primal solution and the expression.
+    /// \pre The problem is solved.
+    Value primal(const Expr& e) const {
+      double res = *e;
+      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
+        res += *c * primal(c);
+      }
+      return res;
+    }
+    /// Returns a component of the primal ray
+    
+    /// The primal ray is solution of the modified primal problem,
+    /// where we change each finite bound to 0, and we looking for a
+    /// negative objective value in case of minimization, and positive
+    /// objective value for maximization. If there is such solution,
+    /// that proofs the unsolvability of the dual problem, and if a
+    /// feasible primal solution exists, then the unboundness of
+    /// primal problem.
+    ///
+    /// \pre The problem is solved and the dual problem is infeasible.
+    /// \note Some solvers does not provide primal ray calculation
+    /// functions.
+    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
+
+    /// Return the dual value of the row
+
+    /// Return the dual value of the row.
+    /// \pre The problem is solved.
+    Value dual(Row r) const { return _getDual(rows(id(r))); }
+
+    /// Return the dual value of the dual expression
+
+    /// Return the dual value of the dual expression, i.e. the dot
+    /// product of the dual solution and the dual expression.
+    /// \pre The problem is solved.
+    Value dual(const DualExpr& e) const {
+      double res = 0.0;
+      for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
+        res += *r * dual(r);
+      }
+      return res;
+    }
+
+    /// Returns a component of the dual ray
+    
+    /// The dual ray is solution of the modified primal problem, where
+    /// we change each finite bound to 0 (i.e. the objective function
+    /// coefficients in the primal problem), and we looking for a
+    /// ositive objective value. If there is such solution, that
+    /// proofs the unsolvability of the primal problem, and if a
+    /// feasible dual solution exists, then the unboundness of
+    /// dual problem.
+    ///
+    /// \pre The problem is solved and the primal problem is infeasible.
+    /// \note Some solvers does not provide dual ray calculation
+    /// functions.
+    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
+
+    /// Return the basis status of the column
+
+    /// \see VarStatus
+    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
+
+    /// Return the basis status of the row
+
+    /// \see VarStatus
+    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
+
+    ///The value of the objective function
+
+    ///\return
+    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
+    /// of the primal problem, depending on whether we minimize or maximize.
+    ///- \ref NaN if no primal solution is found.
+    ///- The (finite) objective value if an optimal solution is found.
+    Value primal() const { return _getPrimalValue()+obj_const_comp;}
+    ///@}
+
+    LpSolver* newSolver() {return _newSolver();}
+    LpSolver* cloneSolver() {return _cloneSolver();}
+
+  protected:
+
+    virtual LpSolver* _newSolver() const = 0;
+    virtual LpSolver* _cloneSolver() const = 0;
+  };
+
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Common base class for MIP solvers
+  ///
+  /// This class is an abstract base class for MIP solvers. This class
+  /// provides a full interface for set and modify an MIP problem,
+  /// solve it and retrieve the solution. You can use one of the
+  /// descendants as a concrete implementation, or the \c Lp
+  /// default MIP solver. However, if you would like to handle MIP
+  /// solvers as reference or pointer in a generic way, you can use
+  /// this class directly.
+  class MipSolver : virtual public LpBase {
+  public:
+
+    /// The problem types for MIP problems
+    enum ProblemType {
+      ///Feasible solution hasn't been found (but may exist).
+      UNDEFINED = 0,
+      ///The problem has no feasible solution
+      INFEASIBLE = 1,
+      ///Feasible solution found
+      FEASIBLE = 2,
+      ///Optimal solution exists and found
+      OPTIMAL = 3,
+      ///The cost function is unbounded
+      ///
+      ///The Mip or at least the relaxed problem is unbounded
+      UNBOUNDED = 4
+    };
+
+    ///\name Solve the MIP
+
+    ///@{
+
+    /// Solve the MIP problem at hand
+    ///
+    ///\return The result of the optimization procedure. Possible
+    ///values and their meanings can be found in the documentation of
+    ///\ref SolveExitStatus.
+    SolveExitStatus solve() { return _solve(); }
+
+    ///@}
+
+    ///\name Setting column type
+    ///@{
+
+    ///Possible variable (column) types (e.g. real, integer, binary etc.)
+    enum ColTypes {
+      ///Continuous variable (default)
+      REAL = 0,
+      ///Integer variable
+      INTEGER = 1
+    };
+
+    ///Sets the type of the given column to the given type
+
+    ///Sets the type of the given column to the given type.
+    ///
+    void colType(Col c, ColTypes col_type) {
+      _setColType(cols(id(c)),col_type);
+    }
+
+    ///Gives back the type of the column.
+
+    ///Gives back the type of the column.
+    ///
+    ColTypes colType(Col c) const {
+      return _getColType(cols(id(c)));
+    }
+    ///@}
+
+    ///\name Obtain the solution
+
+    ///@{
+
+    /// The type of the MIP problem
+    ProblemType type() const {
+      return _getType();
+    }
+
+    /// Return the value of the row in the solution
+
+    ///  Return the value of the row in the solution.
+    /// \pre The problem is solved.
+    Value sol(Col c) const { return _getSol(cols(id(c))); }
+
+    /// Return the value of the expression in the solution
+
+    /// Return the value of the expression in the solution, i.e. the
+    /// dot product of the solution and the expression.
+    /// \pre The problem is solved.
+    Value sol(const Expr& e) const {
+      double res = *e;
+      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
+        res += *c * sol(c);
+      }
+      return res;
+    }
+    ///The value of the objective function
+    
+    ///\return
+    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
+    /// of the problem, depending on whether we minimize or maximize.
+    ///- \ref NaN if no primal solution is found.
+    ///- The (finite) objective value if an optimal solution is found.
+    Value solValue() const { return _getSolValue()+obj_const_comp;}
+    ///@}
+
+  protected:
+
+    virtual SolveExitStatus _solve() = 0;
+    virtual ColTypes _getColType(int col) const = 0;
+    virtual void _setColType(int col, ColTypes col_type) = 0;
+    virtual ProblemType _getType() const = 0;
+    virtual Value _getSol(int i) const = 0;
+    virtual Value _getSolValue() const = 0;
+
+  public:
+
+    MipSolver* newSolver() {return _newSolver();}
+    MipSolver* cloneSolver() {return _cloneSolver();}
+
+  protected:
+
+    virtual MipSolver* _newSolver() const = 0;
+    virtual MipSolver* _cloneSolver() const = 0;
+  };
+
+
+
+} //namespace lemon
+
+#endif //LEMON_LP_BASE_H
Index: lemon/lp_skeleton.cc
===================================================================
--- lemon/lp_skeleton.cc	(revision 459)
+++ lemon/lp_skeleton.cc	(revision 459)
@@ -0,0 +1,134 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/lp_skeleton.h>
+
+///\file
+///\brief A skeleton file to implement LP solver interfaces
+namespace lemon {
+
+  int SkeletonSolverBase::_addCol()
+  {
+    return ++col_num;
+  }
+
+  int SkeletonSolverBase::_addRow()
+  {
+    return ++row_num;
+  }
+
+  void SkeletonSolverBase::_eraseCol(int) {}
+  void SkeletonSolverBase::_eraseRow(int) {}
+
+  void SkeletonSolverBase::_getColName(int, std::string &) const {}
+  void SkeletonSolverBase::_setColName(int, const std::string &) {}
+  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
+
+  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
+  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
+  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
+
+  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
+
+  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
+
+  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
+  { return 0; }
+
+  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
+
+  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setSense(Sense) {}
+  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
+  { return MIN; }
+
+  void SkeletonSolverBase::_clear() {
+    row_num = col_num = 0;
+  }
+
+  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
+
+  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
+
+  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
+
+  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
+  { return UNDEFINED; }
+
+  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
+  { return UNDEFINED; }
+
+  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
+  { return BASIC; }
+
+  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
+  { return BASIC; }
+
+  LpSkeleton* LpSkeleton::_newSolver() const
+  { return static_cast<LpSkeleton*>(0); }
+
+  LpSkeleton* LpSkeleton::_cloneSolver() const
+  { return static_cast<LpSkeleton*>(0); }
+
+  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
+
+  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
+  { return SOLVED; }
+
+  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
+  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
+
+  MipSkeleton::ProblemType MipSkeleton::_getType() const
+  { return UNDEFINED; }
+
+  MipSkeleton* MipSkeleton::_newSolver() const
+  { return static_cast<MipSkeleton*>(0); }
+
+  MipSkeleton* MipSkeleton::_cloneSolver() const
+  { return static_cast<MipSkeleton*>(0); }
+
+  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
+
+} //namespace lemon
+
Index: lemon/lp_skeleton.h
===================================================================
--- lemon/lp_skeleton.h	(revision 459)
+++ lemon/lp_skeleton.h	(revision 459)
@@ -0,0 +1,229 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_SKELETON
+#define LEMON_LP_SKELETON
+
+#include <lemon/lp_base.h>
+
+///\file
+///\brief A skeleton file to implement LP solver interfaces
+namespace lemon {
+
+  ///A skeleton class to implement LP solver interfaces
+  class SkeletonSolverBase : public virtual LpBase {
+    int col_num,row_num;
+
+  protected:
+
+    SkeletonSolverBase()
+      : col_num(-1), row_num(-1) {}
+
+    /// \e
+    virtual int _addCol();
+    /// \e
+    virtual int _addRow();
+    /// \e
+    virtual void _eraseCol(int i);
+    /// \e
+    virtual void _eraseRow(int i);
+
+    /// \e
+    virtual void _getColName(int col, std::string& name) const;
+    /// \e
+    virtual void _setColName(int col, const std::string& name);
+    /// \e
+    virtual int _colByName(const std::string& name) const;
+
+    /// \e
+    virtual void _getRowName(int row, std::string& name) const;
+    /// \e
+    virtual void _setRowName(int row, const std::string& name);
+    /// \e
+    virtual int _rowByName(const std::string& name) const;
+
+    /// \e
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+    /// \e
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    /// Set one element of the coefficient matrix
+    virtual void _setCoeff(int row, int col, Value value);
+
+    /// Get one element of the coefficient matrix
+    virtual Value _getCoeff(int row, int col) const;
+
+    /// The lower bound of a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual void _setColLowerBound(int i, Value value);
+    /// \e
+
+    /// The lower bound of a variable (column) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual Value _getColLowerBound(int i) const;
+
+    /// The upper bound of a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual void _setColUpperBound(int i, Value value);
+    /// \e
+
+    /// The upper bound of a variable (column) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual Value _getColUpperBound(int i) const;
+
+    /// The lower bound of a constraint (row) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual void _setRowLowerBound(int i, Value value);
+    /// \e
+
+    /// The lower bound of a constraint (row) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual Value _getRowLowerBound(int i) const;
+
+    /// The upper bound of a constraint (row) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual void _setRowUpperBound(int i, Value value);
+    /// \e
+
+    /// The upper bound of a constraint (row) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual Value _getRowUpperBound(int i) const;
+
+    /// \e
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    /// \e
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    /// \e
+    virtual Value _getObjCoeff(int i) const;
+
+    ///\e
+    virtual void _setSense(Sense);
+    ///\e
+    virtual Sense _getSense() const;
+
+    ///\e
+    virtual void _clear();
+
+  };
+
+  /// \brief Interface for a skeleton LP solver
+  ///
+  /// This class implements an interface for a skeleton LP solver.
+  ///\ingroup lp_group
+  class LpSkeleton : public SkeletonSolverBase, public LpSolver {
+  public:
+    LpSkeleton() : SkeletonSolverBase(), LpSolver() {}
+
+  protected:
+
+    ///\e
+    virtual SolveExitStatus _solve();
+
+    ///\e
+    virtual Value _getPrimal(int i) const;
+    ///\e
+    virtual Value _getDual(int i) const;
+
+    ///\e
+    virtual Value _getPrimalValue() const;
+
+    ///\e
+    virtual Value _getPrimalRay(int i) const;
+    ///\e
+    virtual Value _getDualRay(int i) const;
+
+    ///\e
+    virtual ProblemType _getPrimalType() const;
+    ///\e
+    virtual ProblemType _getDualType() const;
+
+    ///\e
+    virtual VarStatus _getColStatus(int i) const;
+    ///\e
+    virtual VarStatus _getRowStatus(int i) const;
+
+    ///\e
+    virtual LpSkeleton* _newSolver() const;
+    ///\e
+    virtual LpSkeleton* _cloneSolver() const;
+    ///\e
+    virtual const char* _solverName() const;
+
+  };
+
+  /// \brief Interface for a skeleton MIP solver
+  ///
+  /// This class implements an interface for a skeleton MIP solver.
+  ///\ingroup lp_group
+  class MipSkeleton : public SkeletonSolverBase, public MipSolver {
+  public:
+    MipSkeleton() : SkeletonSolverBase(), MipSolver() {}
+
+  protected:
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual SolveExitStatus _solve();
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual Value _getSol(int i) const;
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual Value _getSolValue() const;
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual ProblemType _getType() const;
+
+    ///\e
+    virtual MipSkeleton* _newSolver() const;
+
+    ///\e
+    virtual MipSkeleton* _cloneSolver() const;
+    ///\e
+    virtual const char* _solverName() const;
+
+  };
+
+} //namespace lemon
+
+#endif // LEMON_LP_SKELETON
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 314)
+++ lemon/maps.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/math.h
===================================================================
--- lemon/math.h	(revision 209)
+++ lemon/math.h	(revision 511)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -56,4 +56,13 @@
   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;
+    }
 
   /// @}
Index: lemon/max_matching.h
===================================================================
--- lemon/max_matching.h	(revision 330)
+++ lemon/max_matching.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -417,5 +417,5 @@
     /// \ref init(), \ref greedyInit() or \ref matchingInit()
     /// functions first, then you can start the algorithm with the \ref
-    /// startParse() or startDense() functions.
+    /// startSparse() or startDense() functions.
 
     ///@{
Index: lemon/nauty_reader.h
===================================================================
--- lemon/nauty_reader.h	(revision 359)
+++ lemon/nauty_reader.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/path.h
===================================================================
--- lemon/path.h	(revision 313)
+++ lemon/path.h	(revision 517)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -930,7 +930,6 @@
 
     template <typename Target, typename Source,
-              bool buildEnable = BuildTagIndicator<Target>::value,
-              bool revEnable = RevPathTagIndicator<Source>::value>
-    struct PathCopySelector {
+              bool buildEnable = BuildTagIndicator<Target>::value>
+    struct PathCopySelectorForward {
       static void copy(Target& target, const Source& source) {
         target.clear();
@@ -942,5 +941,14 @@
 
     template <typename Target, typename Source>
-    struct PathCopySelector<Target, Source, false, true> {
+    struct PathCopySelectorForward<Target, Source, true> {
+      static void copy(Target& target, const Source& source) {
+        target.clear();
+        target.build(source);
+      }
+    };
+
+    template <typename Target, typename Source,
+              bool buildEnable = BuildTagIndicator<Target>::value>
+    struct PathCopySelectorBackward {
       static void copy(Target& target, const Source& source) {
         target.clear();
@@ -952,17 +960,25 @@
 
     template <typename Target, typename Source>
-    struct PathCopySelector<Target, Source, true, false> {
-      static void copy(Target& target, const Source& source) {
-        target.clear();
-        target.build(source);
-      }
-    };
-
-    template <typename Target, typename Source>
-    struct PathCopySelector<Target, Source, true, true> {
+    struct PathCopySelectorBackward<Target, Source, true> {
       static void copy(Target& target, const Source& source) {
         target.clear();
         target.buildRev(source);
       }
+    };
+
+    
+    template <typename Target, typename Source,
+              bool revEnable = RevPathTagIndicator<Source>::value>
+    struct PathCopySelector {
+      static void copy(Target& target, const Source& source) {
+        PathCopySelectorForward<Target, Source>::copy(target, source);
+      }      
+    };
+
+    template <typename Target, typename Source>
+    struct PathCopySelector<Target, Source, true> {
+      static void copy(Target& target, const Source& source) {
+        PathCopySelectorBackward<Target, Source>::copy(target, source);
+      }      
     };
 
Index: lemon/preflow.h
===================================================================
--- lemon/preflow.h	(revision 393)
+++ lemon/preflow.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -367,5 +367,5 @@
     /// \pre Either \ref run() or \ref init() must be called before
     /// using this function.
-    const Elevator& elevator() {
+    const Elevator& elevator() const {
       return *_level;
     }
@@ -919,5 +919,5 @@
     /// \pre Either \ref run() or \ref init() must be called before
     /// using this function.
-    const FlowMap& flowMap() {
+    const FlowMap& flowMap() const {
       return *_flow;
     }
Index: lemon/radix_sort.h
===================================================================
--- lemon/radix_sort.h	(revision 444)
+++ lemon/radix_sort.h	(revision 444)
@@ -0,0 +1,487 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef RADIX_SORT_H
+#define RADIX_SORT_H
+
+/// \ingroup auxalg
+/// \file
+/// \brief Radix sort
+///
+/// Linear time sorting algorithms
+
+#include <vector>
+#include <limits>
+#include <iterator>
+#include <algorithm>
+
+namespace lemon {
+
+  namespace _radix_sort_bits {
+
+    template <typename Value>
+    struct Identity {
+      const Value& operator()(const Value& val) {
+        return val;
+      }
+    };
+
+
+    template <typename Value, typename Iterator, typename Functor>
+    Iterator radixSortPartition(Iterator first, Iterator last,
+                                Functor functor, Value mask) {
+      while (first != last && !(functor(*first) & mask)) {
+        ++first;
+      }
+      if (first == last) {
+        return first;
+      }
+      --last;
+      while (first != last && (functor(*last) & mask)) {
+        --last;
+      }
+      if (first == last) {
+        return first;
+      }
+      std::iter_swap(first, last);
+      ++first;
+      if (!(first < last)) {
+        return first;
+      }
+      while (true) {
+        while (!(functor(*first) & mask)) {
+          ++first;
+        }
+        --last;
+        while (functor(*last) & mask) {
+          --last;
+        }
+        if (!(first < last)) {
+          return first;
+        }
+        std::iter_swap(first, last);
+        ++first;
+      }
+    }
+
+    template <typename Iterator, typename Functor>
+    Iterator radixSortSignPartition(Iterator first, Iterator last,
+                                    Functor functor) {
+      while (first != last && functor(*first) < 0) {
+        ++first;
+      }
+      if (first == last) {
+        return first;
+      }
+      --last;
+      while (first != last && functor(*last) >= 0) {
+        --last;
+      }
+      if (first == last) {
+        return first;
+      }
+      std::iter_swap(first, last);
+      ++first;
+      if (!(first < last)) {
+        return first;
+      }
+      while (true) {
+        while (functor(*first) < 0) {
+          ++first;
+        }
+        --last;
+        while (functor(*last) >= 0) {
+          --last;
+        }
+        if (!(first < last)) {
+          return first;
+        }
+        std::iter_swap(first, last);
+        ++first;
+      }
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixIntroSort(Iterator first, Iterator last,
+                        Functor functor, Value mask) {
+      while (mask != 0 && last - first > 1) {
+        Iterator cut = radixSortPartition(first, last, functor, mask);
+        mask >>= 1;
+        radixIntroSort(first, cut, functor, mask);
+        first = cut;
+      }
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixSignedSort(Iterator first, Iterator last, Functor functor) {
+
+      Iterator cut = radixSortSignPartition(first, last, functor);
+
+      Value mask;
+      int max_digit;
+      Iterator it;
+
+      mask = ~0; max_digit = 0;
+      for (it = first; it != cut; ++it) {
+        while ((mask & functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1;
+        }
+      }
+      radixIntroSort(first, cut, functor, 1 << max_digit);
+
+      mask = 0; max_digit = 0;
+      for (it = cut; it != last; ++it) {
+        while ((mask | functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1; mask |= 1;
+        }
+      }
+      radixIntroSort(cut, last, functor, 1 << max_digit);
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixUnsignedSort(Iterator first, Iterator last, Functor functor) {
+
+      Value mask = 0;
+      int max_digit = 0;
+
+      Iterator it;
+      for (it = first; it != last; ++it) {
+        while ((mask | functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1; mask |= 1;
+        }
+      }
+      radixIntroSort(first, last, functor, 1 << max_digit);
+    }
+
+
+    template <typename Value,
+              bool sign = std::numeric_limits<Value>::is_signed >
+    struct RadixSortSelector {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        radixSignedSort<Value>(first, last, functor);
+      }
+    };
+
+    template <typename Value>
+    struct RadixSortSelector<Value, false> {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        radixUnsignedSort<Value>(first, last, functor);
+      }
+    };
+
+  }
+
+  /// \ingroup auxalg
+  ///
+  /// \brief Sorts the STL compatible range into ascending order.
+  ///
+  /// The \c radixSort sorts an STL compatible range into ascending
+  /// order.  The radix sort algorithm can sort items which are mapped
+  /// to integers with an adaptable unary function \c functor and the
+  /// order will be ascending according to these mapped values.
+  ///
+  /// It is also possible to use a normal function instead
+  /// of the functor object. If the functor is not given it will use
+  /// the identity function instead.
+  ///
+  /// This is a special quick sort algorithm where the pivot
+  /// values to split the items are choosen to be \f$ 2^k \f$ for each \c k.
+  /// Therefore, the time complexity of the
+  /// algorithm is \f$ O(\log(c)n) \f$ and it uses \f$ O(\log(c)) \f$,
+  /// additional space, where \c c is the maximal value and \c n is the
+  /// number of the items in the container.
+  ///
+  /// \param first The begin of the given range.
+  /// \param last The end of the given range.
+  /// \param functor An adaptible unary function or a normal function
+  /// which maps the items to any integer type which can be either
+  /// signed or unsigned.
+  ///
+  /// \sa stableRadixSort()
+  template <typename Iterator, typename Functor>
+  void radixSort(Iterator first, Iterator last, Functor functor) {
+    using namespace _radix_sort_bits;
+    typedef typename Functor::result_type Value;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator>
+  void radixSort(Iterator first, Iterator last) {
+    using namespace _radix_sort_bits;
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    RadixSortSelector<Value>::sort(first, last, Identity<Value>());
+  }
+
+  namespace _radix_sort_bits {
+
+    template <typename Value>
+    unsigned char valueByte(Value value, int byte) {
+      return value >> (std::numeric_limits<unsigned char>::digits * byte);
+    }
+
+    template <typename Functor, typename Key>
+    void stableRadixIntroSort(Key *first, Key *last, Key *target,
+                              int byte, Functor functor) {
+      const int size =
+        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
+      std::vector<int> counter(size);
+      for (int i = 0; i < size; ++i) {
+        counter[i] = 0;
+      }
+      Key *it = first;
+      while (first != last) {
+        ++counter[valueByte(functor(*first), byte)];
+        ++first;
+      }
+      int prev, num = 0;
+      for (int i = 0; i < size; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      while (it != last) {
+        target[counter[valueByte(functor(*it), byte)]++] = *it;
+        ++it;
+      }
+    }
+
+    template <typename Functor, typename Key>
+    void signedStableRadixIntroSort(Key *first, Key *last, Key *target,
+                                    int byte, Functor functor) {
+      const int size =
+        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
+      std::vector<int> counter(size);
+      for (int i = 0; i < size; ++i) {
+        counter[i] = 0;
+      }
+      Key *it = first;
+      while (first != last) {
+        counter[valueByte(functor(*first), byte)]++;
+        ++first;
+      }
+      int prev, num = 0;
+      for (int i = size / 2; i < size; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      for (int i = 0; i < size / 2; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      while (it != last) {
+        target[counter[valueByte(functor(*it), byte)]++] = *it;
+        ++it;
+      }
+    }
+
+
+    template <typename Value, typename Iterator, typename Functor>
+    void stableRadixSignedSort(Iterator first, Iterator last, Functor functor) {
+      if (first == last) return;
+      typedef typename std::iterator_traits<Iterator>::value_type Key;
+      typedef std::allocator<Key> Allocator;
+      Allocator allocator;
+
+      int length = std::distance(first, last);
+      Key* buffer = allocator.allocate(2 * length);
+      try {
+        bool dir = true;
+        std::copy(first, last, buffer);
+        for (int i = 0; i < int(sizeof(Value)) - 1; ++i) {
+          if (dir) {
+            stableRadixIntroSort(buffer, buffer + length, buffer + length,
+                                 i, functor);
+          } else {
+            stableRadixIntroSort(buffer + length, buffer + 2 * length, buffer,
+                                 i, functor);
+          }
+          dir = !dir;
+        }
+        if (dir) {
+          signedStableRadixIntroSort(buffer, buffer + length, buffer + length,
+                                     sizeof(Value) - 1, functor);
+          std::copy(buffer + length, buffer + 2 * length, first);
+        }        else {
+          signedStableRadixIntroSort(buffer + length, buffer + 2 * length,
+                                     buffer, sizeof(Value) - 1, functor);
+          std::copy(buffer, buffer + length, first);
+        }
+      } catch (...) {
+        allocator.deallocate(buffer, 2 * length);
+        throw;
+      }
+      allocator.deallocate(buffer, 2 * length);
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void stableRadixUnsignedSort(Iterator first, Iterator last,
+                                 Functor functor) {
+      if (first == last) return;
+      typedef typename std::iterator_traits<Iterator>::value_type Key;
+      typedef std::allocator<Key> Allocator;
+      Allocator allocator;
+
+      int length = std::distance(first, last);
+      Key *buffer = allocator.allocate(2 * length);
+      try {
+        bool dir = true;
+        std::copy(first, last, buffer);
+        for (int i = 0; i < int(sizeof(Value)); ++i) {
+          if (dir) {
+            stableRadixIntroSort(buffer, buffer + length,
+                                 buffer + length, i, functor);
+          } else {
+            stableRadixIntroSort(buffer + length, buffer + 2 * length,
+                                 buffer, i, functor);
+          }
+          dir = !dir;
+        }
+        if (dir) {
+          std::copy(buffer, buffer + length, first);
+        }        else {
+          std::copy(buffer + length, buffer + 2 * length, first);
+        }
+      } catch (...) {
+        allocator.deallocate(buffer, 2 * length);
+        throw;
+      }
+      allocator.deallocate(buffer, 2 * length);
+    }
+
+
+
+    template <typename Value,
+              bool sign = std::numeric_limits<Value>::is_signed >
+    struct StableRadixSortSelector {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        stableRadixSignedSort<Value>(first, last, functor);
+      }
+    };
+
+    template <typename Value>
+    struct StableRadixSortSelector<Value, false> {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        stableRadixUnsignedSort<Value>(first, last, functor);
+      }
+    };
+
+  }
+
+  /// \ingroup auxalg
+  ///
+  /// \brief Sorts the STL compatible range into ascending order in a stable
+  /// way.
+  ///
+  /// This function sorts an STL compatible range into ascending
+  /// order according to an integer mapping in the same as radixSort() does.
+  ///
+  /// This sorting algorithm is stable, i.e. the order of two equal
+  /// elements remains the same after the sorting.
+  ///
+  /// This sort algorithm  use a radix forward sort on the
+  /// bytes of the integer number. The algorithm sorts the items
+  /// byte-by-byte. First, it counts how many times a byte value occurs
+  /// in the container, then it copies the corresponding items to
+  /// another container in asceding order in \c O(n) time.
+  ///
+  /// The time complexity of the algorithm is \f$ O(\log(c)n) \f$ and
+  /// it uses \f$ O(n) \f$, additional space, where \c c is the
+  /// maximal value and \c n is the number of the items in the
+  /// container.
+  ///
+
+  /// \param first The begin of the given range.
+  /// \param last The end of the given range.
+  /// \param functor An adaptible unary function or a normal function
+  /// which maps the items to any integer type which can be either
+  /// signed or unsigned.
+  /// \sa radixSort()
+  template <typename Iterator, typename Functor>
+  void stableRadixSort(Iterator first, Iterator last, Functor functor) {
+    using namespace _radix_sort_bits;
+    typedef typename Functor::result_type Value;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator>
+  void stableRadixSort(Iterator first, Iterator last) {
+    using namespace _radix_sort_bits;
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    StableRadixSortSelector<Value>::sort(first, last, Identity<Value>());
+  }
+
+}
+
+#endif
Index: lemon/random.cc
===================================================================
--- lemon/random.cc	(revision 209)
+++ lemon/random.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/random.h
===================================================================
--- lemon/random.h	(revision 378)
+++ lemon/random.h	(revision 517)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -78,5 +78,5 @@
 #include <unistd.h>
 #else
-#include <windows.h>
+#include <lemon/bits/windows.h>
 #endif
 
@@ -345,16 +345,6 @@
     };
 
-    template <typename Result, int exp, bool pos = (exp >= 0)>
+    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>(2.0);
-        return res;
-      }
-    };
-
-    template <typename Result, int exp>
-    struct ShiftMultiplier<Result, exp, false> {
       static const Result multiplier() {
         Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
@@ -366,5 +356,5 @@
 
     template <typename Result>
-    struct ShiftMultiplier<Result, 0, true> {
+    struct ShiftMultiplier<Result, 0> {
       static const Result multiplier() {
         return static_cast<Result>(1.0);
@@ -373,5 +363,5 @@
 
     template <typename Result>
-    struct ShiftMultiplier<Result, -20, true> {
+    struct ShiftMultiplier<Result, 20> {
       static const Result multiplier() {
         return static_cast<Result>(1.0/1048576.0);
@@ -380,12 +370,12 @@
 
     template <typename Result>
-    struct ShiftMultiplier<Result, -32, true> {
+    struct ShiftMultiplier<Result, 32> {
       static const Result multiplier() {
-        return static_cast<Result>(1.0/424967296.0);
+        return static_cast<Result>(1.0/4294967296.0);
       }
     };
 
     template <typename Result>
-    struct ShiftMultiplier<Result, -53, true> {
+    struct ShiftMultiplier<Result, 53> {
       static const Result multiplier() {
         return static_cast<Result>(1.0/9007199254740992.0);
@@ -394,5 +384,5 @@
 
     template <typename Result>
-    struct ShiftMultiplier<Result, -64, true> {
+    struct ShiftMultiplier<Result, 64> {
       static const Result multiplier() {
         return static_cast<Result>(1.0/18446744073709551616.0);
@@ -414,5 +404,5 @@
 
       static Result convert(RandomCore<Word>& rnd) {
-        return Shifting<Result, - shift - rest>::
+        return Shifting<Result, shift + rest>::
           shift(static_cast<Result>(rnd() >> (bits - rest)));
       }
@@ -424,5 +414,5 @@
 
       static Result convert(RandomCore<Word>& rnd) {
-        return Shifting<Result, - shift - bits>::
+        return Shifting<Result, shift + bits>::
           shift(static_cast<Result>(rnd())) +
           RealConversion<Result, Word, rest-bits, shift + bits>::
@@ -663,7 +653,5 @@
       seed(getpid() + tv.tv_sec + tv.tv_usec);
 #else
-      FILETIME time;
-      GetSystemTimeAsFileTime(&time);
-      seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime);
+      seed(bits::getWinRndSeed());
 #endif
       return true;
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 375)
+++ lemon/smart_graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/soplex.cc
===================================================================
--- lemon/soplex.cc	(revision 462)
+++ lemon/soplex.cc	(revision 462)
@@ -0,0 +1,423 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <lemon/soplex.h>
+
+#include <soplex/soplex.h>
+
+
+///\file
+///\brief Implementation of the LEMON-SOPLEX lp solver interface.
+namespace lemon {
+
+  SoplexLp::SoplexLp() {
+    soplex = new soplex::SoPlex;
+  }
+
+  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;
+
+  }
+
+  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;
+  }
+
+
+  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();
+
+    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();
+  }
+
+} //namespace lemon
+
Index: lemon/soplex.h
===================================================================
--- lemon/soplex.h	(revision 462)
+++ lemon/soplex.h	(revision 462)
@@ -0,0 +1,151 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_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();
+
+  protected:
+
+    virtual SoplexLp* _newSolver() const;
+    virtual SoplexLp* _cloneSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+    virtual void _clear();
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_SOPLEX_H
+
Index: lemon/suurballe.h
===================================================================
--- lemon/suurballe.h	(revision 346)
+++ lemon/suurballe.h	(revision 519)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -28,4 +28,6 @@
 #include <lemon/bin_heap.h>
 #include <lemon/path.h>
+#include <lemon/list_graph.h>
+#include <lemon/maps.h>
 
 namespace lemon {
@@ -52,5 +54,5 @@
   ///
   /// \note For finding node-disjoint paths this algorithm can be used
-  /// with \ref SplitDigraphAdaptor.
+  /// with \ref SplitNodes.
 #ifdef DOXYGEN
   template <typename Digraph, typename LengthMap>
@@ -77,5 +79,5 @@
 
   private:
-  
+
     /// \brief Special implementation of the Dijkstra algorithm
     /// for finding shortest paths in the residual network.
@@ -107,5 +109,5 @@
       // The processed (i.e. permanently labeled) nodes
       std::vector<Node> _proc_nodes;
-      
+
       Node _s;
       Node _t;
@@ -201,5 +203,5 @@
     // The length map
     const LengthMap &_length;
-    
+
     // Arc map of the current flow
     FlowMap *_flow;
@@ -269,5 +271,5 @@
     /// This function sets the potential map.
     ///
-    /// The potentials provide the dual solution of the underlying 
+    /// The potentials provide the dual solution of the underlying
     /// minimum cost flow problem.
     ///
@@ -331,5 +333,5 @@
       for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
 
-      _dijkstra = new ResidualDijkstra( _graph, *_flow, _length, 
+      _dijkstra = new ResidualDijkstra( _graph, *_flow, _length,
                                         *_potential, _pred,
                                         _source, _target );
@@ -371,5 +373,5 @@
       return _path_num;
     }
-    
+
     /// \brief Compute the paths from the flow.
     ///
Index: lemon/time_measure.h
===================================================================
--- lemon/time_measure.h	(revision 314)
+++ lemon/time_measure.h	(revision 515)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -25,9 +25,7 @@
 
 #ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#define NOMINMAX
-#include <windows.h>
-#include <cmath>
+#include <lemon/bits/windows.h>
 #else
+#include <unistd.h>
 #include <sys/times.h>
 #include <sys/time.h>
@@ -88,24 +86,5 @@
       cstime=ts.tms_cstime/tck;
 #else
-      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;
-      }
+      bits::getWinProcTimes(rtime, utime, stime, cutime, cstime);
 #endif
     }
Index: lemon/tolerance.h
===================================================================
--- lemon/tolerance.h	(revision 280)
+++ lemon/tolerance.h	(revision 517)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -39,6 +39,7 @@
   ///as a result of a probably inexact computation.
   ///
-  ///This is an abstract class, it should be specialized for all
-  ///numerical data types. These specialized classes like
+  ///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.
   ///
@@ -46,8 +47,4 @@
   ///\sa Tolerance<double>
   ///\sa Tolerance<long double>
-  ///\sa Tolerance<int>
-  ///\sa Tolerance<long long int>
-  ///\sa Tolerance<unsigned int>
-  ///\sa Tolerance<unsigned long long int>
 
   template<class T>
@@ -65,18 +62,18 @@
 
     ///Returns \c true if \c a is \e surely strictly less than \c b
-    static bool less(Value a,Value b) {return false;}
-    ///Returns \c true if \c a is \e surely different from \c b
-    static bool different(Value a,Value b) {return false;}
-    ///Returns \c true if \c a is \e surely positive
-    static bool positive(Value a) {return false;}
-    ///Returns \c true if \c a is \e surely negative
-    static bool negative(Value a) {return false;}
-    ///Returns \c true if \c a is \e surely non-zero
-    static bool nonZero(Value a) {return false;}
+    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 T();}
+    static Value zero() {return static_cast<Value>(0);}
 
     //   static bool finite(Value a) {}
@@ -239,211 +236,4 @@
   };
 
-  ///Integer specialization of Tolerance.
-
-  ///Integer specialization of Tolerance.
-  ///\sa Tolerance
-  template<>
-  class Tolerance<int>
-  {
-  public:
-    ///\e
-    typedef int Value;
-
-    ///\name Comparisons
-    ///See \ref lemon::Tolerance "Tolerance" for more details.
-
-    ///@{
-
-    ///Returns \c true if \c a is \e surely strictly less than \c b
-    static bool less(Value a,Value b) { return a<b;}
-    ///Returns \c true if \c a is \e surely different from \c b
-    static bool different(Value a,Value b) { return a!=b; }
-    ///Returns \c true if \c a is \e surely positive
-    static bool positive(Value a) { return 0<a; }
-    ///Returns \c true if \c a is \e surely negative
-    static bool negative(Value a) { return 0>a; }
-    ///Returns \c true if \c a is \e surely non-zero
-    static bool nonZero(Value a) { return a!=0; }
-
-    ///@}
-
-    ///Returns zero
-    static Value zero() {return 0;}
-  };
-
-  ///Unsigned integer specialization of Tolerance.
-
-  ///Unsigned integer specialization of Tolerance.
-  ///\sa Tolerance
-  template<>
-  class Tolerance<unsigned int>
-  {
-  public:
-    ///\e
-    typedef unsigned int Value;
-
-    ///\name Comparisons
-    ///See \ref lemon::Tolerance "Tolerance" for more details.
-
-    ///@{
-
-    ///Returns \c true if \c a is \e surely strictly less than \c b
-    static bool less(Value a,Value b) { return a<b;}
-    ///Returns \c true if \c a is \e surely different from \c b
-    static bool different(Value a,Value b) { return a!=b; }
-    ///Returns \c true if \c a is \e surely positive
-    static bool positive(Value a) { return 0<a; }
-    ///Returns \c true if \c a is \e surely negative
-    static bool negative(Value) { return false; }
-    ///Returns \c true if \c a is \e surely non-zero
-    static bool nonZero(Value a) { return a!=0; }
-
-    ///@}
-
-    ///Returns zero
-    static Value zero() {return 0;}
-  };
-
-
-  ///Long integer specialization of Tolerance.
-
-  ///Long integer specialization of Tolerance.
-  ///\sa Tolerance
-  template<>
-  class Tolerance<long int>
-  {
-  public:
-    ///\e
-    typedef long int Value;
-
-    ///\name Comparisons
-    ///See \ref lemon::Tolerance "Tolerance" for more details.
-
-    ///@{
-
-    ///Returns \c true if \c a is \e surely strictly less than \c b
-    static bool less(Value a,Value b) { return a<b;}
-    ///Returns \c true if \c a is \e surely different from \c b
-    static bool different(Value a,Value b) { return a!=b; }
-    ///Returns \c true if \c a is \e surely positive
-    static bool positive(Value a) { return 0<a; }
-    ///Returns \c true if \c a is \e surely negative
-    static bool negative(Value a) { return 0>a; }
-    ///Returns \c true if \c a is \e surely non-zero
-    static bool nonZero(Value a) { return a!=0;}
-
-    ///@}
-
-    ///Returns zero
-    static Value zero() {return 0;}
-  };
-
-  ///Unsigned long integer specialization of Tolerance.
-
-  ///Unsigned long integer specialization of Tolerance.
-  ///\sa Tolerance
-  template<>
-  class Tolerance<unsigned long int>
-  {
-  public:
-    ///\e
-    typedef unsigned long int Value;
-
-    ///\name Comparisons
-    ///See \ref lemon::Tolerance "Tolerance" for more details.
-
-    ///@{
-
-    ///Returns \c true if \c a is \e surely strictly less than \c b
-    static bool less(Value a,Value b) { return a<b;}
-    ///Returns \c true if \c a is \e surely different from \c b
-    static bool different(Value a,Value b) { return a!=b; }
-    ///Returns \c true if \c a is \e surely positive
-    static bool positive(Value a) { return 0<a; }
-    ///Returns \c true if \c a is \e surely negative
-    static bool negative(Value) { return false; }
-    ///Returns \c true if \c a is \e surely non-zero
-    static bool nonZero(Value a) { return a!=0;}
-
-    ///@}
-
-    ///Returns zero
-    static Value zero() {return 0;}
-  };
-
-#if defined __GNUC__ && !defined __STRICT_ANSI__
-
-  ///Long long integer specialization of Tolerance.
-
-  ///Long long integer specialization of Tolerance.
-  ///\warning This class (more exactly, type <tt>long long</tt>)
-  ///is not ansi compatible.
-  ///\sa Tolerance
-  template<>
-  class Tolerance<long long int>
-  {
-  public:
-    ///\e
-    typedef long long int Value;
-
-    ///\name Comparisons
-    ///See \ref lemon::Tolerance "Tolerance" for more details.
-
-    ///@{
-
-    ///Returns \c true if \c a is \e surely strictly less than \c b
-    static bool less(Value a,Value b) { return a<b;}
-    ///Returns \c true if \c a is \e surely different from \c b
-    static bool different(Value a,Value b) { return a!=b; }
-    ///Returns \c true if \c a is \e surely positive
-    static bool positive(Value a) { return 0<a; }
-    ///Returns \c true if \c a is \e surely negative
-    static bool negative(Value a) { return 0>a; }
-    ///Returns \c true if \c a is \e surely non-zero
-    static bool nonZero(Value a) { return a!=0;}
-
-    ///@}
-
-    ///Returns zero
-    static Value zero() {return 0;}
-  };
-
-  ///Unsigned long long integer specialization of Tolerance.
-
-  ///Unsigned long long integer specialization of Tolerance.
-  ///\warning This class (more exactly, type <tt>unsigned long long</tt>)
-  ///is not ansi compatible.
-  ///\sa Tolerance
-  template<>
-  class Tolerance<unsigned long long int>
-  {
-  public:
-    ///\e
-    typedef unsigned long long int Value;
-
-    ///\name Comparisons
-    ///See \ref lemon::Tolerance "Tolerance" for more details.
-
-    ///@{
-
-    ///Returns \c true if \c a is \e surely strictly less than \c b
-    static bool less(Value a,Value b) { return a<b;}
-    ///Returns \c true if \c a is \e surely different from \c b
-    static bool different(Value a,Value b) { return a!=b; }
-    ///Returns \c true if \c a is \e surely positive
-    static bool positive(Value a) { return 0<a; }
-    ///Returns \c true if \c a is \e surely negative
-    static bool negative(Value) { return false; }
-    ///Returns \c true if \c a is \e surely non-zero
-    static bool nonZero(Value a) { return a!=0;}
-
-    ///@}
-
-    ///Returns zero
-    static Value zero() {return 0;}
-  };
-
-#endif
-
   /// @}
 
Index: lemon/unionfind.h
===================================================================
--- lemon/unionfind.h	(revision 236)
+++ lemon/unionfind.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -1178,7 +1178,8 @@
             if (nodes[nodes[jd].next].size < cmax) {
               pushLeft(nodes[jd].next, nodes[jd].left);
-              if (less(nodes[jd].left, nodes[jd].next)) {
-                nodes[nodes[jd].next].prio = nodes[nodes[jd].left].prio;
-                nodes[nodes[jd].next].item = nodes[nodes[jd].left].item;
+              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);
@@ -1189,7 +1190,8 @@
               popLeft(nodes[jd].next);
               pushRight(jd, ld);
-              if (less(ld, nodes[jd].left)) {
+              if (less(ld, nodes[jd].left) ||
+                  nodes[ld].item == nodes[pd].item) {
                 nodes[jd].item = nodes[ld].item;
-                nodes[jd].prio = nodes[jd].prio;
+                nodes[jd].prio = nodes[ld].prio;
               }
               if (nodes[nodes[jd].next].item == nodes[ld].item) {
@@ -1220,7 +1222,8 @@
             if (nodes[nodes[jd].prev].size < cmax) {
               pushRight(nodes[jd].prev, nodes[jd].right);
-              if (less(nodes[jd].right, nodes[jd].prev)) {
-                nodes[nodes[jd].prev].prio = nodes[nodes[jd].right].prio;
-                nodes[nodes[jd].prev].item = nodes[nodes[jd].right].item;
+              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);
@@ -1231,7 +1234,8 @@
               popRight(nodes[jd].prev);
               pushLeft(jd, ld);
-              if (less(ld, nodes[jd].right)) {
+              if (less(ld, nodes[jd].right) ||
+                  nodes[ld].item == nodes[pd].item) {
                 nodes[jd].item = nodes[ld].item;
-                nodes[jd].prio = nodes[jd].prio;
+                nodes[jd].prio = nodes[ld].prio;
               }
               if (nodes[nodes[jd].prev].item == nodes[ld].item) {
@@ -1251,9 +1255,4 @@
       return comp(nodes[id].prio, nodes[jd].prio);
     }
-
-    bool equal(int id, int jd) const {
-      return !less(id, jd) && !less(jd, id);
-    }
-
 
   public:
@@ -1401,5 +1400,12 @@
               push(new_id, right_id);
               pushRight(new_id, ~(classes[r].parent));
-              setPrio(new_id);
+
+              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;
@@ -1441,5 +1447,12 @@
               push(new_id, left_id);
               pushLeft(new_id, ~(classes[l].parent));
-              setPrio(new_id);
+
+              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;
Index: m4/lx_check_clp.m4
===================================================================
--- m4/lx_check_clp.m4	(revision 459)
+++ m4/lx_check_clp.m4	(revision 459)
@@ -0,0 +1,73 @@
+AC_DEFUN([LX_CHECK_CLP],
+[
+  AC_ARG_WITH([clp],
+AS_HELP_STRING([--with-clp@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
+AS_HELP_STRING([--without-clp], [disable checking for CLP]),
+              [], [with_clp=yes])
+
+  AC_ARG_WITH([clp-includedir],
+AS_HELP_STRING([--with-clp-includedir=DIR], [search for CLP headers in DIR]),
+              [], [with_clp_includedir=no])
+
+  AC_ARG_WITH([clp-libdir],
+AS_HELP_STRING([--with-clp-libdir=DIR], [search for CLP libraries in DIR]),
+              [], [with_clp_libdir=no])
+
+  lx_clp_found=no
+  if test x"$with_clp" != x"no"; then
+    AC_MSG_CHECKING([for CLP])
+
+    if test x"$with_clp_includedir" != x"no"; then
+      CLP_CXXFLAGS="-I$with_clp_includedir"
+    elif test x"$with_clp" != x"yes"; then
+      CLP_CXXFLAGS="-I$with_clp/include"
+    fi
+
+    if test x"$with_clp_libdir" != x"no"; then
+      CLP_LDFLAGS="-L$with_clp_libdir"
+    elif test x"$with_clp" != x"yes"; then
+      CLP_LDFLAGS="-L$with_clp/lib"
+    fi
+    CLP_LIBS="-lClp -lCoinUtils -lm"
+
+    lx_save_cxxflags="$CXXFLAGS"
+    lx_save_ldflags="$LDFLAGS"
+    lx_save_libs="$LIBS"
+    CXXFLAGS="$CLP_CXXFLAGS"
+    LDFLAGS="$CLP_LDFLAGS"
+    LIBS="$CLP_LIBS"
+
+    lx_clp_test_prog='
+      #include <coin/ClpModel.hpp>
+
+      int main(int argc, char** argv)
+      {
+        ClpModel clp;
+        return 0;
+      }'
+
+    AC_LANG_PUSH(C++)
+    AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
+    AC_LANG_POP(C++)
+
+    CXXFLAGS="$lx_save_cxxflags"
+    LDFLAGS="$lx_save_ldflags"
+    LIBS="$lx_save_libs"
+
+    if test x"$lx_clp_found" = x"yes"; then
+      AC_DEFINE([HAVE_CLP], [1], [Define to 1 if you have CLP.])
+      lx_lp_found=yes
+      AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
+      AC_MSG_RESULT([yes])
+    else
+      CLP_CXXFLAGS=""
+      CLP_LDFLAGS=""
+      CLP_LIBS=""
+      AC_MSG_RESULT([no])
+    fi
+  fi
+  CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
+  AC_SUBST(CLP_CXXFLAGS)
+  AC_SUBST(CLP_LIBS)
+  AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
+])
Index: m4/lx_check_cplex.m4
===================================================================
--- m4/lx_check_cplex.m4	(revision 187)
+++ m4/lx_check_cplex.m4	(revision 457)
@@ -63,4 +63,8 @@
     if test x"$lx_cplex_found" = x"yes"; then
       AC_DEFINE([HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
+      lx_lp_found=yes
+      AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
+      lx_mip_found=yes
+      AC_DEFINE([HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
       AC_MSG_RESULT([yes])
     else
Index: m4/lx_check_glpk.m4
===================================================================
--- m4/lx_check_glpk.m4	(revision 187)
+++ m4/lx_check_glpk.m4	(revision 459)
@@ -43,4 +43,9 @@
       }
 
+      #if (GLP_MAJOR_VERSION < 4) \
+         || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33)
+      #error Supported GLPK versions: 4.33 or above
+      #endif
+
       int main(int argc, char** argv)
       {
@@ -61,4 +66,8 @@
     if test x"$lx_glpk_found" = x"yes"; then
       AC_DEFINE([HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
+      lx_lp_found=yes
+      AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
+      lx_mip_found=yes
+      AC_DEFINE([HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
       AC_MSG_RESULT([yes])
     else
Index: m4/lx_check_soplex.m4
===================================================================
--- m4/lx_check_soplex.m4	(revision 187)
+++ m4/lx_check_soplex.m4	(revision 457)
@@ -57,4 +57,6 @@
     if test x"$lx_soplex_found" = x"yes"; then
       AC_DEFINE([HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
+      lx_lp_found=yes
+      AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
       AC_MSG_RESULT([yes])
     else
Index: scripts/chg-len.py
===================================================================
--- scripts/chg-len.py	(revision 376)
+++ scripts/chg-len.py	(revision 422)
@@ -4,4 +4,7 @@
 
 from mercurial import ui, hg
+from mercurial import util
+
+util.rcpath = lambda : []
 
 if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 490)
+++ test/CMakeLists.txt	(revision 528)
@@ -1,8 +1,17 @@
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}
+  ${CMAKE_BINARY_DIR}
+)
+
+IF(HAVE_GLPK)
+  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIR})
+ENDIF(HAVE_GLPK)
 
 LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
 
 SET(TESTS
+  adaptors_test
   bfs_test
+  circulation_test
   counter_test
   dfs_test
@@ -10,5 +19,7 @@
   dijkstra_test
   dim_test
+  edge_set_test
   error_test
+  euler_test
   graph_copy_test
   graph_test
@@ -20,8 +31,47 @@
   max_matching_test
   min_cost_arborescence_test
+  path_test
+  preflow_test
+  radix_sort_test
   random_test
-  path_test
+  suurballe_test
   time_measure_test
   unionfind_test)
+
+IF(HAVE_LP)
+  ADD_EXECUTABLE(lp_test lp_test.cc)
+  IF(HAVE_GLPK)
+    TARGET_LINK_LIBRARIES(lp_test lemon ${GLPK_LIBRARIES})
+  ENDIF(HAVE_GLPK)
+  ADD_TEST(lp_test lp_test)
+
+  IF(WIN32 AND HAVE_GLPK)
+    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
+      COMMAND cmake -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
+      COMMAND cmake -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
+      COMMAND cmake -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
+    )
+  ENDIF(WIN32 AND HAVE_GLPK)
+ENDIF(HAVE_LP)
+
+IF(HAVE_MIP)
+  ADD_EXECUTABLE(mip_test mip_test.cc)
+  IF(HAVE_GLPK)
+    TARGET_LINK_LIBRARIES(mip_test lemon ${GLPK_LIBRARIES})
+  ENDIF(HAVE_GLPK)
+  ADD_TEST(mip_test mip_test)
+
+  IF(WIN32 AND HAVE_GLPK)
+    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
+      COMMAND cmake -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
+      COMMAND cmake -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
+      COMMAND cmake -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
+    )
+  ENDIF(WIN32 AND HAVE_GLPK)
+ENDIF(HAVE_MIP)
 
 FOREACH(TEST_NAME ${TESTS})
Index: test/Makefile.am
===================================================================
--- test/Makefile.am	(revision 490)
+++ test/Makefile.am	(revision 528)
@@ -1,42 +1,51 @@
 EXTRA_DIST += \
-	test/CMakeLists.txt \
-        test/min_cost_flow_test.lgf \
-        test/preflow_graph.lgf
+	test/CMakeLists.txt
 
 noinst_HEADERS += \
 	test/graph_test.h \
-        test/test_tools.h
+	test/test_tools.h
 
 check_PROGRAMS += \
+	test/adaptors_test \
 	test/bfs_test \
-        test/circulation_test \
-        test/counter_test \
+	test/circulation_test \
+	test/counter_test \
 	test/dfs_test \
 	test/digraph_test \
 	test/dijkstra_test \
-        test/dim_test \
+	test/dim_test \
+	test/edge_set_test \
 	test/error_test \
-	test/graph_adaptor_test \
+	test/euler_test \
 	test/graph_copy_test \
 	test/graph_test \
 	test/graph_utils_test \
+	test/hao_orlin_test \
 	test/heap_test \
 	test/kruskal_test \
-	test/hao_orlin_test \
-        test/maps_test \
+	test/maps_test \
 	test/max_matching_test \
 	test/min_cost_arborescence_test \
-        test/random_test \
-        test/path_test \
-        test/preflow_test \
-        test/suurballe_test \
-        test/test_tools_fail \
-        test/test_tools_pass \
-        test/time_measure_test \
+	test/path_test \
+	test/preflow_test \
+	test/radix_sort_test \
+	test/random_test \
+	test/suurballe_test \
+	test/test_tools_fail \
+	test/test_tools_pass \
+	test/time_measure_test \
 	test/unionfind_test
+
+if HAVE_LP
+check_PROGRAMS += test/lp_test
+endif HAVE_LP
+if HAVE_MIP
+check_PROGRAMS += test/mip_test
+endif HAVE_MIP
 
 TESTS += $(check_PROGRAMS)
 XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
 
+test_adaptors_test_SOURCES = test/adaptors_test.cc
 test_bfs_test_SOURCES = test/bfs_test.cc
 test_circulation_test_SOURCES = test/circulation_test.cc
@@ -46,6 +55,7 @@
 test_dijkstra_test_SOURCES = test/dijkstra_test.cc
 test_dim_test_SOURCES = test/dim_test.cc
+test_edge_set_test_SOURCES = test/edge_set_test.cc
 test_error_test_SOURCES = test/error_test.cc
-test_graph_adaptor_test_SOURCES = test/graph_adaptor_test.cc
+test_euler_test_SOURCES = test/euler_test.cc
 test_graph_copy_test_SOURCES = test/graph_copy_test.cc
 test_graph_test_SOURCES = test/graph_test.cc
@@ -54,9 +64,12 @@
 test_kruskal_test_SOURCES = test/kruskal_test.cc
 test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
+test_lp_test_SOURCES = test/lp_test.cc
 test_maps_test_SOURCES = test/maps_test.cc
+test_mip_test_SOURCES = test/mip_test.cc
 test_max_matching_test_SOURCES = test/max_matching_test.cc
 test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
 test_path_test_SOURCES = test/path_test.cc
 test_preflow_test_SOURCES = test/preflow_test.cc
+test_radix_sort_test_SOURCES = test/radix_sort_test.cc
 test_suurballe_test_SOURCES = test/suurballe_test.cc
 test_random_test_SOURCES = test/random_test.cc
Index: test/adaptors_test.cc
===================================================================
--- test/adaptors_test.cc	(revision 465)
+++ test/adaptors_test.cc	(revision 465)
@@ -0,0 +1,1486 @@
+/* -*- 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 <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);
+
+  // 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);
+
+  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);
+
+  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 SplitNodes< ReverseDigraph< const Orienter<
+            const GridGraph, GridGraph::EdgeMap<bool> > > >
+    RevSplitGridGraph;
+  typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
+  typedef Undirector<const SplitGridGraph> USplitGridGraph;
+  typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
+  checkConcept<concepts::Digraph, RevSplitGridGraph>();
+  checkConcept<concepts::Digraph, SplitGridGraph>();
+  checkConcept<concepts::Graph, USplitGridGraph>();
+  checkConcept<concepts::Graph, UUSplitGridGraph>();
+
+  RevSplitGridGraph rev_adaptor =
+    splitNodes(reverseDigraph(orienter(graph, dir_map)));
+  SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
+  USplitGridGraph uadaptor = undirector(adaptor);
+  UUSplitGridGraph uuadaptor = undirector(uadaptor);
+
+  // Check adaptor
+  checkGraphNodeList(adaptor, 8);
+  checkGraphArcList(adaptor, 8);
+  checkGraphConArcList(adaptor, 8);
+
+  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
+  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
+  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
+
+  checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
+  checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
+
+  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, rev_adaptor.inNode(n1), 2);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
+
+  // Check uuadaptor
+  checkGraphNodeList(uuadaptor, 8);
+  checkGraphEdgeList(uuadaptor, 16);
+  checkGraphArcList(uuadaptor, 32);
+  checkGraphConEdgeList(uuadaptor, 16);
+  checkGraphConArcList(uuadaptor, 32);
+
+  checkNodeIds(uuadaptor);
+  checkEdgeIds(uuadaptor);
+  checkArcIds(uuadaptor);
+
+  checkGraphNodeMap(uuadaptor);
+  checkGraphEdgeMap(uuadaptor);
+  checkGraphArcMap(uuadaptor);
+}
+
+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;
+}
Index: test/bfs_test.cc
===================================================================
--- test/bfs_test.cc	(revision 293)
+++ test/bfs_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/circulation_test.cc
===================================================================
--- test/circulation_test.cc	(revision 403)
+++ test/circulation_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/counter_test.cc
===================================================================
--- test/counter_test.cc	(revision 209)
+++ test/counter_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/dfs_test.cc
===================================================================
--- test/dfs_test.cc	(revision 293)
+++ test/dfs_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 375)
+++ test/digraph_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/dijkstra_test.cc
===================================================================
--- test/dijkstra_test.cc	(revision 397)
+++ test/dijkstra_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/dim_test.cc
===================================================================
--- test/dim_test.cc	(revision 253)
+++ test/dim_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/edge_set_test.cc
===================================================================
--- test/edge_set_test.cc	(revision 512)
+++ test/edge_set_test.cc	(revision 512)
@@ -0,0 +1,380 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <vector>
+
+#include <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);
+
+  ArcSet arc_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+
+  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);
+  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);
+
+  ArcSet arc_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+
+  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);
+  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);
+
+  EdgeSet edge_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+
+  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);
+  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);
+
+  EdgeSet edge_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+
+  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);
+  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;
+}
Index: test/error_test.cc
===================================================================
--- test/error_test.cc	(revision 277)
+++ test/error_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/euler_test.cc
===================================================================
--- test/euler_test.cc	(revision 522)
+++ test/euler_test.cc	(revision 522)
@@ -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-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/euler.h>
+#include <lemon/list_graph.h>
+#include <test/test_tools.h>
+
+using namespace lemon;
+
+template <typename Digraph>
+void checkDiEulerIt(const Digraph& g)
+{
+  typename Digraph::template ArcMap<int> visitationNumber(g);
+
+  DiEulerIt<Digraph> e(g);
+  typename Digraph::Node firstNode = g.source(e);
+  typename Digraph::Node lastNode;
+
+  for (; e != INVALID; ++e)
+  {
+    if (e != INVALID)
+    {
+      lastNode = g.target(e);
+    }
+    ++visitationNumber[e];
+  }
+
+  check(firstNode == lastNode,
+      "checkDiEulerIt: first and last node are not the same");
+
+  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)
+{
+  typename Graph::template EdgeMap<int> visitationNumber(g);
+
+  EulerIt<Graph> e(g);
+  typename Graph::Node firstNode = g.u(e);
+  typename Graph::Node lastNode;
+
+  for (; e != INVALID; ++e)
+  {
+    if (e != INVALID)
+    {
+      lastNode = g.v(e);
+    }
+    ++visitationNumber[e];
+  }
+
+  check(firstNode == lastNode,
+      "checkEulerIt: first and last node 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 ListGraph Graph;
+
+  Digraph digraphWithEulerianCircuit;
+  {
+    Digraph& g = digraphWithEulerianCircuit;
+
+    Digraph::Node n0 = g.addNode();
+    Digraph::Node n1 = g.addNode();
+    Digraph::Node n2 = g.addNode();
+
+    g.addArc(n0, n1);
+    g.addArc(n1, n0);
+    g.addArc(n1, n2);
+    g.addArc(n2, n1);
+  }
+
+  Digraph digraphWithoutEulerianCircuit;
+  {
+    Digraph& g = digraphWithoutEulerianCircuit;
+
+    Digraph::Node n0 = g.addNode();
+    Digraph::Node n1 = g.addNode();
+    Digraph::Node n2 = g.addNode();
+
+    g.addArc(n0, n1);
+    g.addArc(n1, n0);
+    g.addArc(n1, n2);
+  }
+
+  Graph graphWithEulerianCircuit;
+  {
+    Graph& g = graphWithEulerianCircuit;
+
+    Graph::Node n0 = g.addNode();
+    Graph::Node n1 = g.addNode();
+    Graph::Node n2 = g.addNode();
+
+    g.addEdge(n0, n1);
+    g.addEdge(n1, n2);
+    g.addEdge(n2, n0);
+  }
+
+  Graph graphWithoutEulerianCircuit;
+  {
+    Graph& g = graphWithoutEulerianCircuit;
+
+    Graph::Node n0 = g.addNode();
+    Graph::Node n1 = g.addNode();
+    Graph::Node n2 = g.addNode();
+
+    g.addEdge(n0, n1);
+    g.addEdge(n1, n2);
+  }
+
+  checkDiEulerIt(digraphWithEulerianCircuit);
+
+  checkEulerIt(graphWithEulerianCircuit);
+
+  check(eulerian(digraphWithEulerianCircuit),
+      "this graph should have an Eulerian circuit");
+  check(!eulerian(digraphWithoutEulerianCircuit),
+      "this graph should not have an Eulerian circuit");
+
+  check(eulerian(graphWithEulerianCircuit),
+      "this graph should have an Eulerian circuit");
+  check(!eulerian(graphWithoutEulerianCircuit),
+      "this graph should have an Eulerian circuit");
+
+  return 0;
+}
Index: st/graph_adaptor_test.cc
===================================================================
--- test/graph_adaptor_test.cc	(revision 416)
+++ 	(revision )
@@ -1,984 +1,0 @@
-/* -*- mode: C++; indent-tabs-mode: nil; -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library.
- *
- * Copyright (C) 2003-2008
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-#include<iostream>
-#include<lemon/concept_check.h>
-
-#include<lemon/list_graph.h>
-#include<lemon/smart_graph.h>
-
-#include<lemon/concepts/digraph.h>
-#include<lemon/concepts/graph.h>
-
-#include<lemon/adaptors.h>
-
-#include <limits>
-#include <lemon/bfs.h>
-#include <lemon/path.h>
-
-#include"test/test_tools.h"
-#include"test/graph_test.h"
-
-using namespace lemon;
-
-void checkReverseDigraph() {
-  checkConcept<concepts::Digraph, ReverseDigraph<concepts::Digraph> >();
-
-  typedef ListDigraph Digraph;
-  typedef ReverseDigraph<Digraph> Adaptor;
-
-  Digraph digraph;
-  Adaptor adaptor(digraph);
-
-  Digraph::Node n1 = digraph.addNode();
-  Digraph::Node n2 = digraph.addNode();
-  Digraph::Node n3 = digraph.addNode();
-
-  Digraph::Arc a1 = digraph.addArc(n1, n2);
-  Digraph::Arc a2 = digraph.addArc(n1, n3);
-  Digraph::Arc a3 = digraph.addArc(n2, n3);
-
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 3);
-  checkGraphConArcList(adaptor, 3);
-
-  checkGraphOutArcList(adaptor, n1, 0);
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 2);
-
-  checkGraphInArcList(adaptor, n1, 2);
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 0);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
-    check(adaptor.source(a) == digraph.target(a), "Wrong reverse");
-    check(adaptor.target(a) == digraph.source(a), "Wrong reverse");
-  }
-}
-
-void checkSubDigraph() {
-  checkConcept<concepts::Digraph,
-    SubDigraph<concepts::Digraph,
-    concepts::Digraph::NodeMap<bool>,
-    concepts::Digraph::ArcMap<bool> > >();
-
-  typedef ListDigraph Digraph;
-  typedef Digraph::NodeMap<bool> NodeFilter;
-  typedef Digraph::ArcMap<bool> ArcFilter;
-  typedef SubDigraph<Digraph, NodeFilter, ArcFilter> Adaptor;
-
-  Digraph digraph;
-  NodeFilter node_filter(digraph);
-  ArcFilter arc_filter(digraph);
-  Adaptor adaptor(digraph, node_filter, arc_filter);
-
-  Digraph::Node n1 = digraph.addNode();
-  Digraph::Node n2 = digraph.addNode();
-  Digraph::Node n3 = digraph.addNode();
-
-  Digraph::Arc a1 = digraph.addArc(n1, n2);
-  Digraph::Arc a2 = digraph.addArc(n1, n3);
-  Digraph::Arc a3 = digraph.addArc(n2, n3);
-
-  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
-  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
-  
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 3);
-  checkGraphConArcList(adaptor, 3);
-
-  checkGraphOutArcList(adaptor, n1, 2);
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 0);
-
-  checkGraphInArcList(adaptor, n1, 0);
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 2);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  arc_filter[a2] = false;
-
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 2);
-  checkGraphConArcList(adaptor, 2);
-
-  checkGraphOutArcList(adaptor, n1, 1);
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 0);
-
-  checkGraphInArcList(adaptor, n1, 0);
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  node_filter[n1] = false;
-
-  checkGraphNodeList(adaptor, 2);
-  checkGraphArcList(adaptor, 1);
-  checkGraphConArcList(adaptor, 1);
-
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 0);
-
-  checkGraphInArcList(adaptor, n2, 0);
-  checkGraphInArcList(adaptor, n3, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
-  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
-
-  checkGraphNodeList(adaptor, 0);
-  checkGraphArcList(adaptor, 0);
-  checkGraphConArcList(adaptor, 0);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-}
-
-void checkFilterNodes1() {
-  checkConcept<concepts::Digraph,
-    FilterNodes<concepts::Digraph,
-      concepts::Digraph::NodeMap<bool> > >();
-
-  typedef ListDigraph Digraph;
-  typedef Digraph::NodeMap<bool> NodeFilter;
-  typedef FilterNodes<Digraph, NodeFilter> Adaptor;
-
-  Digraph digraph;
-  NodeFilter node_filter(digraph);
-  Adaptor adaptor(digraph, node_filter);
-
-  Digraph::Node n1 = digraph.addNode();
-  Digraph::Node n2 = digraph.addNode();
-  Digraph::Node n3 = digraph.addNode();
-
-  Digraph::Arc a1 = digraph.addArc(n1, n2);
-  Digraph::Arc a2 = digraph.addArc(n1, n3);
-  Digraph::Arc a3 = digraph.addArc(n2, n3);
-
-  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
-  
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 3);
-  checkGraphConArcList(adaptor, 3);
-
-  checkGraphOutArcList(adaptor, n1, 2);
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 0);
-
-  checkGraphInArcList(adaptor, n1, 0);
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 2);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  node_filter[n1] = false;
-
-  checkGraphNodeList(adaptor, 2);
-  checkGraphArcList(adaptor, 1);
-  checkGraphConArcList(adaptor, 1);
-
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 0);
-
-  checkGraphInArcList(adaptor, n2, 0);
-  checkGraphInArcList(adaptor, n3, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
-
-  checkGraphNodeList(adaptor, 0);
-  checkGraphArcList(adaptor, 0);
-  checkGraphConArcList(adaptor, 0);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-}
-
-void checkFilterArcs() {
-  checkConcept<concepts::Digraph,
-    FilterArcs<concepts::Digraph,
-    concepts::Digraph::ArcMap<bool> > >();
-
-  typedef ListDigraph Digraph;
-  typedef Digraph::ArcMap<bool> ArcFilter;
-  typedef FilterArcs<Digraph, ArcFilter> Adaptor;
-
-  Digraph digraph;
-  ArcFilter arc_filter(digraph);
-  Adaptor adaptor(digraph, arc_filter);
-
-  Digraph::Node n1 = digraph.addNode();
-  Digraph::Node n2 = digraph.addNode();
-  Digraph::Node n3 = digraph.addNode();
-
-  Digraph::Arc a1 = digraph.addArc(n1, n2);
-  Digraph::Arc a2 = digraph.addArc(n1, n3);
-  Digraph::Arc a3 = digraph.addArc(n2, n3);
-
-  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
-  
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 3);
-  checkGraphConArcList(adaptor, 3);
-
-  checkGraphOutArcList(adaptor, n1, 2);
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 0);
-
-  checkGraphInArcList(adaptor, n1, 0);
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 2);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  arc_filter[a2] = false;
-
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 2);
-  checkGraphConArcList(adaptor, 2);
-
-  checkGraphOutArcList(adaptor, n1, 1);
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 0);
-
-  checkGraphInArcList(adaptor, n1, 0);
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
-
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 0);
-  checkGraphConArcList(adaptor, 0);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-}
-
-void checkUndirector() {
-  checkConcept<concepts::Graph, Undirector<concepts::Digraph> >();
-
-  typedef ListDigraph Digraph;
-  typedef Undirector<Digraph> Adaptor;
-
-  Digraph digraph;
-  Adaptor adaptor(digraph);
-
-  Digraph::Node n1 = digraph.addNode();
-  Digraph::Node n2 = digraph.addNode();
-  Digraph::Node n3 = digraph.addNode();
-
-  Digraph::Arc a1 = digraph.addArc(n1, n2);
-  Digraph::Arc a2 = digraph.addArc(n1, n3);
-  Digraph::Arc a3 = digraph.addArc(n2, n3);
-
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 6);
-  checkGraphEdgeList(adaptor, 3);
-  checkGraphConArcList(adaptor, 6);
-  checkGraphConEdgeList(adaptor, 3);
-
-  checkGraphOutArcList(adaptor, n1, 2);
-  checkGraphOutArcList(adaptor, n2, 2);
-  checkGraphOutArcList(adaptor, n3, 2);
-
-  checkGraphInArcList(adaptor, n1, 2);
-  checkGraphInArcList(adaptor, n2, 2);
-  checkGraphInArcList(adaptor, n3, 2);
-
-  checkGraphIncEdgeList(adaptor, n1, 2);
-  checkGraphIncEdgeList(adaptor, n2, 2);
-  checkGraphIncEdgeList(adaptor, n3, 2);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-
-  for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) {
-    check(adaptor.u(e) == digraph.source(e), "Wrong undir");
-    check(adaptor.v(e) == digraph.target(e), "Wrong undir");
-  }
-
-}
-
-void checkResidual() {
-  checkConcept<concepts::Digraph,
-    Residual<concepts::Digraph,
-    concepts::Digraph::ArcMap<int>,
-    concepts::Digraph::ArcMap<int> > >();
-
-  typedef ListDigraph Digraph;
-  typedef Digraph::ArcMap<int> IntArcMap;
-  typedef Residual<Digraph, IntArcMap> Adaptor;
-
-  Digraph digraph;
-  IntArcMap capacity(digraph), flow(digraph);
-  Adaptor adaptor(digraph, capacity, flow);
-
-  Digraph::Node n1 = digraph.addNode();
-  Digraph::Node n2 = digraph.addNode();
-  Digraph::Node n3 = digraph.addNode();
-  Digraph::Node n4 = digraph.addNode();
-
-  Digraph::Arc a1 = digraph.addArc(n1, n2);
-  Digraph::Arc a2 = digraph.addArc(n1, n3);
-  Digraph::Arc a3 = digraph.addArc(n1, n4);
-  Digraph::Arc a4 = digraph.addArc(n2, n3);
-  Digraph::Arc a5 = digraph.addArc(n2, n4);
-  Digraph::Arc a6 = digraph.addArc(n3, n4);
-
-  capacity[a1] = 8;
-  capacity[a2] = 6;
-  capacity[a3] = 4;
-  capacity[a4] = 4;
-  capacity[a5] = 6;
-  capacity[a6] = 10;
-
-  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
-    flow[a] = 0;
-  }
-
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 6);
-  checkGraphConArcList(adaptor, 6);
-
-  checkGraphOutArcList(adaptor, n1, 3);
-  checkGraphOutArcList(adaptor, n2, 2);
-  checkGraphOutArcList(adaptor, n3, 1);
-  checkGraphOutArcList(adaptor, n4, 0);
-
-  checkGraphInArcList(adaptor, n1, 0);
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 2);
-  checkGraphInArcList(adaptor, n4, 3);
-
-  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
-    flow[a] = capacity[a] / 2;
-  }
-
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 12);
-  checkGraphConArcList(adaptor, 12);
-
-  checkGraphOutArcList(adaptor, n1, 3);
-  checkGraphOutArcList(adaptor, n2, 3);
-  checkGraphOutArcList(adaptor, n3, 3);
-  checkGraphOutArcList(adaptor, n4, 3);
-
-  checkGraphInArcList(adaptor, n1, 3);
-  checkGraphInArcList(adaptor, n2, 3);
-  checkGraphInArcList(adaptor, n3, 3);
-  checkGraphInArcList(adaptor, n4, 3);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
-    flow[a] = capacity[a];
-  }
-
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 6);
-  checkGraphConArcList(adaptor, 6);
-
-  checkGraphOutArcList(adaptor, n1, 0);
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 2);
-  checkGraphOutArcList(adaptor, n4, 3);
-
-  checkGraphInArcList(adaptor, n1, 3);
-  checkGraphInArcList(adaptor, n2, 2);
-  checkGraphInArcList(adaptor, n3, 1);
-  checkGraphInArcList(adaptor, n4, 0);
-
-  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
-    flow[a] = 0;
-  }
-
-  int flow_value = 0;
-  while (true) {
-
-    Bfs<Adaptor> bfs(adaptor);
-    bfs.run(n1, n4);
-
-    if (!bfs.reached(n4)) break;
-
-    Path<Adaptor> p = bfs.path(n4);
-
-    int min = std::numeric_limits<int>::max();
-    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
-      if (adaptor.residualCapacity(a) < min)
-        min = adaptor.residualCapacity(a);
-    }
-
-    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
-      adaptor.augment(a, min);
-    }
-    flow_value += min;
-  }
-
-  check(flow_value == 18, "Wrong flow with res graph adaptor");
-
-}
-
-void checkSplitNodes() {
-  checkConcept<concepts::Digraph, SplitNodes<concepts::Digraph> >();
-
-  typedef ListDigraph Digraph;
-  typedef SplitNodes<Digraph> Adaptor;
-
-  Digraph digraph;
-  Adaptor adaptor(digraph);
-
-  Digraph::Node n1 = digraph.addNode();
-  Digraph::Node n2 = digraph.addNode();
-  Digraph::Node n3 = digraph.addNode();
-
-  Digraph::Arc a1 = digraph.addArc(n1, n2);
-  Digraph::Arc a2 = digraph.addArc(n1, n3);
-  Digraph::Arc a3 = digraph.addArc(n2, n3);
-
-  checkGraphNodeList(adaptor, 6);
-  checkGraphArcList(adaptor, 6);
-  checkGraphConArcList(adaptor, 6);
-
-  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
-  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2);
-  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
-  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1);
-  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
-  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0);
-
-  checkGraphInArcList(adaptor, adaptor.inNode(n1), 0);
-  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
-  checkGraphInArcList(adaptor, adaptor.inNode(n2), 1);
-  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
-  checkGraphInArcList(adaptor, adaptor.inNode(n3), 2);
-  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
-    if (adaptor.origArc(a)) {
-      Digraph::Arc oa = a;
-      check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)),
-            "Wrong split");
-      check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)),
-            "Wrong split");
-    } else {
-      Digraph::Node on = a;
-      check(adaptor.source(a) == adaptor.inNode(on), "Wrong split");
-      check(adaptor.target(a) == adaptor.outNode(on), "Wrong split");
-    }
-  }
-}
-
-void checkSubGraph() {
-  checkConcept<concepts::Graph,
-    SubGraph<concepts::Graph,
-    concepts::Graph::NodeMap<bool>,
-    concepts::Graph::EdgeMap<bool> > >();
-
-  typedef ListGraph Graph;
-  typedef Graph::NodeMap<bool> NodeFilter;
-  typedef Graph::EdgeMap<bool> EdgeFilter;
-  typedef SubGraph<Graph, NodeFilter, EdgeFilter> Adaptor;
-
-  Graph graph;
-  NodeFilter node_filter(graph);
-  EdgeFilter edge_filter(graph);
-  Adaptor adaptor(graph, node_filter, edge_filter);
-
-  Graph::Node n1 = graph.addNode();
-  Graph::Node n2 = graph.addNode();
-  Graph::Node n3 = graph.addNode();
-  Graph::Node n4 = graph.addNode();
-
-  Graph::Edge e1 = graph.addEdge(n1, n2);
-  Graph::Edge e2 = graph.addEdge(n1, n3);
-  Graph::Edge e3 = graph.addEdge(n2, n3);
-  Graph::Edge e4 = graph.addEdge(n3, n4);
-
-  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
-  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
-  
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 8);
-  checkGraphEdgeList(adaptor, 4);
-  checkGraphConArcList(adaptor, 8);
-  checkGraphConEdgeList(adaptor, 4);
-
-  checkGraphOutArcList(adaptor, n1, 2);
-  checkGraphOutArcList(adaptor, n2, 2);
-  checkGraphOutArcList(adaptor, n3, 3);
-  checkGraphOutArcList(adaptor, n4, 1);
-
-  checkGraphInArcList(adaptor, n1, 2);
-  checkGraphInArcList(adaptor, n2, 2);
-  checkGraphInArcList(adaptor, n3, 3);
-  checkGraphInArcList(adaptor, n4, 1);
-
-  checkGraphIncEdgeList(adaptor, n1, 2);
-  checkGraphIncEdgeList(adaptor, n2, 2);
-  checkGraphIncEdgeList(adaptor, n3, 3);
-  checkGraphIncEdgeList(adaptor, n4, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-
-  edge_filter[e2] = false;
-
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 6);
-  checkGraphEdgeList(adaptor, 3);
-  checkGraphConArcList(adaptor, 6);
-  checkGraphConEdgeList(adaptor, 3);
-
-  checkGraphOutArcList(adaptor, n1, 1);
-  checkGraphOutArcList(adaptor, n2, 2);
-  checkGraphOutArcList(adaptor, n3, 2);
-  checkGraphOutArcList(adaptor, n4, 1);
-
-  checkGraphInArcList(adaptor, n1, 1);
-  checkGraphInArcList(adaptor, n2, 2);
-  checkGraphInArcList(adaptor, n3, 2);
-  checkGraphInArcList(adaptor, n4, 1);
-
-  checkGraphIncEdgeList(adaptor, n1, 1);
-  checkGraphIncEdgeList(adaptor, n2, 2);
-  checkGraphIncEdgeList(adaptor, n3, 2);
-  checkGraphIncEdgeList(adaptor, n4, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-
-  node_filter[n1] = false;
-
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 4);
-  checkGraphEdgeList(adaptor, 2);
-  checkGraphConArcList(adaptor, 4);
-  checkGraphConEdgeList(adaptor, 2);
-
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 2);
-  checkGraphOutArcList(adaptor, n4, 1);
-
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 2);
-  checkGraphInArcList(adaptor, n4, 1);
-
-  checkGraphIncEdgeList(adaptor, n2, 1);
-  checkGraphIncEdgeList(adaptor, n3, 2);
-  checkGraphIncEdgeList(adaptor, n4, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-
-  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
-  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
-
-  checkGraphNodeList(adaptor, 0);
-  checkGraphArcList(adaptor, 0);
-  checkGraphEdgeList(adaptor, 0);
-  checkGraphConArcList(adaptor, 0);
-  checkGraphConEdgeList(adaptor, 0);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-}
-
-void checkFilterNodes2() {
-  checkConcept<concepts::Graph,
-    FilterNodes<concepts::Graph,
-      concepts::Graph::NodeMap<bool> > >();
-
-  typedef ListGraph Graph;
-  typedef Graph::NodeMap<bool> NodeFilter;
-  typedef FilterNodes<Graph, NodeFilter> Adaptor;
-
-  Graph graph;
-  NodeFilter node_filter(graph);
-  Adaptor adaptor(graph, node_filter);
-
-  Graph::Node n1 = graph.addNode();
-  Graph::Node n2 = graph.addNode();
-  Graph::Node n3 = graph.addNode();
-  Graph::Node n4 = graph.addNode();
-
-  Graph::Edge e1 = graph.addEdge(n1, n2);
-  Graph::Edge e2 = graph.addEdge(n1, n3);
-  Graph::Edge e3 = graph.addEdge(n2, n3);
-  Graph::Edge e4 = graph.addEdge(n3, n4);
-
-  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
-  
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 8);
-  checkGraphEdgeList(adaptor, 4);
-  checkGraphConArcList(adaptor, 8);
-  checkGraphConEdgeList(adaptor, 4);
-
-  checkGraphOutArcList(adaptor, n1, 2);
-  checkGraphOutArcList(adaptor, n2, 2);
-  checkGraphOutArcList(adaptor, n3, 3);
-  checkGraphOutArcList(adaptor, n4, 1);
-
-  checkGraphInArcList(adaptor, n1, 2);
-  checkGraphInArcList(adaptor, n2, 2);
-  checkGraphInArcList(adaptor, n3, 3);
-  checkGraphInArcList(adaptor, n4, 1);
-
-  checkGraphIncEdgeList(adaptor, n1, 2);
-  checkGraphIncEdgeList(adaptor, n2, 2);
-  checkGraphIncEdgeList(adaptor, n3, 3);
-  checkGraphIncEdgeList(adaptor, n4, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-
-  node_filter[n1] = false;
-
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 4);
-  checkGraphEdgeList(adaptor, 2);
-  checkGraphConArcList(adaptor, 4);
-  checkGraphConEdgeList(adaptor, 2);
-
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 2);
-  checkGraphOutArcList(adaptor, n4, 1);
-
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 2);
-  checkGraphInArcList(adaptor, n4, 1);
-
-  checkGraphIncEdgeList(adaptor, n2, 1);
-  checkGraphIncEdgeList(adaptor, n3, 2);
-  checkGraphIncEdgeList(adaptor, n4, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-
-  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
-
-  checkGraphNodeList(adaptor, 0);
-  checkGraphArcList(adaptor, 0);
-  checkGraphEdgeList(adaptor, 0);
-  checkGraphConArcList(adaptor, 0);
-  checkGraphConEdgeList(adaptor, 0);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-}
-
-void checkFilterEdges() {
-  checkConcept<concepts::Graph,
-    FilterEdges<concepts::Graph,
-    concepts::Graph::EdgeMap<bool> > >();
-
-  typedef ListGraph Graph;
-  typedef Graph::EdgeMap<bool> EdgeFilter;
-  typedef FilterEdges<Graph, EdgeFilter> Adaptor;
-
-  Graph graph;
-  EdgeFilter edge_filter(graph);
-  Adaptor adaptor(graph, edge_filter);
-
-  Graph::Node n1 = graph.addNode();
-  Graph::Node n2 = graph.addNode();
-  Graph::Node n3 = graph.addNode();
-  Graph::Node n4 = graph.addNode();
-
-  Graph::Edge e1 = graph.addEdge(n1, n2);
-  Graph::Edge e2 = graph.addEdge(n1, n3);
-  Graph::Edge e3 = graph.addEdge(n2, n3);
-  Graph::Edge e4 = graph.addEdge(n3, n4);
-
-  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
-  
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 8);
-  checkGraphEdgeList(adaptor, 4);
-  checkGraphConArcList(adaptor, 8);
-  checkGraphConEdgeList(adaptor, 4);
-
-  checkGraphOutArcList(adaptor, n1, 2);
-  checkGraphOutArcList(adaptor, n2, 2);
-  checkGraphOutArcList(adaptor, n3, 3);
-  checkGraphOutArcList(adaptor, n4, 1);
-
-  checkGraphInArcList(adaptor, n1, 2);
-  checkGraphInArcList(adaptor, n2, 2);
-  checkGraphInArcList(adaptor, n3, 3);
-  checkGraphInArcList(adaptor, n4, 1);
-
-  checkGraphIncEdgeList(adaptor, n1, 2);
-  checkGraphIncEdgeList(adaptor, n2, 2);
-  checkGraphIncEdgeList(adaptor, n3, 3);
-  checkGraphIncEdgeList(adaptor, n4, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-
-  edge_filter[e2] = false;
-
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 6);
-  checkGraphEdgeList(adaptor, 3);
-  checkGraphConArcList(adaptor, 6);
-  checkGraphConEdgeList(adaptor, 3);
-
-  checkGraphOutArcList(adaptor, n1, 1);
-  checkGraphOutArcList(adaptor, n2, 2);
-  checkGraphOutArcList(adaptor, n3, 2);
-  checkGraphOutArcList(adaptor, n4, 1);
-
-  checkGraphInArcList(adaptor, n1, 1);
-  checkGraphInArcList(adaptor, n2, 2);
-  checkGraphInArcList(adaptor, n3, 2);
-  checkGraphInArcList(adaptor, n4, 1);
-
-  checkGraphIncEdgeList(adaptor, n1, 1);
-  checkGraphIncEdgeList(adaptor, n2, 2);
-  checkGraphIncEdgeList(adaptor, n3, 2);
-  checkGraphIncEdgeList(adaptor, n4, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-
-  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
-
-  checkGraphNodeList(adaptor, 4);
-  checkGraphArcList(adaptor, 0);
-  checkGraphEdgeList(adaptor, 0);
-  checkGraphConArcList(adaptor, 0);
-  checkGraphConEdgeList(adaptor, 0);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-  checkEdgeIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-  checkGraphEdgeMap(adaptor);
-}
-
-void checkOrienter() {
-  checkConcept<concepts::Digraph,
-    Orienter<concepts::Graph, concepts::Graph::EdgeMap<bool> > >();
-
-  typedef ListGraph Graph;
-  typedef ListGraph::EdgeMap<bool> DirMap;
-  typedef Orienter<Graph> Adaptor;
-
-  Graph graph;
-  DirMap dir(graph, true);
-  Adaptor adaptor(graph, dir);
-
-  Graph::Node n1 = graph.addNode();
-  Graph::Node n2 = graph.addNode();
-  Graph::Node n3 = graph.addNode();
-
-  Graph::Edge e1 = graph.addEdge(n1, n2);
-  Graph::Edge e2 = graph.addEdge(n1, n3);
-  Graph::Edge e3 = graph.addEdge(n2, n3);
-
-  checkGraphNodeList(adaptor, 3);
-  checkGraphArcList(adaptor, 3);
-  checkGraphConArcList(adaptor, 3);
-
-  {
-    dir[e1] = true;
-    Adaptor::Node u = adaptor.source(e1);
-    Adaptor::Node v = adaptor.target(e1);
-
-    dir[e1] = false;
-    check (u == adaptor.target(e1), "Wrong dir");
-    check (v == adaptor.source(e1), "Wrong dir");
-
-    check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir");
-    dir[e1] = n1 == u;
-  }
-
-  {
-    dir[e2] = true;
-    Adaptor::Node u = adaptor.source(e2);
-    Adaptor::Node v = adaptor.target(e2);
-
-    dir[e2] = false;
-    check (u == adaptor.target(e2), "Wrong dir");
-    check (v == adaptor.source(e2), "Wrong dir");
-
-    check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir");
-    dir[e2] = n3 == u;
-  }
-
-  {
-    dir[e3] = true;
-    Adaptor::Node u = adaptor.source(e3);
-    Adaptor::Node v = adaptor.target(e3);
-
-    dir[e3] = false;
-    check (u == adaptor.target(e3), "Wrong dir");
-    check (v == adaptor.source(e3), "Wrong dir");
-
-    check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir");
-    dir[e3] = n2 == u;
-  }
-
-  checkGraphOutArcList(adaptor, n1, 1);
-  checkGraphOutArcList(adaptor, n2, 1);
-  checkGraphOutArcList(adaptor, n3, 1);
-
-  checkGraphInArcList(adaptor, n1, 1);
-  checkGraphInArcList(adaptor, n2, 1);
-  checkGraphInArcList(adaptor, n3, 1);
-
-  checkNodeIds(adaptor);
-  checkArcIds(adaptor);
-
-  checkGraphNodeMap(adaptor);
-  checkGraphArcMap(adaptor);
-
-}
-
-
-int main(int, const char **) {
-
-  checkReverseDigraph();
-  checkSubDigraph();
-  checkFilterNodes1();
-  checkFilterArcs();
-  checkUndirector();
-  checkResidual();
-  checkSplitNodes();
-
-  checkSubGraph();
-  checkFilterNodes2();
-  checkFilterEdges();
-  checkOrienter();
-
-  return 0;
-}
Index: test/graph_copy_test.cc
===================================================================
--- test/graph_copy_test.cc	(revision 282)
+++ test/graph_copy_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/graph_test.cc
===================================================================
--- test/graph_test.cc	(revision 375)
+++ test/graph_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/graph_test.h
===================================================================
--- test/graph_test.h	(revision 374)
+++ test/graph_test.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/graph_utils_test.cc
===================================================================
--- test/graph_utils_test.cc	(revision 220)
+++ test/graph_utils_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/hao_orlin_test.cc
===================================================================
--- test/hao_orlin_test.cc	(revision 410)
+++ test/hao_orlin_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/heap_test.cc
===================================================================
--- test/heap_test.cc	(revision 293)
+++ test/heap_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/kruskal_test.cc
===================================================================
--- test/kruskal_test.cc	(revision 209)
+++ test/kruskal_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/lp_test.cc
===================================================================
--- test/lp_test.cc	(revision 462)
+++ test/lp_test.cc	(revision 462)
@@ -0,0 +1,403 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <sstream>
+#include <lemon/lp_skeleton.h>
+#include "test_tools.h"
+#include <lemon/tolerance.h>
+
+#ifdef HAVE_CONFIG_H
+#include <lemon/config.h>
+#endif
+
+#ifdef HAVE_GLPK
+#include <lemon/glpk.h>
+#endif
+
+#ifdef HAVE_CPLEX
+#include <lemon/cplex.h>
+#endif
+
+#ifdef HAVE_SOPLEX
+#include <lemon/soplex.h>
+#endif
+
+#ifdef HAVE_CLP
+#include <lemon/clp.h>
+#endif
+
+using namespace lemon;
+
+void lpTest(LpSolver& lp)
+{
+
+  typedef LpSolver LP;
+
+  std::vector<LP::Col> x(10);
+  //  for(int i=0;i<10;i++) x.push_back(lp.addCol());
+  lp.addColSet(x);
+  lp.colLowerBound(x,1);
+  lp.colUpperBound(x,1);
+  lp.colBounds(x,1,2);
+
+  std::vector<LP::Col> y(10);
+  lp.addColSet(y);
+
+  lp.colLowerBound(y,1);
+  lp.colUpperBound(y,1);
+  lp.colBounds(y,1,2);
+
+  std::map<int,LP::Col> z;
+
+  z.insert(std::make_pair(12,INVALID));
+  z.insert(std::make_pair(2,INVALID));
+  z.insert(std::make_pair(7,INVALID));
+  z.insert(std::make_pair(5,INVALID));
+
+  lp.addColSet(z);
+
+  lp.colLowerBound(z,1);
+  lp.colUpperBound(z,1);
+  lp.colBounds(z,1,2);
+
+  {
+    LP::Expr e,f,g;
+    LP::Col p1,p2,p3,p4,p5;
+    LP::Constr c;
+
+    p1=lp.addCol();
+    p2=lp.addCol();
+    p3=lp.addCol();
+    p4=lp.addCol();
+    p5=lp.addCol();
+
+    e[p1]=2;
+    *e=12;
+    e[p1]+=2;
+    *e+=12;
+    e[p1]-=2;
+    *e-=12;
+
+    e=2;
+    e=2.2;
+    e=p1;
+    e=f;
+
+    e+=2;
+    e+=2.2;
+    e+=p1;
+    e+=f;
+
+    e-=2;
+    e-=2.2;
+    e-=p1;
+    e-=f;
+
+    e*=2;
+    e*=2.2;
+    e/=2;
+    e/=2.2;
+
+    e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
+       (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
+       (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
+       2.2*f+f*2.2+f/2.2+
+       2*f+f*2+f/2+
+       2.2*p1+p1*2.2+p1/2.2+
+       2*p1+p1*2+p1/2
+       );
+
+
+    c = (e  <= f  );
+    c = (e  <= 2.2);
+    c = (e  <= 2  );
+    c = (e  <= p1 );
+    c = (2.2<= f  );
+    c = (2  <= f  );
+    c = (p1 <= f  );
+    c = (p1 <= p2 );
+    c = (p1 <= 2.2);
+    c = (p1 <= 2  );
+    c = (2.2<= p2 );
+    c = (2  <= p2 );
+
+    c = (e  >= f  );
+    c = (e  >= 2.2);
+    c = (e  >= 2  );
+    c = (e  >= p1 );
+    c = (2.2>= f  );
+    c = (2  >= f  );
+    c = (p1 >= f  );
+    c = (p1 >= p2 );
+    c = (p1 >= 2.2);
+    c = (p1 >= 2  );
+    c = (2.2>= p2 );
+    c = (2  >= p2 );
+
+    c = (e  == f  );
+    c = (e  == 2.2);
+    c = (e  == 2  );
+    c = (e  == p1 );
+    c = (2.2== f  );
+    c = (2  == f  );
+    c = (p1 == f  );
+    //c = (p1 == p2 );
+    c = (p1 == 2.2);
+    c = (p1 == 2  );
+    c = (2.2== p2 );
+    c = (2  == p2 );
+
+    c = ((2 <= e) <= 3);
+    c = ((2 <= p1) <= 3);
+
+    c = ((2 >= e) >= 3);
+    c = ((2 >= p1) >= 3);
+
+    e[x[3]]=2;
+    e[x[3]]=4;
+    e[x[3]]=1;
+    *e=12;
+
+    lp.addRow(-LP::INF,e,23);
+    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
+    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
+
+    lp.addRow(x[1]+x[3]<=x[5]-3);
+    lp.addRow((-7<=x[1]+x[3]-12)<=3);
+    lp.addRow(x[1]<=x[5]);
+
+    std::ostringstream buf;
+
+
+    e=((p1+p2)+(p1-0.99*p2));
+    //e.prettyPrint(std::cout);
+    //(e<=2).prettyPrint(std::cout);
+    double tolerance=0.001;
+    e.simplify(tolerance);
+    buf << "Coeff. of p2 should be 0.01";
+    check(e[p2]>0, buf.str());
+
+    tolerance=0.02;
+    e.simplify(tolerance);
+    buf << "Coeff. of p2 should be 0";
+    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
+
+
+  }
+
+  {
+    LP::DualExpr e,f,g;
+    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
+      p4 = INVALID, p5 = INVALID;
+
+    e[p1]=2;
+    e[p1]+=2;
+    e[p1]-=2;
+
+    e=p1;
+    e=f;
+
+    e+=p1;
+    e+=f;
+
+    e-=p1;
+    e-=f;
+
+    e*=2;
+    e*=2.2;
+    e/=2;
+    e/=2.2;
+
+    e=((p1+p2)+(p1-p2)+
+       (p1+f)+(f+p1)+(f+g)+
+       (p1-f)+(f-p1)+(f-g)+
+       2.2*f+f*2.2+f/2.2+
+       2*f+f*2+f/2+
+       2.2*p1+p1*2.2+p1/2.2+
+       2*p1+p1*2+p1/2
+       );
+  }
+
+}
+
+void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
+                   double exp_opt) {
+  using std::string;
+  lp.solve();
+
+  std::ostringstream buf;
+  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
+
+  check(lp.primalType()==stat, buf.str());
+
+  if (stat ==  LpSolver::OPTIMAL) {
+    std::ostringstream sbuf;
+    sbuf << "Wrong optimal value: the right optimum is " << exp_opt;
+    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
+  }
+}
+
+void aTest(LpSolver & lp)
+{
+  typedef LpSolver LP;
+
+ //The following example is very simple
+
+  typedef LpSolver::Row Row;
+  typedef LpSolver::Col Col;
+
+
+  Col x1 = lp.addCol();
+  Col x2 = lp.addCol();
+
+
+  //Constraints
+  Row upright=lp.addRow(x1+2*x2 <=1);
+  lp.addRow(x1+x2 >=-1);
+  lp.addRow(x1-x2 <=1);
+  lp.addRow(x1-x2 >=-1);
+  //Nonnegativity of the variables
+  lp.colLowerBound(x1, 0);
+  lp.colLowerBound(x2, 0);
+  //Objective function
+  lp.obj(x1+x2);
+
+  lp.sense(lp.MAX);
+
+  //Testing the problem retrieving routines
+  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(lp.sense() == lp.MAX,"This is a maximization!");
+  check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
+  check(lp.colLowerBound(x1)==0,
+        "The lower bound for variable x1 should be 0.");
+  check(lp.colUpperBound(x1)==LpSolver::INF,
+        "The upper bound for variable x1 should be infty.");
+  check(lp.rowLowerBound(upright) == -LpSolver::INF,
+        "The lower bound for the first row should be -infty.");
+  check(lp.rowUpperBound(upright)==1,
+        "The upper bound for the first row should be 1.");
+  LpSolver::Expr e = lp.row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 2, "The second coefficient should 1.");
+
+  lp.row(upright, x1+x2 <=1);
+  e = lp.row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 1, "The second coefficient should 1.");
+
+  LpSolver::DualExpr de = lp.col(x1);
+  check(  de[upright] == 1, "The first coefficient should 1.");
+
+  LpSolver* clp = lp.cloneSolver();
+
+  //Testing the problem retrieving routines
+  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(clp->sense() == clp->MAX,"This is a maximization!");
+  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
+  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
+  check(clp->colLowerBound(x1)==0,
+        "The lower bound for variable x1 should be 0.");
+  check(clp->colUpperBound(x1)==LpSolver::INF,
+        "The upper bound for variable x1 should be infty.");
+
+  check(lp.rowLowerBound(upright)==-LpSolver::INF,
+        "The lower bound for the first row should be -infty.");
+  check(lp.rowUpperBound(upright)==1,
+        "The upper bound for the first row should be 1.");
+  e = clp->row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 1, "The second coefficient should 1.");
+
+  de = clp->col(x1);
+  check(de[upright] == 1, "The first coefficient should 1.");
+
+  delete clp;
+
+  //Maximization of x1+x2
+  //over the triangle with vertices (0,0) (0,1) (1,0)
+  double expected_opt=1;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Minimization
+  lp.sense(lp.MIN);
+  expected_opt=0;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Vertex (-1,0) instead of (0,0)
+  lp.colLowerBound(x1, -LpSolver::INF);
+  expected_opt=-1;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Erase one constraint and return to maximization
+  lp.erase(upright);
+  lp.sense(lp.MAX);
+  expected_opt=LpSolver::INF;
+  solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
+
+  //Infeasibilty
+  lp.addRow(x1+x2 <=-2);
+  solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
+
+}
+
+int main()
+{
+  LpSkeleton lp_skel;
+  lpTest(lp_skel);
+
+#ifdef HAVE_GLPK
+  {
+    GlpkLp lp_glpk1,lp_glpk2;
+    lpTest(lp_glpk1);
+    aTest(lp_glpk2);
+  }
+#endif
+
+#ifdef HAVE_CPLEX
+  try {
+    CplexLp lp_cplex1,lp_cplex2;
+    lpTest(lp_cplex1);
+    aTest(lp_cplex2);
+  } catch (CplexEnv::LicenseError& error) {
+#ifdef LEMON_FORCE_CPLEX_CHECK
+    check(false, error.what());
+#else
+    std::cerr << error.what() << std::endl;
+    std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
+#endif
+  }
+#endif
+
+#ifdef HAVE_SOPLEX
+  {
+    SoplexLp lp_soplex1,lp_soplex2;
+    lpTest(lp_soplex1);
+    aTest(lp_soplex2);
+  }
+#endif
+
+#ifdef HAVE_CLP
+  {
+    ClpLp lp_clp1,lp_clp2;
+    lpTest(lp_clp1);
+    aTest(lp_clp2);
+  }
+#endif
+
+  return 0;
+}
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 210)
+++ test/maps_test.cc	(revision 507)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -171,5 +171,5 @@
     typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
     checkConcept<ReadMap<B,double>, CompMap>();
-    CompMap map1(DoubleMap(),ReadMap<B,A>());
+    CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
     CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
 
@@ -184,5 +184,5 @@
     typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
     checkConcept<ReadMap<A,double>, CombMap>();
-    CombMap map1(DoubleMap(), DoubleMap());
+    CombMap map1 = CombMap(DoubleMap(), DoubleMap());
     CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
 
@@ -196,9 +196,9 @@
     checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
     FunctorToMap<F> map1;
-    FunctorToMap<F> map2(F());
+    FunctorToMap<F> map2 = FunctorToMap<F>(F());
     B b = functorToMap(F())[A()];
 
     checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
-    MapToFunctor<ReadMap<A,B> > map(ReadMap<A,B>());
+    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
 
     check(functorToMap(&func)[A()] == 3,
Index: test/max_matching_test.cc
===================================================================
--- test/max_matching_test.cc	(revision 327)
+++ test/max_matching_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: st/min_cost_flow_test.lgf
===================================================================
--- test/min_cost_flow_test.lgf	(revision 345)
+++ 	(revision )
@@ -1,44 +1,0 @@
-@nodes
-label	supply1	supply2	supply3
-1	0	20	27	
-2	0	-4	0		
-3	0	0	0	
-4	0	0	0	
-5	0	9	0	
-6	0	-6	0	
-7	0	0	0	
-8	0	0	0	
-9	0	3	0	
-10	0	-2	0	
-11	0	0	0		
-12	0	-20	-27	
-               
-@arcs
-		cost	capacity	lower1	lower2
-1	2	70	11		0	8
-1	3	150	3		0	1
-1	4	80	15		0	2
-2	8	80	12		0	0
-3	5	140	5		0	3
-4	6	60	10		0	1
-4	7	80	2		0	0
-4	8	110	3		0	0
-5	7	60	14		0	0
-5	11	120	12		0	0
-6	3	0	3		0	0
-6	9	140	4		0	0
-6	10	90	8		0	0
-7	1	30	5		0	0
-8	12	60	16		0	4
-9	12	50	6		0	0
-10	12	70	13		0	5
-10	2	100	7		0	0
-10	7	60	10		0	0
-11	10	20	14		0	6
-12	11	30	10		0	0
-
-@attributes
-source	1
-target	12
-
-@end
Index: test/mip_test.cc
===================================================================
--- test/mip_test.cc	(revision 462)
+++ test/mip_test.cc	(revision 462)
@@ -0,0 +1,136 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include "test_tools.h"
+
+
+#ifdef HAVE_CONFIG_H
+#include <lemon/config.h>
+#endif
+
+#ifdef HAVE_CPLEX
+#include <lemon/cplex.h>
+#endif
+
+#ifdef HAVE_GLPK
+#include <lemon/glpk.h>
+#endif
+
+
+using namespace lemon;
+
+void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
+                   double exp_opt) {
+  using std::string;
+
+  mip.solve();
+  //int decimal,sign;
+  std::ostringstream buf;
+  buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
+
+
+  //  itoa(stat,buf1, 10);
+  check(mip.type()==stat, buf.str());
+
+  if (stat ==  MipSolver::OPTIMAL) {
+    std::ostringstream sbuf;
+    buf << "Wrong optimal value: the right optimum is " << exp_opt;
+    check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
+    //+ecvt(exp_opt,2)
+  }
+}
+
+void aTest(MipSolver& mip)
+{
+ //The following example is very simple
+
+
+  typedef MipSolver::Row Row;
+  typedef MipSolver::Col Col;
+
+
+
+  Col x1 = mip.addCol();
+  Col x2 = mip.addCol();
+
+
+  //Objective function
+  mip.obj(x1);
+
+  mip.max();
+
+
+  //Unconstrained optimization
+  mip.solve();
+  //Check it out!
+
+  //Constraints
+  mip.addRow(2*x1+x2 <=2);
+  mip.addRow(x1-2*x2 <=0);
+
+  //Nonnegativity of the variable x1
+  mip.colLowerBound(x1, 0);
+
+  //Maximization of x1
+  //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
+  double expected_opt=4.0/5.0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+  //Restrict x2 to integer
+  mip.colType(x2,MipSolver::INTEGER);
+  expected_opt=1.0/2.0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+
+  //Restrict both to integer
+  mip.colType(x1,MipSolver::INTEGER);
+  expected_opt=0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+
+
+}
+
+
+int main()
+{
+
+#ifdef HAVE_GLPK
+  {
+    GlpkMip mip1;
+    aTest(mip1);
+  }
+#endif
+
+#ifdef HAVE_CPLEX
+  try {
+    CplexMip mip2;
+    aTest(mip2);
+  } catch (CplexEnv::LicenseError& error) {
+#ifdef LEMON_FORCE_CPLEX_CHECK
+    check(false, error.what());
+#else
+    std::cerr << error.what() << std::endl;
+    std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
+#endif
+  }
+#endif
+
+  return 0;
+
+}
Index: test/path_test.cc
===================================================================
--- test/path_test.cc	(revision 209)
+++ test/path_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: st/preflow_graph.lgf
===================================================================
--- test/preflow_graph.lgf	(revision 394)
+++ 	(revision )
@@ -1,34 +1,0 @@
-@nodes
-label
-0
-1
-2
-3
-4
-5
-6
-7
-8
-9
-@arcs
-		label	capacity
-0	1	0	20
-0	2	1	0
-1	1	2	3
-1	2	3	8
-1	3	4	8
-2	5	5	5
-3	2	6	5
-3	5	7	5
-3	6	8	5
-4	3	9	3
-5	7	10	3
-5	6	11	10
-5	8	12	10
-6	8	13	8
-8	9	14	20
-8	1	15	5
-9	5	16	5
-@attributes
-source 1
-target 8
Index: test/preflow_test.cc
===================================================================
--- test/preflow_test.cc	(revision 394)
+++ test/preflow_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -17,6 +17,5 @@
  */
 
-#include <fstream>
-#include <string>
+#include <iostream>
 
 #include "test_tools.h"
@@ -29,4 +28,40 @@
 
 using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "    label capacity\n"
+  "0 1 0     20\n"
+  "0 2 1     0\n"
+  "1 1 2     3\n"
+  "1 2 3     8\n"
+  "1 3 4     8\n"
+  "2 5 5     5\n"
+  "3 2 6     5\n"
+  "3 5 7     5\n"
+  "3 6 8     5\n"
+  "4 3 9     3\n"
+  "5 7 10    3\n"
+  "5 6 11    10\n"
+  "5 8 12    10\n"
+  "6 8 13    8\n"
+  "8 9 14    20\n"
+  "8 1 15    5\n"
+  "9 5 16    5\n"
+  "@attributes\n"
+  "source 1\n"
+  "target 8\n";
 
 void checkPreflowCompile()
@@ -124,18 +159,9 @@
   typedef Preflow<Digraph, CapMap> PType;
 
-  std::string f_name;
-  if( getenv("srcdir") )
-    f_name = std::string(getenv("srcdir"));
-  else f_name = ".";
-  f_name += "/test/preflow_graph.lgf";
-
-  std::ifstream file(f_name.c_str());
-
-  check(file, "Input file '" << f_name << "' not found.");
-
   Digraph g;
   Node s, t;
   CapMap cap(g);
-  DigraphReader<Digraph>(g,file).
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(g,input).
     arcMap("capacity", cap).
     node("source",s).
Index: test/radix_sort_test.cc
===================================================================
--- test/radix_sort_test.cc	(revision 444)
+++ test/radix_sort_test.cc	(revision 444)
@@ -0,0 +1,147 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/time_measure.h>
+#include <lemon/smart_graph.h>
+#include <lemon/maps.h>
+#include <lemon/radix_sort.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+#include <vector>
+#include <algorithm>
+
+using namespace lemon;
+
+static const int n = 10000;
+
+struct Negate {
+  typedef int argument_type;
+  typedef int result_type;
+  int operator()(int a) { return - a; }
+};
+
+int negate(int a) { return - a; }
+
+
+void generateIntSequence(int n, std::vector<int>& data) {
+  int prime = 9973;
+  int root = 136, value = 1;
+  for (int i = 0; i < n; ++i) {
+    data.push_back(value - prime / 2);
+    value = (value * root) % prime;
+  }
+}
+
+void generateCharSequence(int n, std::vector<unsigned char>& data) {
+  int prime = 251;
+  int root = 3, value = root;
+  for (int i = 0; i < n; ++i) {
+    data.push_back(static_cast<unsigned char>(value));
+    value = (value * root) % prime;
+  }
+}
+
+void checkRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    radixSort(data2.begin(), data2.end(), Negate());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+    radixSort(data2.begin(), data2.end(), negate);
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+}
+
+
+void checkStableRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    stableRadixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), Negate());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), negate);
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+}
+
+int main() {
+
+  checkRadixSort();
+  checkStableRadixSort();
+
+  return 0;
+}
Index: test/random_test.cc
===================================================================
--- test/random_test.cc	(revision 209)
+++ test/random_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/suurballe_test.cc
===================================================================
--- test/suurballe_test.cc	(revision 346)
+++ test/suurballe_test.cc	(revision 440)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -18,5 +18,4 @@
 
 #include <iostream>
-#include <fstream>
 
 #include <lemon/list_graph.h>
@@ -29,7 +28,50 @@
 using namespace lemon;
 
+char test_lgf[] =
+  "@nodes\n"
+  "label supply1 supply2 supply3\n"
+  "1     0        20      27\n"
+  "2     0       -4        0\n"
+  "3     0        0        0\n"
+  "4     0        0        0\n"
+  "5     0        9        0\n"
+  "6     0       -6        0\n"
+  "7     0        0        0\n"
+  "8     0        0        0\n"
+  "9     0        3        0\n"
+  "10    0       -2        0\n"
+  "11    0        0        0\n"
+  "12    0       -20     -27\n"
+  "@arcs\n"
+  "      cost capacity lower1 lower2\n"
+  " 1  2  70  11       0      8\n"
+  " 1  3 150   3       0      1\n"
+  " 1  4  80  15       0      2\n"
+  " 2  8  80  12       0      0\n"
+  " 3  5 140   5       0      3\n"
+  " 4  6  60  10       0      1\n"
+  " 4  7  80   2       0      0\n"
+  " 4  8 110   3       0      0\n"
+  " 5  7  60  14       0      0\n"
+  " 5 11 120  12       0      0\n"
+  " 6  3   0   3       0      0\n"
+  " 6  9 140   4       0      0\n"
+  " 6 10  90   8       0      0\n"
+  " 7  1  30   5       0      0\n"
+  " 8 12  60  16       0      4\n"
+  " 9 12  50   6       0      0\n"
+  "10 12  70  13       0      5\n"
+  "10  2 100   7       0      0\n"
+  "10  7  60  10       0      0\n"
+  "11 10  20  14       0      6\n"
+  "12 11  30  10       0      0\n"
+  "@attributes\n"
+  "source  1\n"
+  "target 12\n"
+  "@end\n";
+
 // Check the feasibility of the flow
 template <typename Digraph, typename FlowMap>
-bool checkFlow( const Digraph& gr, const FlowMap& flow, 
+bool checkFlow( const Digraph& gr, const FlowMap& flow,
                 typename Digraph::Node s, typename Digraph::Node t,
                 int value )
@@ -54,5 +96,5 @@
 
 // Check the optimalitiy of the flow
-template < typename Digraph, typename CostMap, 
+template < typename Digraph, typename CostMap,
            typename FlowMap, typename PotentialMap >
 bool checkOptimality( const Digraph& gr, const CostMap& cost,
@@ -97,12 +139,5 @@
   Node source, target;
 
-  std::string fname;
-  if(getenv("srcdir"))
-    fname = std::string(getenv("srcdir"));
-  else fname = ".";
-  fname += "/test/min_cost_flow_test.lgf";
-
-  std::ifstream input(fname.c_str());
-  check(input, "Input file '" << fname << "' not found");
+  std::istringstream input(test_lgf);
   DigraphReader<ListDigraph>(digraph, input).
     arcMap("cost", length).
@@ -110,6 +145,5 @@
     node("target", target).
     run();
-  input.close();
-  
+
   // Find 2 paths
   {
@@ -119,5 +153,5 @@
           "The flow is not feasible");
     check(suurballe.totalLength() == 510, "The flow is not optimal");
-    check(checkOptimality(digraph, length, suurballe.flowMap(), 
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
                           suurballe.potentialMap()),
           "Wrong potentials");
@@ -134,5 +168,5 @@
           "The flow is not feasible");
     check(suurballe.totalLength() == 1040, "The flow is not optimal");
-    check(checkOptimality(digraph, length, suurballe.flowMap(), 
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
                           suurballe.potentialMap()),
           "Wrong potentials");
@@ -149,5 +183,5 @@
           "The flow is not feasible");
     check(suurballe.totalLength() == 1040, "The flow is not optimal");
-    check(checkOptimality(digraph, length, suurballe.flowMap(), 
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
                           suurballe.potentialMap()),
           "Wrong potentials");
Index: test/test_tools.h
===================================================================
--- test/test_tools.h	(revision 209)
+++ test/test_tools.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/test_tools_fail.cc
===================================================================
--- test/test_tools_fail.cc	(revision 209)
+++ test/test_tools_fail.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/test_tools_pass.cc
===================================================================
--- test/test_tools_pass.cc	(revision 209)
+++ test/test_tools_pass.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/time_measure_test.cc
===================================================================
--- test/time_measure_test.cc	(revision 209)
+++ test/time_measure_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/unionfind_test.cc
===================================================================
--- test/unionfind_test.cc	(revision 209)
+++ test/unionfind_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: tools/CMakeLists.txt
===================================================================
--- tools/CMakeLists.txt	(revision 527)
+++ tools/CMakeLists.txt	(revision 527)
@@ -0,0 +1,28 @@
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}
+  ${CMAKE_BINARY_DIR}
+)
+
+LINK_DIRECTORIES(${CMAKE_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(
+    FILES ${CMAKE_CURRENT_SOURCE_DIR}/lemon-0.x-to-1.x.sh
+    RUNTIME DESTINATION bin
+    COMPONENT bin)
+ENDIF(NOT WIN32)
Index: tools/Makefile.am
===================================================================
--- tools/Makefile.am	(revision 385)
+++ tools/Makefile.am	(revision 526)
@@ -2,5 +2,7 @@
 
 bin_PROGRAMS += \
-	tools/dimacs-to-lgf
+	tools/dimacs-solver \
+	tools/dimacs-to-lgf \
+	tools/lgf-gen
 
 dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
@@ -8,3 +10,5 @@
 endif WANT_TOOLS
 
+tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc
 tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
+tools_lgf_gen_SOURCES = tools/lgf-gen.cc
Index: tools/dimacs-solver.cc
===================================================================
--- tools/dimacs-solver.cc	(revision 526)
+++ tools/dimacs-solver.cc	(revision 526)
@@ -0,0 +1,233 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup tools
+///\file
+///\brief DIMACS to LGF converter.
+///
+/// This program converts various DIMACS formats to the LEMON Digraph Format
+/// (LGF).
+///
+/// See
+/// \verbatim
+///  dimacs-solver --help
+/// \endverbatim
+/// for more info on usage.
+///
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include <lemon/smart_graph.h>
+#include <lemon/dimacs.h>
+#include <lemon/lgf_writer.h>
+#include <lemon/time_measure.h>
+
+#include <lemon/arg_parser.h>
+#include <lemon/error.h>
+
+#include <lemon/dijkstra.h>
+#include <lemon/preflow.h>
+#include <lemon/max_matching.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 &,
+              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, 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';  
+}
+
+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>
+void solve(ArgParser &ap, std::istream &is, std::ostream &os,
+           DimacsDescriptor &desc)
+{
+  switch(desc.type)
+    {
+    case DimacsDescriptor::MIN:
+      std::cerr <<
+        "\n\n Sorry, the min. cost flow solver is not yet available.\n"
+                << std::endl;
+      break;
+    case DimacsDescriptor::MAX:
+      solve_max<Value>(ap,is,os,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[]) {
+  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.")
+    .boolOption("q", "Do not print any report")
+    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
+    .optionGroup("datatype","int")
+#ifdef 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")
+    .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' << std::endl;
+    }
+    
+  if(ap.given("double"))
+    solve<double>(ap,is,os,desc);
+  else if(ap.given("ldouble"))
+    solve<long double>(ap,is,os,desc);
+#ifdef HAVE_LONG_LONG
+  else if(ap.given("long"))
+    solve<long long>(ap,is,os,desc);
+#endif
+  else solve<int>(ap,is,os,desc);
+
+  return 0;
+}
Index: tools/dimacs-to-lgf.cc
===================================================================
--- tools/dimacs-to-lgf.cc	(revision 387)
+++ tools/dimacs-to-lgf.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: tools/lemon-0.x-to-1.x.sh
===================================================================
--- tools/lemon-0.x-to-1.x.sh	(revision 366)
+++ tools/lemon-0.x-to-1.x.sh	(revision 466)
@@ -93,4 +93,28 @@
         -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"\
     <$i > $TMP
     mv $TMP $i
Index: tools/lgf-gen.cc
===================================================================
--- tools/lgf-gen.cc	(revision 524)
+++ tools/lgf-gen.cc	(revision 524)
@@ -0,0 +1,835 @@
+/* -*- 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 digraph generator.
+///
+/// Graph generator application for various types of plane graphs.
+///
+/// See
+/// \verbatim
+///  lgf-gen --help
+/// \endverbatim
+/// for more info on the usage.
+///
+
+
+#include <algorithm>
+#include <set>
+#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+=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) + 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 - 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()) {
+        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, 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, 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()) spikeheap.erase(bit->second);
+      if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
+      if (nbit->second != spikeheap.end()) 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, 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, 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,a,b);
+      int k=sur.run(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,pi->a,pi->b);
+        int k=sur.run(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")
+//     .mandatoryGroup("dist")
+    .onlyOneGroup("dist")
+    .boolOption("eps", "Also generate .eps output (prefix.eps)")
+    .boolOption("nonodes", "Draw the edges only in the generated .eps")
+    .boolOption("dir", "Directed digraph is generated (each arcs are replaced by two directed ones)")
+    .boolOption("2con", "Create a two connected planar digraph")
+    .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 digraph")
+    .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 = 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+=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();
+}
+
