Index: gtags
===================================================================
--- .hgtags	(revision 1278)
+++ 	(revision )
@@ -1,5 +1,0 @@
-3ed8f7c8bed8f51aecdc8395aa11af2f1fa12d9f r1.2
-ffc2d2559fc916e90c3f000582a2d4761d229d44 r1.2.1
-d303bfa8b1edf141856665fb73fddcc6abc33fef r1.2.2
-9e587caed9537aeb01a855749b5919ee3e005911 r1.2.3
-e13061207f85ee5f428855b83b2fe3a3ad62a26c r1.2.4
Index: AUTHORS
===================================================================
--- AUTHORS	(revision 1072)
+++ AUTHORS	(revision 1148)
@@ -1,3 +1,3 @@
-The authors of the 1.x series are
+The main developers of release series 1.x are
 
  * Balazs Dezso <deba@inf.elte.hu>
@@ -6,9 +6,9 @@
  * Akos Ladanyi <ladanyi@tmit.bme.hu>
 
-For more details on the actual contribution, please visit the history
-of the main LEMON source repository: http://lemon.cs.elte.hu/hg/lemon
+For more complete list of contributors, please visit the history of
+the LEMON source code repository: http://lemon.cs.elte.hu/hg/lemon
 
-Moreover, this version is heavily based on the 0.x series of
-LEMON. Here is the list of people who contributed to those versions.
+Moreover, this version is heavily based on version 0.x of LEMON. Here
+is the list of people who contributed to those versions.
 
  * Mihaly Barasz <klao@cs.elte.hu>
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 1161)
+++ CMakeLists.txt	(revision 1322)
@@ -1,3 +1,7 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+IF(POLICY CMP0048) 
+  CMAKE_POLICY(SET CMP0048 OLD) 
+ENDIF(POLICY CMP0048)
 
 SET(PROJECT_NAME "LEMON")
@@ -13,27 +17,45 @@
 ELSE()
   EXECUTE_PROCESS(
-    COMMAND ${PYTHON_EXECUTABLE} ./scripts/chg-len.py
+    COMMAND
+    hg log -r. --template "{latesttag}"
     WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
-    OUTPUT_VARIABLE HG_REVISION_PATH
+    OUTPUT_VARIABLE HG_REVISION_TAG
     ERROR_QUIET
     OUTPUT_STRIP_TRAILING_WHITESPACE
   )
   EXECUTE_PROCESS(
-    COMMAND hg id -i
+    COMMAND
+    hg log -r. --template "{latesttagdistance}"
     WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
-    OUTPUT_VARIABLE HG_REVISION
+    OUTPUT_VARIABLE HG_REVISION_DIST
     ERROR_QUIET
     OUTPUT_STRIP_TRAILING_WHITESPACE
   )
-  IF(HG_REVISION STREQUAL "")
+  EXECUTE_PROCESS(
+    COMMAND
+    hg log -r. --template "{node|short}"
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION_ID
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+
+  IF(HG_REVISION_TAG STREQUAL "")
     SET(HG_REVISION_ID "hg-tip")
   ELSE()
-    IF(HG_REVISION_PATH STREQUAL "")
-      SET(HG_REVISION_ID ${HG_REVISION})
+    IF(HG_REVISION_TAG STREQUAL "null")
+      SET(HG_REVISION_TAG "trunk")
+    ELSEIF(HG_REVISION_TAG MATCHES "^r")
+      STRING(SUBSTRING ${HG_REVISION_TAG} 1 -1 HG_REVISION_TAG)
+    ENDIF()
+    IF(HG_REVISION_DIST STREQUAL "0")
+      SET(HG_REVISION ${HG_REVISION_TAG})
     ELSE()
-      SET(HG_REVISION_ID ${HG_REVISION_PATH}.${HG_REVISION})
+      SET(HG_REVISION
+	"${HG_REVISION_TAG}+${HG_REVISION_DIST}-${HG_REVISION_ID}")
     ENDIF()
   ENDIF()
-  SET(LEMON_VERSION ${HG_REVISION_ID} CACHE STRING "LEMON version string.")
+
+  SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
 ENDIF()
 
@@ -44,7 +66,79 @@
 FIND_PACKAGE(Doxygen)
 FIND_PACKAGE(Ghostscript)
-FIND_PACKAGE(GLPK 4.33)
-FIND_PACKAGE(CPLEX)
-FIND_PACKAGE(COIN)
+
+SET(LEMON_ENABLE_GLPK YES CACHE STRING "Enable GLPK solver backend.")
+SET(LEMON_ENABLE_ILOG YES CACHE STRING "Enable ILOG (CPLEX) solver backend.")
+SET(LEMON_ENABLE_COIN YES CACHE STRING "Enable COIN solver backend.")
+SET(LEMON_ENABLE_SOPLEX YES CACHE STRING "Enable SoPlex solver backend.")
+
+IF(LEMON_ENABLE_GLPK) 
+  FIND_PACKAGE(GLPK 4.33)
+ENDIF(LEMON_ENABLE_GLPK)
+IF(LEMON_ENABLE_ILOG)
+  FIND_PACKAGE(ILOG)
+ENDIF(LEMON_ENABLE_ILOG)
+IF(LEMON_ENABLE_COIN)
+  FIND_PACKAGE(COIN)
+ENDIF(LEMON_ENABLE_COIN)
+IF(LEMON_ENABLE_SOPLEX)
+  FIND_PACKAGE(SOPLEX)
+ENDIF(LEMON_ENABLE_SOPLEX)
+
+IF(GLPK_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_GLPK TRUE)
+ENDIF(GLPK_FOUND)
+IF(ILOG_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_CPLEX TRUE)
+ENDIF(ILOG_FOUND)
+IF(COIN_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_CLP TRUE)
+  SET(LEMON_HAVE_CBC TRUE)
+ENDIF(COIN_FOUND)
+IF(SOPLEX_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_SOPLEX TRUE)
+ENDIF(SOPLEX_FOUND)
+
+IF(ILOG_FOUND)
+  SET(DEFAULT_LP "CPLEX")
+  SET(DEFAULT_MIP "CPLEX")
+ELSEIF(COIN_FOUND)
+  SET(DEFAULT_LP "CLP")
+  SET(DEFAULT_MIP "CBC")
+ELSEIF(GLPK_FOUND)
+  SET(DEFAULT_LP "GLPK")
+  SET(DEFAULT_MIP "GLPK")
+ELSEIF(SOPLEX_FOUND)
+  SET(DEFAULT_LP "SOPLEX")
+ENDIF()
+
+IF(NOT LEMON_DEFAULT_LP OR
+    (NOT ILOG_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CPLEX")) OR
+    (NOT COIN_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CLP")) OR
+    (NOT GLPK_FOUND AND (LEMON_DEFAULT_LP STREQUAL "GLPK")) OR
+    (NOT SOPLEX_FOUND AND (LEMON_DEFAULT_LP STREQUAL "SOPLEX")))
+  SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
+    "Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)" FORCE)
+ELSE()
+  SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
+    "Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)")
+ENDIF()
+IF(NOT LEMON_DEFAULT_MIP OR
+    (NOT ILOG_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CPLEX")) OR
+    (NOT COIN_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CBC")) OR
+    (NOT GLPK_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "GLPK")))
+  SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
+    "Default MIP solver backend (GLPK, CPLEX or CBC)" FORCE)
+ELSE()
+  SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
+    "Default MIP solver backend (GLPK, CPLEX or CBC)")
+ENDIF()
+
 
 IF(DEFINED ENV{LEMON_CXX_WARNING})
@@ -74,18 +168,36 @@
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}")
 
-SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING
+IF(MSVC)
+  SET( CMAKE_CXX_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
     "Flags used by the C++ compiler during maintainer builds."
-    FORCE )
-SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING
+    )
+  SET( CMAKE_C_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
     "Flags used by the C compiler during maintainer builds."
-    FORCE )
-SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
-    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+    )
+  SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
     "Flags used for linking binaries during maintainer builds."
-    FORCE )
-SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
-    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+    )
+  SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
     "Flags used by the shared libraries linker during maintainer builds."
-    FORCE )
+    )
+ELSE()
+  SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING
+    "Flags used by the C++ compiler during maintainer builds."
+    )
+  SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING
+    "Flags used by the C compiler during maintainer builds."
+    )
+  SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used for linking binaries during maintainer builds."
+    )
+  SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used by the shared libraries linker during maintainer builds."
+    )
+ENDIF()
+
 MARK_AS_ADVANCED(
     CMAKE_CXX_FLAGS_MAINTAINER
@@ -115,5 +227,25 @@
 SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
 
-INCLUDE(FindPythonInterp)
+INCLUDE(FindThreads)
+
+IF(NOT LEMON_THREADING)
+  IF(CMAKE_USE_PTHREADS_INIT)
+    SET(LEMON_THREADING "Pthread")
+  ELSEIF(CMAKE_USE_WIN32_THREADS_INIT)
+    SET(LEMON_THREADING "Win32")
+  ELSE()
+    SET(LEMON_THREADING "None")
+  ENDIF()
+ENDIF()
+
+SET( LEMON_THREADING "${LEMON_THREADING}" CACHE STRING
+  "Choose the threading library, options are: Pthread Win32 None."
+  FORCE )
+
+IF(LEMON_THREADING STREQUAL "Pthread")
+  SET(LEMON_USE_PTHREAD TRUE)
+ELSEIF(LEMON_THREADING STREQUAL "Win32")
+  SET(LEMON_USE_WIN32_THREADS TRUE)
+ENDIF()
 
 ENABLE_TESTING()
@@ -127,4 +259,5 @@
 ADD_SUBDIRECTORY(lemon)
 IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
+  ADD_SUBDIRECTORY(contrib)
   ADD_SUBDIRECTORY(demo)
   ADD_SUBDIRECTORY(tools)
@@ -150,4 +283,31 @@
 ENDIF()
 
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/cmake/version.cmake.in
+  ${PROJECT_BINARY_DIR}/cmake/version.cmake
+  @ONLY
+)
+
+SET(ARCHIVE_BASE_NAME ${CMAKE_PROJECT_NAME})
+STRING(TOLOWER ${ARCHIVE_BASE_NAME} ARCHIVE_BASE_NAME)
+SET(ARCHIVE_NAME ${ARCHIVE_BASE_NAME}-${PROJECT_VERSION})
+ADD_CUSTOM_TARGET(dist
+  COMMAND cmake -E remove_directory ${ARCHIVE_NAME}
+  COMMAND hg archive ${ARCHIVE_NAME}
+  COMMAND cmake -E copy cmake/version.cmake ${ARCHIVE_NAME}/cmake/version.cmake
+  COMMAND tar -czf ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_NAME}
+  COMMAND zip -r ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.zip ${ARCHIVE_NAME}
+  COMMAND cmake -E copy_directory doc/html ${ARCHIVE_NAME}/doc/html
+  COMMAND tar -czf ${ARCHIVE_NAME}.tar.gz ${ARCHIVE_NAME}
+  COMMAND zip -r ${ARCHIVE_NAME}.zip ${ARCHIVE_NAME}
+  COMMAND cmake -E copy_directory doc/html ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
+  COMMAND tar -czf ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
+  COMMAND zip -r ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.zip ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
+  COMMAND cmake -E remove_directory ${ARCHIVE_NAME}
+  COMMAND cmake -E remove_directory ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
+  DEPENDS html
+  WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
+
+# CPACK config (Basically for NSIS)
 IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
   SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
Index: INSTALL
===================================================================
--- INSTALL	(revision 890)
+++ INSTALL	(revision 1233)
@@ -2,196 +2,166 @@
 =========================
 
-Since you are reading this I assume you already obtained one of the release
-tarballs and successfully extracted it. The latest version of LEMON is
-available at our web page (http://lemon.cs.elte.hu/).
+This file contains instructions for building and installing LEMON from
+source on Linux. The process on Windows is similar.
 
-LEMON provides two different build environments, one is based on "autotool",
-while the other is based on "cmake". This file contains instructions only for
-the former one, which is the recommended build environment on Linux, Mac OSX
-and other unices or if you use Cygwin on Windows. For cmake installation
-instructions visit http://lemon.cs.elte.hu.
+Note that it is not necessary to install LEMON in order to use
+it. Instead, you can easily integrate it with your own code
+directly. For instructions, see
+https://lemon.cs.elte.hu/trac/lemon/wiki/HowToCompile
+
 
 In order to install LEMON from the extracted source tarball you have to
 issue the following commands:
 
-   1. `cd lemon-x.y.z'
+   1. Step into the root of the source directory.
 
-      This command changes to the directory which was created when you
-      extracted the sources. The x.y.z part is a version number.
+      $ cd lemon-x.y.z
 
-   2. `./configure'
+   2. Create a build subdirectory and step into it.
 
-      This command runs the configure shell script, which does some checks and
-      creates the makefiles.
+      $ mkdir build
+      $ cd build
 
-   3. `make'
+   3. Perform system checks and create the makefiles.
 
-      This command compiles the non-template part of LEMON into libemon.a
-      file. It also compiles the programs in the tools subdirectory by
-      default.
+      $ cmake ..
 
-   4. `make check'
+   4. Build LEMON.
 
-      This step is optional, but recommended. It runs the test programs that
-      we developed for LEMON to check whether the library works properly on
-      your platform.
+      $ make 
 
-   5. `make install'
+      This command compiles the non-template part of LEMON into
+      libemon.a file. It also compiles the programs in the 'tools' and
+      'demo' subdirectories.
+
+   5. [Optional] Compile and run the self-tests.
+
+      $ make check
+
+   5. [Optional] Generate the user documentation.
+
+      $ make html
+
+      The release tarballs already include the documentation.
+
+      Note that for this step you need to have the following tools
+      installed: Python, Doxygen, Graphviz, Ghostscript, LaTeX.
+
+   6. [Optional] Install LEMON
+
+      $ make install
 
       This command installs LEMON under /usr/local (you will need root
-      privileges to be able to do that). If you want to install it to some
-      other location, then pass the --prefix=DIRECTORY flag to configure in
-      step 2. For example: `./configure --prefix=/home/username/lemon'.
-
-   6. `make install-html'
-
-      This command installs the documentation under share/doc/lemon/docs. The
-      generated documentation is included in the tarball. If you want to
-      generate it yourself, then run `make html'. Note that for this you need
-      to have the following programs installed: Doxygen, Graphviz, Ghostscript,
-      Latex.
-
+      privileges to be able to do that). If you want to install it to
+      some other location, then pass the
+      -DCMAKE_INSTALL_PREFIX=DIRECTORY flag to cmake in Step 3.
+      For example:
+      
+      $ cmake -DCMAKE_INSTALL_PREFIX=/home/username/lemon'
 
 Configure Options and Variables
 ===============================
 
-In step 2 you can customize the actions of configure by setting variables
-and passing options to it. This can be done like this:
-`./configure [OPTION]... [VARIABLE=VALUE]...'
+In Step 3, you can customize the build process by passing options to CMAKE.
 
-Below you will find some useful variables and options (see `./configure --help'
-for more):
+$ cmake [OPTIONS] ..
 
-CXX='comp'
+You find a list of the most useful options below.
 
-  Change the C++ compiler to 'comp'.
-
-CXXFLAGS='flags'
-
-  Pass the 'flags' to the compiler. For example CXXFLAGS='-O3 -march=pentium-m'
-  turns on generation of aggressively optimized Pentium-M specific code.
-
---prefix=PREFIX
+-DCMAKE_INSTALL_PREFIX=PREFIX
 
   Set the installation prefix to PREFIX. By default it is /usr/local.
 
---enable-tools
+-DCMAKE_BUILD_TYPE=[Release|Debug|Maintainer|...]
 
-   Build the programs in the tools subdirectory (default).
+  This sets the compiler options. The choices are the following
 
---disable-tools
+  'Release': A strong optimization is turned on (-O3 with gcc). This
+    is the default setting and we strongly recommend using this for
+    the final compilation.
 
-   Do not build the programs in the tools subdirectory.
+  'Debug': Optimization is turned off and debug info is added (-O0
+    -ggdb with gcc). If is recommended during the development.
 
---with-glpk[=PREFIX]
+  'Maintainer': The same as 'Debug' but the compiler warnings are
+    converted to errors (-Werror with gcc). In addition, 'make' will
+    also automatically compile and execute the test codes. It is the
+    best way of ensuring that LEMON codebase is clean and safe.
 
-   Enable GLPK support (default). You should specify the prefix too if
-   you installed GLPK to some non-standard location (e.g. your home
-   directory). If it is not found, GLPK support will be disabled.
+  'RelWithDebInfo': Optimized build with debug info.
 
---with-glpk-includedir=DIR
+  'MinSizeRel': Size optimized build (-Os with gcc)
 
-   The directory where the GLPK header files are located. This is only
-   useful when the GLPK headers and libraries are not under the same
-   prefix (which is unlikely).
+-DTEST_WITH_VALGRIND=YES
 
---with-glpk-libdir=DIR
+  Using this, the test codes will be executed using valgrind. It is a
+  very effective way of identifying indexing problems and memory leaks.
 
-   The directory where the GLPK libraries are located. This is only
-   useful when the GLPK headers and libraries are not under the same
-   prefix (which is unlikely).
+-DCMAKE_CXX_COMPILER=path-to-compiler
 
---without-glpk
+  Change the compiler to be used.
 
-   Disable GLPK support.
+-DBUILD_SHARED_LIBS=TRUE
 
---with-cplex[=PREFIX]
+  Build shared library instead of static one. Think twice if you
+  really want to use this option.
 
-   Enable CPLEX support (default). You should specify the prefix too
-   if you installed CPLEX to some non-standard location
-   (e.g. /opt/ilog/cplex75). If it is not found, CPLEX support will be
-   disabled.
+-DLEMON_DOC_SOURCE_BROWSER=YES
 
---with-cplex-includedir=DIR
+  Include the browsable cross referenced LEMON source code into the
+  doc. It makes the doc quite bloated, but may be useful for
+  developing LEMON itself.
 
-   The directory where the CPLEX header files are located. This is
-   only useful when the CPLEX headers and libraries are not under the
-   same prefix (e.g.  /usr/local/cplex/cplex75/include).
+-DLEMON_DOC_USE_MATHJAX=YES
 
---with-cplex-libdir=DIR
+  Use MathJax (http://mathjax.org) for rendering the math formulae in
+  the doc.  It of much higher quality compared to the default LaTeX
+  generated static images and it allows copy&paste of the formulae to
+  LaTeX, Open Office, MS Word etc. documents.
 
-   The directory where the CPLEX libraries are located. This is only
-   useful when the CPLEX headers and libraries are not under the same
-   prefix (e.g.
-   /usr/local/cplex/cplex75/lib/i86_linux2_glibc2.2_gcc3.0/static_pic_mt).
+  On the other hand, it needs either Internet access or a locally
+  installed version of MathJax to properly render the doc.
 
---without-cplex
+-DLEMON_DOC_MATHJAX_RELPATH=DIRECTORY
+  
+  The location of the MathJax library. It defaults to
+  http://www.mathjax.org/mathjax, which necessitates Internet access
+  for proper rendering. The easiest way to make it usable offline is
+  to set this parameter to 'mathjax' and copy all files of the MathJax
+  library into the 'doc/html/mathjax' subdirectory of the build
+  location.
 
-   Disable CPLEX support.
+  See http://docs.mathjax.org/en/latest/installation.html for more details.
 
---with-soplex[=PREFIX]
+  
+-DLEMON_ENABLE_GLPK=NO
+-DLEMON_ENABLE_COIN=NO
+-DLEMON_ENABLE_ILOG=NO
 
-   Enable SoPlex support (default). You should specify the prefix too if
-   you installed SoPlex to some non-standard location (e.g. your home
-   directory). If it is not found, SoPlex support will be disabled.
+  Enable optional third party libraries. They are all enabled by default. 
 
---with-soplex-includedir=DIR
+-DLEMON_DEFAULT_LP=GLPK
 
-   The directory where the SoPlex header files are located. This is only
-   useful when the SoPlex headers and libraries are not under the same
-   prefix (which is unlikely).
+  Sets the default LP solver backend. The supported values are
+  CPLEX, CLP and GLPK. By default, it is set to the first one which
+  is enabled and succesfully discovered.
 
---with-soplex-libdir=DIR
+-DLEMON_DEFAULT_MIP=GLPK
 
-   The directory where the SoPlex libraries are located. This is only
-   useful when the SoPlex headers and libraries are not under the same
-   prefix (which is unlikely).
+  Sets the default MIP solver backend. The supported values are
+  CPLEX, CBC and GLPK. By default, it is set to the first one which
+  is enabled and succesfully discovered.
 
---without-soplex
+-DGLPK_ROOT_DIR=DIRECTORY
+-DCOIN_ROOT_DIR=DIRECTORY
+-DILOG_ROOT_DIR=DIRECTORY
 
-   Disable SoPlex support.
-
---with-coin[=PREFIX]
-
-   Enable support for COIN-OR solvers (CLP and CBC). You should
-   specify the prefix too. (by default, COIN-OR tools install
-   themselves to the source code directory). This command enables the
-   solvers that are actually found.
-
---with-coin-includedir=DIR
-
-   The directory where the COIN-OR header files are located. This is
-   only useful when the COIN-OR headers and libraries are not under
-   the same prefix (which is unlikely).
-
---with-coin-libdir=DIR
-
-   The directory where the COIN-OR libraries are located. This is only
-   useful when the COIN-OR headers and libraries are not under the
-   same prefix (which is unlikely).
-
---without-coin
-
-   Disable COIN-OR support.
-
+  Root directory prefixes of optional third party libraries.
 
 Makefile Variables
 ==================
 
-Some Makefile variables are reserved by the GNU Coding Standards for
-the use of the "user" - the person building the package. For instance,
-CXX and CXXFLAGS are such variables, and have the same meaning as
-explained in the previous section. These variables can be set on the
-command line when invoking `make' like this:
-`make [VARIABLE=VALUE]...'
+make VERBOSE=1
 
-WARNINGCXXFLAGS is a non-standard Makefile variable introduced by us
-to hold several compiler flags related to warnings. Its default value
-can be overridden when invoking `make'. For example to disable all
-warning flags use `make WARNINGCXXFLAGS='.
-
-In order to turn off a single flag from the default set of warning
-flags, you can use the CXXFLAGS variable, since this is passed after
-WARNINGCXXFLAGS. For example to turn off `-Wold-style-cast' (which is
-used by default when g++ is detected) you can use
-`make CXXFLAGS="-g -O2 -Wno-old-style-cast"'.
+   This results in a more verbose output by showing the full
+   compiler and linker commands.
Index: LICENSE
===================================================================
--- LICENSE	(revision 959)
+++ LICENSE	(revision 1148)
@@ -2,5 +2,5 @@
 copyright/license.
 
-Copyright (C) 2003-2010 Egervary Jeno Kombinatorikus Optimalizalasi
+Copyright (C) 2003-2012 Egervary Jeno Kombinatorikus Optimalizalasi
 Kutatocsoport (Egervary Combinatorial Optimization Research Group,
 EGRES).
Index: kefile.am
===================================================================
--- Makefile.am	(revision 840)
+++ 	(revision )
@@ -1,80 +1,0 @@
-ACLOCAL_AMFLAGS = -I m4
-
-AM_CXXFLAGS = $(WARNINGCXXFLAGS)
-
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
-LDADD = $(top_builddir)/lemon/libemon.la
-
-EXTRA_DIST = \
-	AUTHORS \
-	LICENSE \
-	m4/lx_check_cplex.m4 \
-	m4/lx_check_glpk.m4 \
-	m4/lx_check_soplex.m4 \
-	m4/lx_check_coin.m4 \
-	CMakeLists.txt \
-	cmake/FindGhostscript.cmake \
-	cmake/FindCPLEX.cmake \
-	cmake/FindGLPK.cmake \
-	cmake/FindCOIN.cmake \
-	cmake/LEMONConfig.cmake.in \
-	cmake/version.cmake.in \
-	cmake/version.cmake \
-	cmake/nsis/lemon.ico \
-	cmake/nsis/uninstall.ico
-
-pkgconfigdir = $(libdir)/pkgconfig
-lemondir = $(pkgincludedir)
-bitsdir = $(lemondir)/bits
-conceptdir = $(lemondir)/concepts
-pkgconfig_DATA =
-lib_LTLIBRARIES =
-lemon_HEADERS =
-bits_HEADERS =
-concept_HEADERS =
-noinst_HEADERS =
-noinst_PROGRAMS =
-bin_PROGRAMS =
-check_PROGRAMS =
-dist_bin_SCRIPTS =
-TESTS =
-XFAIL_TESTS =
-
-include lemon/Makefile.am
-include test/Makefile.am
-include doc/Makefile.am
-include tools/Makefile.am
-include scripts/Makefile.am
-
-DIST_SUBDIRS = demo
-
-demo:
-	$(MAKE) $(AM_MAKEFLAGS) -C demo
-
-MRPROPERFILES = \
-	aclocal.m4 \
-	config.h.in \
-	config.h.in~ \
-	configure \
-	Makefile.in \
-	build-aux/config.guess \
-	build-aux/config.sub \
-	build-aux/depcomp \
-	build-aux/install-sh \
-	build-aux/ltmain.sh \
-	build-aux/missing \
-	doc/doxygen.log
-
-mrproper:
-	$(MAKE) $(AM_MAKEFLAGS) maintainer-clean
-	-rm -f $(MRPROPERFILES)
-
-dist-bz2: dist
-	zcat $(PACKAGE)-$(VERSION).tar.gz | \
-	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
-
-distcheck-bz2: distcheck
-	zcat $(PACKAGE)-$(VERSION).tar.gz | \
-	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
-
-.PHONY: demo mrproper dist-bz2 distcheck-bz2
Index: NEWS
===================================================================
--- NEWS	(revision 1277)
+++ NEWS	(revision 1281)
@@ -1,60 +1,99 @@
-2013-08-10 Version 1.2.4 released
-
-        Bugfix release.
-
-        #432: Add missing doc/template.h and doc/references.bib to release
-              tarball
-        #433: Support shared library build
-        ----: Update CPLEX lookup
-        ----: Make CBC interface compatible with latest CBC releases
-        ----: Intel C++ compatibility fixes
-        #441: Fix buggy reinitialization in _solver_bits::VarIndex::clear()
-        #444: Bugfix in path copy constructors and assignment operators
-        #447: Bugfix in AllArcLookUp<>
-        #448: Bugfix in adaptor_test.cc
-        #449: Fix clang compilation warnings and errors
-        #440: Fix a bug + remove redundant typedefs in dimacs-solver
-        #453: Avoid GCC 4.7 compiler warnings
-        #445: Fix missing initialization in CplexEnv::CplexEnv()
-        #461: Bugfix in assert.h
-        #470: Fix compilation issues related to various gcc versions
-        #439: Bugfix in biNodeConnected()
-        #469: Bugfix in test/maps_test.cc
-
-2011-11-09 Version 1.2.3 released
-
-        Bugfix release.
-
-        #428: Add missing lemon/lemon.pc.cmake to the release tarball
-        #429: Fix VS warnings
-        #430: Fix LpBase::Constr two-side limit bug
-
-2011-08-08 Version 1.2.2 released
-
-        Bugfix release.
-
-        #392: Bug fix in Dfs::start(s,t)
-        #414: Fix wrong initialization in Preflow
-        #404: Update Doxygen configuration
-        #416: Support tests with valgrind
-        #418: Better Win CodeBlock/MinGW support
-        #419: Backport build environment improvements from the main branch
-              - Build of mip_test and lp_test precede the running of the tests
-              - Also search for coin libs under ${COIN_ROOT_DIR}/lib/coin
-              - Do not look for COIN_VOL libraries
-        #382: Allow lgf file without Arc maps
-        #417: Bug fix in CostScaling
-
-2010-10-21 Version 1.2.1 released
-
-        Bugfix release.
-
-        #366: Fix Pred[Matrix]MapPath::empty()
-        #371: Bug fix in (di)graphCopy()
-              The target graph is cleared before adding nodes and arcs/edges.
-
-        #364: Add missing UndirectedTags
-        #368: Fix the usage of std::numeric_limits<>::min() in Network Simplex
-        #372: Fix a critical bug in preflow
+2013-08-10 Version 1.3 released
+
+        This is major feature release
+
+        * New data structures
+
+          #69 : Bipartite graph concepts and implementations
+
+        * New algorithms
+
+          #177: Port Edmonds-Karp algorithm
+          #380, #405: Heuristic algorithm for the max clique problem
+          #386: Heuristic algorithms for symmetric TSP
+          ----: Nagamochi-Ibaraki algorithm [5087694945e4]
+          #397, #56: Max. cardinality search
+
+        * Other new features
+
+          #223: Thread safe graph and graph map implementations
+          #442: Different TimeStamp print formats
+          #457: File export functionality to LpBase
+          #362: Bidirectional iterator support for radixSort()
+
+        * Implementation improvements
+
+          ----: Network Simplex
+                #391: Better update process, pivot rule and arc mixing
+                #435: Improved Altering List pivot rule
+          #417: Various fine tunings in CostScaling
+          #438: Optional iteration limit in HowardMmc
+          #436: Ensure strongly polynomial running time for CycleCanceling
+                while keeping the same performance
+          ----: Make the CBC interface be compatible with latest CBC releases
+                [ee581a0ecfbf]
+
+        * CMAKE has become the default build environment (#434)
+
+          ----: Autotool support has been dropped
+          ----: Improved LP/MIP configuration
+                #465: Enable/disable options for LP/MIP backends
+                #446: Better CPLEX discovery
+                #460: Add cmake config to find SoPlex
+          ----: Allow CPACK configuration on all platforms
+          #390: Add 'Maintainer' CMAKE build type
+          #388: Add 'check' target.
+          #401: Add contrib dir
+          #389: Better version string setting in CMAKE
+          #433: Support shared library build    
+          #416: Support testing with valgrind
+  
+        * Doc improvements
+
+          #395: SOURCE_BROWSER Doxygen switch is configurable from CMAKE
+                update-external-tags CMAKE target
+          #455: Optionally use MathJax for rendering the math formulae
+          #402, #437, #459, #456, #463: Various doc improvements
+
+        * Bugfixes (compared to release 1.2):
+
+          #432: Add missing doc/template.h and doc/references.bib to release
+                tarball
+          ----: Intel C++ compatibility fixes
+          #441: Fix buggy reinitialization in _solver_bits::VarIndex::clear()
+          #444: Bugfix in path copy constructors and assignment operators
+          #447: Bugfix in AllArcLookUp<>
+          #448: Bugfix in adaptor_test.cc
+          #449: Fix clang compilation warnings and errors
+          #440: Fix a bug + remove redundant typedefs in dimacs-solver
+          #453: Avoid GCC 4.7 compiler warnings
+          #445: Fix missing initialization in CplexEnv::CplexEnv()
+          #428: Add missing lemon/lemon.pc.cmake to the release tarball
+          #393: Create and install lemon.pc
+          #429: Fix VS warnings
+          #430: Fix LpBase::Constr two-side limit bug
+          #392: Bug fix in Dfs::start(s,t)
+          #414: Fix wrong initialization in Preflow
+          #418: Better Win CodeBlock/MinGW support
+          #419: Build environment improvements
+                - Build of mip_test and lp_test precede the running of the tests
+                - Also search for coin libs under ${COIN_ROOT_DIR}/lib/coin
+                - Do not look for COIN_VOL libraries
+          #382: Allow lgf file without Arc maps
+          #417: Bug fix in CostScaling
+          #366: Fix Pred[Matrix]MapPath::empty()
+          #371: Bug fix in (di)graphCopy()
+                The target graph is cleared before adding nodes and arcs/edges.
+          #364: Add missing UndirectedTags
+          #368: Fix the usage of std::numeric_limits<>::min() in Network Simplex
+          #372: Fix a critical bug in preflow
+          #461: Bugfix in assert.h
+          #470: Fix compilation issues related to various gcc versions
+          #446: Fix #define indicating CPLEX availability
+          #294: Add explicit namespace to
+                ignore_unused_variable_warning() usages
+          #420: Bugfix in IterableValueMap
+          #439: Bugfix in biNodeConnected()
+
 
 2010-03-19 Version 1.2 released
Index: cmake/FindCOIN.cmake
===================================================================
--- cmake/FindCOIN.cmake	(revision 1120)
+++ cmake/FindCOIN.cmake	(revision 1232)
@@ -109,9 +109,2 @@
   COIN_BZ2_LIBRARY
 )
-
-IF(COIN_FOUND)
-  SET(LEMON_HAVE_LP TRUE)
-  SET(LEMON_HAVE_MIP TRUE)
-  SET(LEMON_HAVE_CLP TRUE)
-  SET(LEMON_HAVE_CBC TRUE)
-ENDIF(COIN_FOUND)
Index: ake/FindCPLEX.cmake
===================================================================
--- cmake/FindCPLEX.cmake	(revision 1119)
+++ 	(revision )
@@ -1,40 +1,0 @@
-SET(CPLEX_ROOT_DIR "" CACHE PATH "CPLEX root directory")
-
-FIND_PATH(CPLEX_INCLUDE_DIR
-  ilcplex/cplex.h
-  PATHS "C:/ILOG/CPLEX/include"
-  PATHS "/opt/ilog/cplex/include"
-  HINTS ${CPLEX_ROOT_DIR}/include
-)
-FIND_LIBRARY(CPLEX_LIBRARY
-  cplex
-  PATHS "C:/ILOG/CPLEX/lib/msvc7/stat_mda"
-  PATHS "/opt/ilog/cplex/bin"
-  HINTS ${CPLEX_ROOT_DIR}/bin
-  HINTS ${CPLEX_ROOT_DIR}/lib
-)
-
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR)
-
-FIND_PATH(CPLEX_BIN_DIR
-  cplex.dll
-  PATHS "C:/ILOG/CPLEX/bin/x86_win32"
-  HINTS ${CPLEX_ROOT_DIR}/bin
-)
-
-IF(CPLEX_FOUND)
-  SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR})
-  SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY})
-  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
-    SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
-  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
-ENDIF(CPLEX_FOUND)
-
-MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR)
-
-IF(CPLEX_FOUND)
-  SET(LEMON_HAVE_LP TRUE)
-  SET(LEMON_HAVE_MIP TRUE)
-  SET(LEMON_HAVE_CPLEX TRUE)
-ENDIF(CPLEX_FOUND)
Index: cmake/FindGLPK.cmake
===================================================================
--- cmake/FindGLPK.cmake	(revision 685)
+++ cmake/FindGLPK.cmake	(revision 1232)
@@ -54,8 +54,2 @@
 
 MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
-
-IF(GLPK_FOUND)
-  SET(LEMON_HAVE_LP TRUE)
-  SET(LEMON_HAVE_MIP TRUE)
-  SET(LEMON_HAVE_GLPK TRUE)
-ENDIF(GLPK_FOUND)
Index: cmake/FindILOG.cmake
===================================================================
--- cmake/FindILOG.cmake	(revision 1232)
+++ cmake/FindILOG.cmake	(revision 1232)
@@ -0,0 +1,102 @@
+FIND_PATH(ILOG_ROOT_DIR
+  NAMES cplex
+  DOC "CPLEX STUDIO root directory"
+  PATHS /opt/ibm/ILOG /usr/local/ibm/ILOG /usr/local/ILOG /usr/local/ilog
+  PATHS "$ENV{HOME}/ILOG" "$ENV{HOME}/.local/ILOG"
+  PATHS "$ENV{HOME}/ibm/ILOG" "$ENV{HOME}/.local/ibm/ILOG"
+  PATHS "C:/Program Files/IBM/ILOG" 
+  PATH_SUFFIXES "CPLEX_Studio126" "CPLEX_Studio125"
+  "CPLEX_Studio124" "CPLEX_Studio123" "CPLEX_Studio122"
+  NO_DEFAULT_PATH
+)
+
+IF(WIN32)
+  IF(MSVC_VERSION STREQUAL "1400")
+    SET(ILOG_WIN_COMPILER "windows_vs2005")
+  ELSEIF(MSVC_VERSION STREQUAL "1500")
+    SET(ILOG_WIN_COMPILER "windows_vs2008")
+  ELSEIF(MSVC_VERSION STREQUAL "1600")
+    SET(ILOG_WIN_COMPILER "windows_vs2010")
+  ELSE()
+    SET(ILOG_WIN_COMPILER "windows_vs2008")
+  ENDIF()
+  IF(CMAKE_CL_64)
+    SET(ILOG_WIN_COMPILER "x64_${ILOG_WIN_COMPILER}")
+    SET(ILOG_WIN_PLATFORM "x64_win32")
+  ELSE()
+    SET(ILOG_WIN_COMPILER "x86_${ILOG_WIN_COMPILER}")
+    SET(ILOG_WIN_PLATFORM "x86_win32")
+  ENDIF()
+ENDIF()
+
+FIND_PATH(ILOG_CPLEX_ROOT_DIR
+  NAMES include/ilcplex
+  HINTS ${ILOG_ROOT_DIR}/cplex ${ILOG_ROOT_DIR}/cplex121
+  ${ILOG_ROOT_DIR}/cplex122 ${ILOG_ROOT_DIR}/cplex123
+  DOC "CPLEX root directory"
+  NO_DEFAULT_PATH
+)
+
+FIND_PATH(ILOG_CONCERT_ROOT_DIR
+  NAMES include/ilconcert
+  HINTS ${ILOG_ROOT_DIR}/concert ${ILOG_ROOT_DIR}/concert29
+  DOC "CONCERT root directory"
+  NO_DEFAULT_PATH
+)
+
+FIND_PATH(ILOG_CPLEX_INCLUDE_DIR
+  ilcplex/cplex.h
+  HINTS ${ILOG_CPLEX_ROOT_DIR}/include
+  NO_DEFAULT_PATH
+)
+
+FIND_PATH(ILOG_CONCERT_INCLUDE_DIR
+  ilconcert/ilobasic.h
+  HINTS ${ILOG_CONCERT_ROOT_DIR}/include
+  NO_DEFAULT_PATH
+)
+
+FIND_LIBRARY(ILOG_CPLEX_LIBRARY
+  cplex cplex121 cplex122 cplex123 cplex124
+  HINTS ${ILOG_CPLEX_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
+  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
+  ${ILOG_CPLEX_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
+  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
+  ${ILOG_CPLEX_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
+  NO_DEFAULT_PATH
+  )
+
+FIND_LIBRARY(ILOG_CONCERT_LIBRARY
+  concert
+  HINTS ${ILOG_CONCERT_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
+  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
+  ${ILOG_CONCERT_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
+  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
+  ${ILOG_CONCERT_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
+  NO_DEFAULT_PATH
+  )
+
+FIND_FILE(ILOG_CPLEX_DLL
+  cplex121.dll cplex122.dll cplex123.dll cplex124.dll
+  HINTS ${ILOG_CPLEX_ROOT_DIR}/bin/${ILOG_WIN_PLATFORM}
+  NO_DEFAULT_PATH
+  )
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ILOG
+  DEFAULT_MSG ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR
+  )
+
+IF(ILOG_FOUND)
+  SET(ILOG_INCLUDE_DIRS ${ILOG_CPLEX_INCLUDE_DIR} ${ILOG_CONCERT_INCLUDE_DIR})
+  SET(ILOG_LIBRARIES ${ILOG_CPLEX_LIBRARY} ${ILOG_CONCERT_LIBRARY})
+  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    # SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
+    SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread")
+  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ENDIF(ILOG_FOUND)
+
+MARK_AS_ADVANCED(
+  ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR ILOG_CPLEX_DLL
+  ILOG_CONCERT_LIBRARY ILOG_CONCERT_INCLUDE_DIR ILOG_CONCERT_DLL
+  )
Index: cmake/FindSOPLEX.cmake
===================================================================
--- cmake/FindSOPLEX.cmake	(revision 1264)
+++ cmake/FindSOPLEX.cmake	(revision 1264)
@@ -0,0 +1,23 @@
+SET(SOPLEX_ROOT_DIR "" CACHE PATH "SoPlex root directory")
+
+FIND_PATH(SOPLEX_INCLUDE_DIR
+  soplex.h
+  HINTS ${SOPLEX_ROOT_DIR}/src
+)
+FIND_LIBRARY(SOPLEX_LIBRARY
+  soplex
+  HINTS ${SOPLEX_ROOT_DIR}/lib
+)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SOPLEX DEFAULT_MSG SOPLEX_LIBRARY SOPLEX_INCLUDE_DIR)
+
+IF(SOPLEX_FOUND)
+  SET(SOPLEX_INCLUDE_DIRS ${SOPLEX_INCLUDE_DIR})
+  SET(SOPLEX_LIBRARIES ${SOPLEX_LIBRARY})
+  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    SET(SOPLEX_LIBRARIES "${SOPLEX_LIBRARIES};z")
+  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ENDIF(SOPLEX_FOUND)
+
+MARK_AS_ADVANCED(SOPLEX_LIBRARY SOPLEX_INCLUDE_DIR)
Index: cmake/version.cmake.in
===================================================================
--- cmake/version.cmake.in	(revision 725)
+++ cmake/version.cmake.in	(revision 1135)
@@ -1,1 +1,1 @@
-SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
+SET(LEMON_VERSION "@LEMON_VERSION@" CACHE STRING "LEMON version string.")
Index: nfigure.ac
===================================================================
--- configure.ac	(revision 1276)
+++ 	(revision )
@@ -1,157 +1,0 @@
-dnl Process this file with autoconf to produce a configure script.
-
-dnl Version information.
-m4_define([lemon_version_number],
-          [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
-dnl m4_define([lemon_version_number], [])
-m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))])
-m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))])
-m4_define([lemon_version], [ifelse(lemon_version_number(),
-                           [],
-                           [ifelse(lemon_hg_revision(),
-                           [],
-                           [hg-tip],
-                           [lemon_hg_path().lemon_hg_revision()])],
-                           [lemon_version_number()])])
-
-AC_PREREQ([2.59])
-AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
-AC_CONFIG_AUX_DIR([build-aux])
-AC_CONFIG_MACRO_DIR([m4])
-AM_INIT_AUTOMAKE([-Wall foreign subdir-objects nostdinc])
-AC_CONFIG_SRCDIR([lemon/list_graph.h])
-AC_CONFIG_HEADERS([config.h lemon/config.h])
-
-AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
-
-dnl Do compilation tests using the C++ compiler.
-AC_LANG([C++])
-
-dnl Check the existence of long long type.
-AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
-if test x"$long_long_found" = x"yes"; then
-  AC_DEFINE([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
-fi
-
-dnl Checks for programs.
-AC_PROG_CXX
-AC_PROG_CXXCPP
-AC_PROG_INSTALL
-AC_DISABLE_SHARED
-AC_PROG_LIBTOOL
-
-AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
-AC_CHECK_PROG([python_found],[python],[yes],[no])
-AC_CHECK_PROG([gs_found],[gs],[yes],[no])
-
-dnl Detect Intel compiler.
-AC_MSG_CHECKING([whether we are using the Intel C++ compiler])
-AC_COMPILE_IFELSE([#ifndef __INTEL_COMPILER
-choke me
-#endif], [ICC=[yes]], [ICC=[no]])
-if test x"$ICC" = x"yes"; then
-  AC_MSG_RESULT([yes])
-else
-  AC_MSG_RESULT([no])
-fi
-
-dnl Set custom compiler flags when using g++.
-if test "$GXX" = yes -a "$ICC" = no; then
-  WARNINGCXXFLAGS="-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
-fi
-AC_SUBST([WARNINGCXXFLAGS])
-
-dnl Checks for libraries.
-LX_CHECK_GLPK
-LX_CHECK_CPLEX
-LX_CHECK_SOPLEX
-LX_CHECK_COIN
-
-AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
-AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
-
-dnl Disable/enable building the binary tools.
-AC_ARG_ENABLE([tools],
-AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
-AS_HELP_STRING([--disable-tools], [do not build additional tools]),
-              [], [enable_tools=yes])
-AC_MSG_CHECKING([whether to build the additional tools])
-if test x"$enable_tools" != x"no"; then
-  AC_MSG_RESULT([yes])
-else
-  AC_MSG_RESULT([no])
-fi
-AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
-
-dnl Support for running test cases using valgrind.
-use_valgrind=no
-AC_ARG_ENABLE([valgrind],
-AS_HELP_STRING([--enable-valgrind], [use valgrind when running tests]),
-              [use_valgrind=yes])
-
-if [[ "$use_valgrind" = "yes" ]]; then
-  AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
-
-  if [[ "$HAVE_VALGRIND" = "no" ]]; then
-    AC_MSG_ERROR([Valgrind not found in PATH.])
-  fi
-fi
-AM_CONDITIONAL(USE_VALGRIND, [test "$use_valgrind" = "yes"])
-
-dnl Checks for header files.
-AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_C_INLINE
-AC_TYPE_SIZE_T
-AC_HEADER_TIME
-AC_STRUCT_TM
-
-dnl Checks for library functions.
-AC_HEADER_STDC
-AC_CHECK_FUNCS(gettimeofday times ctime_r)
-
-dnl Add dependencies on files generated by configure.
-AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
-  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
-
-AC_CONFIG_FILES([
-Makefile
-demo/Makefile
-cmake/version.cmake
-doc/Doxyfile
-doc/mainpage.dox
-lemon/lemon.pc
-])
-
-AC_OUTPUT
-
-echo
-echo '****************************** SUMMARY ******************************'
-echo
-echo Package version............... : $PACKAGE-$VERSION
-echo
-echo C++ compiler.................. : $CXX
-echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
-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 CBC support................... : $lx_cbc_found
-echo
-echo Build additional tools........ : $enable_tools
-echo Use valgrind for tests........ : $use_valgrind
-echo
-echo The packace will be installed in
-echo -n '  '
-echo $prefix.
-echo
-echo '*********************************************************************'
-
-echo
-echo Configure complete, now type \'make\' and then \'make install\'.
-echo
Index: contrib/CMakeLists.txt
===================================================================
--- contrib/CMakeLists.txt	(revision 1031)
+++ contrib/CMakeLists.txt	(revision 1031)
@@ -0,0 +1,19 @@
+INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}
+  ${PROJECT_BINARY_DIR}
+)
+
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
+
+# Uncomment (and adjust) the following two lines. 'myprog' is the name
+# of the final executable ('.exe' will automatically be added to the
+# name on Windows) and 'myprog-main.cc' is the source code it is
+# compiled from. You can add more source files separated by
+# whitespaces. Moreover, you can add multiple similar blocks if you
+# want to build more than one executables.
+
+# ADD_EXECUTABLE(myprog myprog-main.cc)
+# TARGET_LINK_LIBRARIES(myprog lemon)
+
Index: mo/Makefile.am
===================================================================
--- demo/Makefile.am	(revision 611)
+++ 	(revision )
@@ -1,17 +1,0 @@
-AM_CXXFLAGS = $(WARNINGCXXFLAGS)
-
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
-LDADD = $(top_builddir)/lemon/libemon.la
-
-EXTRA_DIST = \
-	CMakeLists.txt \
-	digraph.lgf
-
-noinst_PROGRAMS = \
-	arg_parser_demo \
-	graph_to_eps_demo \
-	lgf_demo
-
-arg_parser_demo_SOURCES = arg_parser_demo.cc
-graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
-lgf_demo_SOURCES = lgf_demo.cc
Index: doc/CMakeLists.txt
===================================================================
--- doc/CMakeLists.txt	(revision 1110)
+++ doc/CMakeLists.txt	(revision 1251)
@@ -5,4 +5,11 @@
 
 SET(LEMON_DOC_SOURCE_BROWSER "NO" CACHE STRING "Include source into the doc (YES/NO).")
+SET(LEMON_DOC_USE_MATHJAX "NO" CACHE STRING "Use MathJax to display math formulae (YES/NO).")
+SET(LEMON_DOC_MATHJAX_RELPATH "http://www.mathjax.org/mathjax" CACHE STRING "MathJax library location.")
+
+SET(LEMON_DOC_LIBSTDC++_URL
+  "http://gcc.gnu.org/onlinedocs/gcc-4.7.3/libstdc++/api"
+  CACHE STRING "GCC libstdc++ doxygen doc url.")
+
 
 CONFIGURE_FILE(
@@ -18,4 +25,13 @@
 )
 
+# Copy doc from source (if exists)
+IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/html AND 
+    NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html/index.html)
+  MESSAGE(STATUS "Copy doc from source tree")
+  EXECUTE_PROCESS(
+    COMMAND cmake -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/html ${CMAKE_CURRENT_BINARY_DIR}/html
+    )
+ENDIF()
+
 IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
   FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
@@ -24,20 +40,21 @@
     COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
     COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
-    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r20 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/adaptors2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/adaptors2.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r40 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/tsp.png ${CMAKE_CURRENT_SOURCE_DIR}/images/tsp.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
     COMMAND ${CMAKE_COMMAND} -E remove_directory html
-    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
     COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
     WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
@@ -64,10 +81,5 @@
 IF(WGET_FOUND)
 ADD_CUSTOM_TARGET(update-external-tags
-  COMMAND ${CMAKE_COMMAND} -E make_directory dl
-  # COMMAND ${CMAKE_COMMAND} -E copy libstdc++.tag dl
-  COMMAND ${WGET_EXECUTABLE} wget -P dl -N libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag
-  COMMAND ${CMAKE_COMMAND} -E rename dl/libstdc++.tag libstdc++.tag
-  COMMAND ${CMAKE_COMMAND} -E remove dl/libstdc++.tag
-  COMMAND ${CMAKE_COMMAND} -E remove_directory dl
+  COMMAND ${WGET_EXECUTABLE} -N ${LEMON_DOC_LIBSTDC++_URL}/libstdc++.tag
   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
   )
Index: doc/Doxyfile.in
===================================================================
--- doc/Doxyfile.in	(revision 1110)
+++ doc/Doxyfile.in	(revision 1251)
@@ -78,4 +78,5 @@
 FILE_VERSION_FILTER    = 
 LAYOUT_FILE            = "@abs_top_srcdir@/doc/DoxygenLayout.xml"
+CITE_BIB_FILES         = "@abs_top_srcdir@/doc/references.bib"
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
@@ -96,8 +97,8 @@
                          "@abs_top_srcdir@/lemon/concepts" \
                          "@abs_top_srcdir@/demo" \
+                         "@abs_top_srcdir@/contrib" \
                          "@abs_top_srcdir@/tools" \
                          "@abs_top_srcdir@/test/test_tools.h" \
-                         "@abs_top_builddir@/doc/mainpage.dox" \
-                         "@abs_top_builddir@/doc/references.dox"
+                         "@abs_top_builddir@/doc/mainpage.dox"
 INPUT_ENCODING         = UTF-8
 FILE_PATTERNS          = *.h \
@@ -182,6 +183,6 @@
 FORMULA_FONTSIZE       = 10
 FORMULA_TRANSPARENT    = YES
-USE_MATHJAX            = NO
-MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+USE_MATHJAX            = @LEMON_DOC_USE_MATHJAX@
+MATHJAX_RELPATH        = @LEMON_DOC_MATHJAX_RELPATH@
 SEARCHENGINE           = YES
 SERVER_BASED_SEARCH    = NO
@@ -253,5 +254,5 @@
 # Configuration::additions related to external references
 #---------------------------------------------------------------------------
-TAGFILES               = "@abs_top_builddir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
+TAGFILES               = "@abs_top_builddir@/doc/libstdc++.tag = @LEMON_DOC_LIBSTDC++_URL@"
 GENERATE_TAGFILE       = html/lemon.tag
 ALLEXTERNALS           = NO
Index: doc/DoxygenLayout.xml
===================================================================
--- doc/DoxygenLayout.xml	(revision 1036)
+++ doc/DoxygenLayout.xml	(revision 1251)
@@ -18,5 +18,4 @@
       <tab type="globals" visible="yes" title="" intro=""/>
     </tab>
-    <tab type="dirs" visible="yes" title="" intro=""/>
     <tab type="examples" visible="yes" title="" intro=""/>
     <tab type="pages" visible="yes" title="" intro=""/>
Index: c/Makefile.am
===================================================================
--- doc/Makefile.am	(revision 1115)
+++ 	(revision )
@@ -1,125 +1,0 @@
-EXTRA_DIST += \
-	doc/Doxyfile.in \
-	doc/DoxygenLayout.xml \
-	doc/coding_style.dox \
-	doc/dirs.dox \
-	doc/groups.dox \
-	doc/lgf.dox \
-	doc/license.dox \
-	doc/mainpage.dox \
-	doc/migration.dox \
-	doc/min_cost_flow.dox \
-	doc/named-param.dox \
-	doc/namespaces.dox \
-	doc/references.bib \
-	doc/template.h \
-	doc/html \
-	doc/CMakeLists.txt
-
-DOC_EPS_IMAGES18 = \
-	grid_graph.eps \
-	nodeshape_0.eps \
-	nodeshape_1.eps \
-	nodeshape_2.eps \
-	nodeshape_3.eps \
-	nodeshape_4.eps
-
-DOC_EPS_IMAGES27 = \
-	bipartite_matching.eps \
-	bipartite_partitions.eps \
-	connected_components.eps \
-	edge_biconnected_components.eps \
-	matching.eps \
-	node_biconnected_components.eps \
-	planar.eps \
-	strongly_connected_components.eps
-
-DOC_EPS_IMAGES = \
-	$(DOC_EPS_IMAGES18) \
-	$(DOC_EPS_IMAGES27)
-
-DOC_PNG_IMAGES = \
-	$(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png)
-
-EXTRA_DIST += $(DOC_EPS_IMAGES:%=doc/images/%)
-
-doc/html:
-	$(MAKE) $(AM_MAKEFLAGS) html
-
-GS_COMMAND=gs -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4
-
-$(DOC_EPS_IMAGES18:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
-	-mkdir doc/gen-images
-	if test ${gs_found} = yes; then \
-	  $(GS_COMMAND) -sDEVICE=pngalpha -r18 -sOutputFile=$@ $<; \
-	else \
-	  echo; \
-	  echo "Ghostscript not found."; \
-	  echo; \
-	  exit 1; \
-	fi
-
-$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
-	-mkdir doc/gen-images
-	if test ${gs_found} = yes; then \
-	  $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
-	else \
-	  echo; \
-	  echo "Ghostscript not found."; \
-	  echo; \
-	  exit 1; \
-	fi
-
-references.dox: doc/references.bib
-	if test ${python_found} = yes; then \
-	  cd doc; \
-	  python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
-	  cd ..; \
-	else \
-	  echo; \
-	  echo "Python not found."; \
-	  echo; \
-	  exit 1; \
-	fi
-
-html-local: $(DOC_PNG_IMAGES) references.dox
-	if test ${doxygen_found} = yes; then \
-	  cd doc; \
-	  doxygen Doxyfile; \
-	  cd ..; \
-	else \
-	  echo; \
-	  echo "Doxygen not found."; \
-	  echo; \
-	  exit 1; \
-	fi
-
-clean-local:
-	-rm -rf doc/html
-	-rm -f doc/doxygen.log
-	-rm -f $(DOC_PNG_IMAGES)
-	-rm -rf doc/gen-images
-
-update-external-tags:
-	wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \
-	mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \
-	rm doc/libstdc++.tag.tmp
-
-install-html-local: doc/html
-	@$(NORMAL_INSTALL)
-	$(mkinstalldirs) $(DESTDIR)$(htmldir)/html
-	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
-	  f="`echo $$p | sed -e 's|^.*/||'`"; \
-	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
-	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
-	done
-
-uninstall-local:
-	@$(NORMAL_UNINSTALL)
-	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
-	  f="`echo $$p | sed -e 's|^.*/||'`"; \
-	  echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
-	  rm -f $(DESTDIR)$(htmldir)/html/$$f; \
-	done
-
-.PHONY: update-external-tags
Index: doc/coding_style.dox
===================================================================
--- doc/coding_style.dox	(revision 463)
+++ doc/coding_style.dox	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -99,8 +99,8 @@
 \subsection pri-loc-var Private member variables
 
-Private member variables should start with underscore
+Private member variables should start with underscore.
 
 \code
-_start_with_underscores
+_start_with_underscore
 \endcode
 
Index: doc/dirs.dox
===================================================================
--- doc/dirs.dox	(revision 463)
+++ doc/dirs.dox	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -32,4 +32,17 @@
 documentation.
 */
+
+/**
+\dir contrib
+\brief Directory for user contributed source codes.
+
+You can place your own C++ code using LEMON into this directory, which
+will compile to an executable along with LEMON when you build the
+library. This is probably the easiest way of compiling short to medium
+codes, for this does require neither a LEMON installed system-wide nor
+adding several paths to the compiler.
+
+Please have a look at <tt>contrib/CMakeLists.txt</tt> for
+instruction on how to add your own files into the build process.  */
 
 /**
Index: doc/groups.dox
===================================================================
--- doc/groups.dox	(revision 963)
+++ doc/groups.dox	(revision 1271)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -113,4 +113,12 @@
 detailed documentation of particular adaptors.
 
+Since the adaptor classes conform to the \ref graph_concepts "graph concepts",
+an adaptor can even be applied to another one.
+The following image illustrates a situation when a \ref SubDigraph adaptor
+is applied on a digraph and \ref Undirector is applied on the subgraph.
+
+\image html adaptors2.png
+\image latex adaptors2.eps "Using graph adaptors" width=\textwidth
+
 The behavior of graph adaptors can be very different. Some of them keep
 capabilities of the original graph while in other cases this would be
@@ -287,4 +295,12 @@
 
 /**
+@defgroup matrices Matrices
+@ingroup auxdat
+\brief Two dimensional data storages implemented in LEMON.
+
+This group contains two dimensional data storages implemented in LEMON.
+*/
+
+/**
 @defgroup algs Algorithms
 \brief This group contains the several algorithms
@@ -302,5 +318,5 @@
 This group contains the common graph search algorithms, namely
 \e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
-\ref clrs01algorithms.
+\cite clrs01algorithms.
 */
 
@@ -311,5 +327,5 @@
 
 This group contains the algorithms for finding shortest paths in digraphs
-\ref clrs01algorithms.
+\cite clrs01algorithms.
 
  - \ref Dijkstra algorithm for finding shortest paths from a source node
@@ -319,4 +335,8 @@
    but the digraph should not contain directed cycles with negative total
    length.
+ - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
+   for solving the \e all-pairs \e shortest \e paths \e problem when arc
+   lenghts can be either positive or negative, but the digraph should
+   not contain directed cycles with negative total length.
  - \ref Suurballe A successive shortest path algorithm for finding
    arc-disjoint paths between two nodes having minimum total length.
@@ -329,5 +349,5 @@
 
 This group contains the algorithms for finding minimum cost spanning
-trees and arborescences \ref clrs01algorithms.
+trees and arborescences \cite clrs01algorithms.
 */
 
@@ -338,5 +358,5 @@
 
 This group contains the algorithms for finding maximum flows and
-feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
+feasible circulations \cite clrs01algorithms, \cite amo93networkflows.
 
 The \e maximum \e flow \e problem is to find a flow of maximum value between
@@ -352,8 +372,18 @@
 \f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
 
-\ref Preflow is an efficient implementation of Goldberg-Tarjan's
-preflow push-relabel algorithm \ref goldberg88newapproach for finding
-maximum flows. It also provides functions to query the minimum cut,
-which is the dual problem of maximum flow.
+LEMON contains several algorithms for solving maximum flow problems:
+- \ref EdmondsKarp Edmonds-Karp algorithm
+  \cite edmondskarp72theoretical.
+- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
+  \cite goldberg88newapproach.
+- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
+  \cite dinic70algorithm, \cite sleator83dynamic.
+- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
+  \cite goldberg88newapproach, \cite sleator83dynamic.
+
+In most cases the \ref Preflow algorithm provides the
+fastest method for computing a maximum flow. All implementations
+also provide functions to query the minimum cut, which is the dual
+problem of maximum flow.
 
 \ref Circulation is a preflow push-relabel algorithm implemented directly
@@ -370,23 +400,39 @@
 
 This group contains the algorithms for finding minimum cost flows and
-circulations \ref amo93networkflows. For more information about this
-problem and its dual solution, see \ref min_cost_flow
+circulations \cite amo93networkflows. For more information about this
+problem and its dual solution, see: \ref min_cost_flow
 "Minimum Cost Flow Problem".
 
 LEMON contains several algorithms for this problem.
  - \ref NetworkSimplex Primal Network Simplex algorithm with various
-   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
+   pivot strategies \cite dantzig63linearprog, \cite kellyoneill91netsimplex.
  - \ref CostScaling Cost Scaling algorithm based on push/augment and
-   relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
-   \ref bunnagel98efficient.
+   relabel operations \cite goldberg90approximation, \cite goldberg97efficient,
+   \cite bunnagel98efficient.
  - \ref CapacityScaling Capacity Scaling algorithm based on the successive
-   shortest path method \ref edmondskarp72theoretical.
+   shortest path method \cite edmondskarp72theoretical.
  - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
-   strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
-
-In general NetworkSimplex is the most efficient implementation,
-but in special cases other algorithms could be faster.
+   strongly polynomial \cite klein67primal, \cite goldberg89cyclecanceling.
+
+In general, \ref NetworkSimplex and \ref CostScaling are the most efficient
+implementations.
+\ref NetworkSimplex is usually the fastest on relatively small graphs (up to
+several thousands of nodes) and on dense graphs, while \ref CostScaling is
+typically more efficient on large graphs (e.g. hundreds of thousands of
+nodes or above), especially if they are sparse.
+However, other algorithms could be faster in special cases.
 For example, if the total supply and/or capacities are rather small,
-CapacityScaling is usually the fastest algorithm (without effective scaling).
+\ref CapacityScaling is usually the fastest algorithm
+(without effective scaling).
+
+These classes are intended to be used with integer-valued input data
+(capacities, supply values, and costs), except for \ref CapacityScaling,
+which is capable of handling real-valued arc costs (other numerical
+data are required to be integer).
+
+For more details about these implementations and for a comprehensive
+experimental study, see the paper \cite KiralyKovacs12MCF.
+It also compares these codes to other publicly available
+minimum cost flow solvers.
 */
 
@@ -412,4 +458,6 @@
 - \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
   in directed graphs.
+- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
+  calculating minimum cut in undirected graphs.
 - \ref GomoryHu "Gomory-Hu tree computation" for calculating
   all-pairs minimum cut in undirected graphs.
@@ -425,5 +473,5 @@
 
 This group contains the algorithms for finding minimum mean cycles
-\ref clrs01algorithms, \ref amo93networkflows.
+\cite amo93networkflows, \cite karp78characterization.
 
 The \e minimum \e mean \e cycle \e problem is to find a directed cycle
@@ -441,17 +489,15 @@
 
 LEMON contains three algorithms for solving the minimum mean cycle problem:
-- \ref KarpMmc Karp's original algorithm \ref amo93networkflows,
-  \ref dasdan98minmeancycle.
+- \ref KarpMmc Karp's original algorithm \cite karp78characterization.
 - \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
-  version of Karp's algorithm \ref dasdan98minmeancycle.
+  version of Karp's algorithm \cite hartmann93finding.
 - \ref HowardMmc Howard's policy iteration algorithm
-  \ref dasdan98minmeancycle.
-
-In practice, the \ref HowardMmc "Howard" algorithm proved to be by far the
+  \cite dasdan98minmeancycle, \cite dasdan04experimental.
+
+In practice, the \ref HowardMmc "Howard" algorithm turned out to be by far the
 most efficient one, though the best known theoretical bound on its running
 time is exponential.
 Both \ref KarpMmc "Karp" and \ref HartmannOrlinMmc "Hartmann-Orlin" algorithms
-run in time O(ne) and use space O(n<sup>2</sup>+e), but the latter one is
-typically faster due to the applied early termination scheme.
+run in time O(nm) and use space O(n<sup>2</sup>+m).
 */
 
@@ -474,4 +520,14 @@
 
 The matching algorithms implemented in LEMON:
+- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
+  for calculating maximum cardinality matching in bipartite graphs.
+- \ref PrBipartiteMatching Push-relabel algorithm
+  for calculating maximum cardinality matching in bipartite graphs.
+- \ref MaxWeightedBipartiteMatching
+  Successive shortest path algorithm for calculating maximum weighted
+  matching and maximum weighted bipartite matching in bipartite graphs.
+- \ref MinCostMaxBipartiteMatching
+  Successive shortest path algorithm for calculating minimum cost maximum
+  matching in bipartite graphs.
 - \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
   maximum cardinality matching in general graphs.
@@ -506,5 +562,5 @@
 
 /**
-@defgroup planar Planarity Embedding and Drawing
+@defgroup planar Planar Embedding and Drawing
 @ingroup algs
 \brief Algorithms for planarity checking, embedding and drawing
@@ -515,4 +571,53 @@
 \image html planar.png
 \image latex planar.eps "Plane graph" width=\textwidth
+*/
+
+/**
+@defgroup tsp Traveling Salesman Problem
+@ingroup algs
+\brief Algorithms for the symmetric traveling salesman problem
+
+This group contains basic heuristic algorithms for the the symmetric
+\e traveling \e salesman \e problem (TSP).
+Given an \ref FullGraph "undirected full graph" with a cost map on its edges,
+the problem is to find a shortest possible tour that visits each node exactly
+once (i.e. the minimum cost Hamiltonian cycle).
+
+These TSP algorithms are intended to be used with a \e metric \e cost
+\e function, i.e. the edge costs should satisfy the triangle inequality.
+Otherwise the algorithms could yield worse results.
+
+LEMON provides five well-known heuristics for solving symmetric TSP:
+ - \ref NearestNeighborTsp Neareast neighbor algorithm
+ - \ref GreedyTsp Greedy algorithm
+ - \ref InsertionTsp Insertion heuristic (with four selection methods)
+ - \ref ChristofidesTsp Christofides algorithm
+ - \ref Opt2Tsp 2-opt algorithm
+
+\ref NearestNeighborTsp, \ref GreedyTsp, and \ref InsertionTsp are the fastest
+solution methods. Furthermore, \ref InsertionTsp is usually quite effective.
+
+\ref ChristofidesTsp is somewhat slower, but it has the best guaranteed
+approximation factor: 3/2.
+
+\ref Opt2Tsp usually provides the best results in practice, but
+it is the slowest method. It can also be used to improve given tours,
+for example, the results of other algorithms.
+
+\image html tsp.png
+\image latex tsp.eps "Traveling salesman problem" width=\textwidth
+*/
+
+/**
+@defgroup approx_algs Approximation Algorithms
+@ingroup algs
+\brief Approximation algorithms.
+
+This group contains the approximation and heuristic algorithms
+implemented in LEMON.
+
+<b>Maximum Clique Problem</b>
+  - \ref GrossoLocatelliPullanMc An efficient heuristic algorithm of
+    Grosso, Locatelli, and Pullan.
 */
 
@@ -544,6 +649,23 @@
 high-level interface.
 
-The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
-\ref cplex, \ref soplex.
+The currently supported solvers are \cite glpk, \cite clp, \cite cbc,
+\cite cplex, \cite soplex.
+*/
+
+/**
+@defgroup lp_utils Tools for Lp and Mip Solvers
+@ingroup lp_group
+\brief Helper tools to the Lp and Mip solvers.
+
+This group adds some helper tools to general optimization framework
+implemented in LEMON.
+*/
+
+/**
+@defgroup metah Metaheuristics
+@ingroup gen_opt_group
+\brief Metaheuristics for LEMON library.
+
+This group contains some metaheuristic optimization tools.
 */
 
@@ -615,4 +737,6 @@
 This group contains general \c EPS drawing methods and special
 graph exporting tools.
+
+\image html graph_to_eps.png
 */
 
Index: doc/images/adaptors1.eps
===================================================================
--- doc/images/adaptors1.eps	(revision 1218)
+++ doc/images/adaptors1.eps	(revision 1218)
@@ -0,0 +1,303 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: adaptors1.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5
+%%CreationDate: Sun Feb 21 18:51:21 2010
+%%For: Peter@KOVACSPETER (PÃ©ter,U-KOVACSPETER\Peter,S-1-5-21-1774138250-1299389707-1938712334-1001)
+%%BoundingBox: 0 0 787 372
+%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 372 moveto 0 0 lineto 787 0 lineto 787 372 lineto closepath clip newpath
+-14.2 385.4 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+	/endangle exch def
+	/startangle exch def
+	/yrad exch def
+	/xrad exch def
+	/y exch def
+	/x exch def
+	/savematrix mtrx currentmatrix def
+	x y tr xrad yrad sc 0 0 1 startangle endangle arc
+	closepath
+	savematrix setmatrix
+	} def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% 
+% here starts figure with depth 60
+% Polyline
+0 slj
+0 slc
+15.000 slw
+gs  clippath
+6319 5229 m 6442 5564 l 6527 5533 l 6403 5198 l 6403 5198 l 6424 5383 l 6319 5229 l cp
+eoclip
+n 5850 3825 m
+ 6480 5535 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 6319 5229 m 6424 5383 l 6403 5198 l 6319 5229 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+5417 4044 m 5746 3905 l 5711 3822 l 5382 3961 l 5382 3961 l 5566 3933 l 5417 4044 l cp
+eoclip
+n 1575 5625 m
+ 5715 3870 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 5417 4044 m 5566 3933 l 5382 3961 l 5417 4044 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3897 3780 m 3540 3780 l 3540 3870 l 3897 3870 l 3897 3870 l 3717 3825 l 3897 3780 l cp
+eoclip
+n 5625 3825 m
+ 3555 3825 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3897 3780 m 3717 3825 l 3897 3870 l 3897 3780 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3075 4188 m 3327 3936 l 3263 3872 l 3011 4124 l 3011 4124 l 3171 4029 l 3075 4188 l cp
+eoclip
+n 1575 5625 m
+ 3285 3915 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3075 4188 m 3171 4029 l 3011 4124 l 3075 4188 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3528 2520 m 3885 2520 l 3885 2430 l 3528 2430 l 3528 2430 l 3708 2475 l 3528 2520 l cp
+eoclip
+n 1800 2475 m
+ 3870 2475 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3528 2520 m 3708 2475 l 3528 2430 l 3528 2520 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4304 2156 m 4052 2408 l 4116 2472 l 4368 2220 l 4368 2220 l 4209 2316 l 4304 2156 l cp
+eoclip
+n 5850 675 m
+ 4095 2430 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4304 2156 m 4209 2316 l 4368 2220 l 4304 2156 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+6319 2079 m 6442 2414 l 6527 2383 l 6403 2048 l 6403 2048 l 6424 2233 l 6319 2079 l cp
+eoclip
+n 5850 675 m
+ 6480 2385 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 6319 2079 m 6424 2233 l 6403 2048 l 6319 2079 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+5417 894 m 5746 755 l 5711 672 l 5382 811 l 5382 811 l 5566 783 l 5417 894 l cp
+eoclip
+n 1575 2475 m
+ 5715 720 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 5417 894 m 5566 783 l 5382 811 l 5417 894 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3528 5670 m 3885 5670 l 3885 5580 l 3528 5580 l 3528 5580 l 3708 5625 l 3528 5670 l cp
+eoclip
+n 1800 5625 m
+ 3870 5625 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3528 5670 m 3708 5625 l 3528 5580 l 3528 5670 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4572 5580 m 4215 5580 l 4215 5670 l 4572 5670 l 4572 5670 l 4392 5625 l 4572 5580 l cp
+eoclip
+n 6300 5625 m
+ 4230 5625 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4572 5580 m 4392 5625 l 4572 5670 l 4572 5580 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4304 5306 m 4052 5558 l 4116 5622 l 4368 5370 l 4368 5370 l 4209 5466 l 4304 5306 l cp
+eoclip
+n 5850 3825 m
+ 4095 5580 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4304 5306 m 4209 5466 l 4368 5370 l 4304 5306 l  cp gs 0.00 setgray ef gr  col0 s
+% here ends figure;
+% 
+% here starts figure with depth 50
+% Ellipse
+15.000 slw
+n 3375 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Polyline
+0 slj
+0 slc
+n 247 2947 m 2947 247 l 9697 247 l 6997 2947 l
+ 247 2947 l  cp gs col0 s gr 
+% Polyline
+n 247 6097 m 2947 3397 l 9697 3397 l 6997 6097 l
+ 247 6097 l  cp gs col0 s gr 
+% Ellipse
+n 1575 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 4050 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 675 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 1575 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 4050 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% here ends figure;
+% 
+% here starts figure with depth 40
+/Helvetica ff 480.00 scf sf
+8280 2610 m
+gs 1 -1 sc (SubDigraph adaptor) col0 sh gr
+% Polyline
+0 slj
+0 slc
+7.500 slw
+ [15 45] 45 sd
+n 4050 2610 m
+ 4050 5625 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 5850 810 m
+ 5850 3825 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 6525 2610 m
+ 6525 5625 l gs col0 s gr  [] 0 sd
+/Helvetica ff 480.00 scf sf
+8280 5760 m
+gs 1 -1 sc (Original digraph) col0 sh gr
+% Polyline
+ [15 45] 45 sd
+n 1575 2610 m
+ 1575 5625 l gs col0 s gr  [] 0 sd
+% here ends figure;
+$F2psEnd
+rs
+showpage
+%%Trailer
+%EOF
Index: doc/images/adaptors2.eps
===================================================================
--- doc/images/adaptors2.eps	(revision 1218)
+++ doc/images/adaptors2.eps	(revision 1218)
@@ -0,0 +1,349 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: adaptors2.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5
+%%CreationDate: Sun Feb 21 18:51:31 2010
+%%For: Peter@KOVACSPETER (PÃ©ter,U-KOVACSPETER\Peter,S-1-5-21-1774138250-1299389707-1938712334-1001)
+%%BoundingBox: 0 0 787 570
+%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 570 moveto 0 0 lineto 787 0 lineto 787 570 lineto closepath clip newpath
+-14.2 583.9 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+	/endangle exch def
+	/startangle exch def
+	/yrad exch def
+	/xrad exch def
+	/y exch def
+	/x exch def
+	/savematrix mtrx currentmatrix def
+	x y tr xrad yrad sc 0 0 1 startangle endangle arc
+	closepath
+	savematrix setmatrix
+	} def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% 
+% here starts figure with depth 60
+% Polyline
+0 slj
+0 slc
+15.000 slw
+gs  clippath
+5417 4044 m 5746 3905 l 5711 3822 l 5382 3961 l 5382 3961 l 5566 3933 l 5417 4044 l cp
+eoclip
+n 1575 5625 m
+ 5715 3870 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 5417 4044 m 5566 3933 l 5382 3961 l 5417 4044 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+5417 7194 m 5746 7055 l 5711 6972 l 5382 7111 l 5382 7111 l 5566 7083 l 5417 7194 l cp
+eoclip
+n 1575 8775 m
+ 5715 7020 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 5417 7194 m 5566 7083 l 5382 7111 l 5417 7194 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+6319 8379 m 6442 8714 l 6527 8683 l 6403 8348 l 6403 8348 l 6424 8533 l 6319 8379 l cp
+eoclip
+n 5850 6975 m
+ 6480 8685 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 6319 8379 m 6424 8533 l 6403 8348 l 6319 8379 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4304 8456 m 4052 8708 l 4116 8772 l 4368 8520 l 4368 8520 l 4209 8616 l 4304 8456 l cp
+eoclip
+n 5850 6975 m
+ 4095 8730 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4304 8456 m 4209 8616 l 4368 8520 l 4304 8456 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4572 8730 m 4215 8730 l 4215 8820 l 4572 8820 l 4572 8820 l 4392 8775 l 4572 8730 l cp
+eoclip
+n 6300 8775 m
+ 4230 8775 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4572 8730 m 4392 8775 l 4572 8820 l 4572 8730 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3528 8820 m 3885 8820 l 3885 8730 l 3528 8730 l 3528 8730 l 3708 8775 l 3528 8820 l cp
+eoclip
+n 1800 8775 m
+ 3870 8775 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3528 8820 m 3708 8775 l 3528 8730 l 3528 8820 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+n 1800 2475 m
+ 3870 2475 l gs col0 s gr 
+% Polyline
+n 1575 2475 m
+ 5715 720 l gs col0 s gr 
+% Polyline
+n 5850 675 m
+ 4095 2430 l gs col0 s gr 
+% Polyline
+n 5850 675 m
+ 6480 2385 l gs col0 s gr 
+% Polyline
+gs  clippath
+3075 7338 m 3327 7086 l 3263 7022 l 3011 7274 l 3011 7274 l 3171 7179 l 3075 7338 l cp
+eoclip
+n 1575 8775 m
+ 3285 7065 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3075 7338 m 3171 7179 l 3011 7274 l 3075 7338 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3528 5670 m 3885 5670 l 3885 5580 l 3528 5580 l 3528 5580 l 3708 5625 l 3528 5670 l cp
+eoclip
+n 1800 5625 m
+ 3870 5625 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3528 5670 m 3708 5625 l 3528 5580 l 3528 5670 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+4304 5306 m 4052 5558 l 4116 5622 l 4368 5370 l 4368 5370 l 4209 5466 l 4304 5306 l cp
+eoclip
+n 5850 3825 m
+ 4095 5580 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 4304 5306 m 4209 5466 l 4368 5370 l 4304 5306 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+6319 5229 m 6442 5564 l 6527 5533 l 6403 5198 l 6403 5198 l 6424 5383 l 6319 5229 l cp
+eoclip
+n 5850 3825 m
+ 6480 5535 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 6319 5229 m 6424 5383 l 6403 5198 l 6319 5229 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+15.000 slw
+gs  clippath
+3897 6930 m 3540 6930 l 3540 7020 l 3897 7020 l 3897 7020 l 3717 6975 l 3897 6930 l cp
+eoclip
+n 5625 6975 m
+ 3555 6975 l gs col0 s gr gr
+
+% arrowhead
+75.000 slw
+n 3897 6930 m 3717 6975 l 3897 7020 l 3897 6930 l  cp gs 0.00 setgray ef gr  col0 s
+% here ends figure;
+% 
+% here starts figure with depth 50
+% Polyline
+0 slj
+0 slc
+15.000 slw
+n 247 6097 m 2947 3397 l 9697 3397 l 6997 6097 l
+ 247 6097 l  cp gs col0 s gr 
+% Polyline
+n 247 9247 m 2947 6547 l 9697 6547 l 6997 9247 l
+ 247 9247 l  cp gs col0 s gr 
+% Ellipse
+n 4050 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 1575 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 675 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 1575 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 4050 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 1575 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 4050 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 3375 6975 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 6525 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 5850 6975 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
+
+% Polyline
+n 247 2947 m 2947 247 l 9697 247 l 6997 2947 l
+ 247 2947 l  cp gs col0 s gr 
+% here ends figure;
+% 
+% here starts figure with depth 40
+/Helvetica ff 480.00 scf sf
+8280 8910 m
+gs 1 -1 sc (Original digraph) col0 sh gr
+% Polyline
+0 slj
+0 slc
+7.500 slw
+ [15 45] 45 sd
+n 5850 810 m
+ 5850 3825 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 6525 2610 m
+ 6525 5625 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 4050 2610 m
+ 4050 5625 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 1575 2610 m
+ 1575 5625 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 5850 3960 m
+ 5850 6975 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 6525 5760 m
+ 6525 8775 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 4050 5760 m
+ 4050 8775 l gs col0 s gr  [] 0 sd
+/Helvetica ff 480.00 scf sf
+8280 2610 m
+gs 1 -1 sc (Undirector adaptor) col0 sh gr
+/Helvetica ff 480.00 scf sf
+8280 5760 m
+gs 1 -1 sc (SubDigraph adaptor) col0 sh gr
+% Polyline
+ [15 45] 45 sd
+n 1575 5760 m
+ 1575 8775 l gs col0 s gr  [] 0 sd
+% here ends figure;
+$F2psEnd
+rs
+showpage
+%%Trailer
+%EOF
Index: doc/images/bipartite_partitions.eps
===================================================================
--- doc/images/bipartite_partitions.eps	(revision 634)
+++ doc/images/bipartite_partitions.eps	(revision 1213)
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0 EPSF-2.0
 %%Creator: LEMON, graphToEps()
-%%CreationDate: Tue Nov 15 16:51:43 2005
+%%CreationDate: Fri Mar  8 00:18:43 2013
 %%BoundingBox: 0 0 842 596
 %%EndComments
@@ -54,60 +54,60 @@
 %Edges:
 gsave
-513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2 lb
-513.857 -446.322 575.52 -315.655 637.183 -184.989 0 0 0 2 lb
-393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2 lb
-393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2 lb
-393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2 lb
-869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2 lb
-869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2 lb
--82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2 lb
--663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2 lb
--663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2 lb
--1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2 lb
--1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2 lb
--1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2 lb
--1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2 lb
--880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2 lb
--499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2 lb
--499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2 lb
--499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2 lb
-79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2 lb
-637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2 lb
-205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2 lb
-399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2 lb
-399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2 lb
--842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2 lb
--842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2 lb
--860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2 lb
--211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2 lb
--99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2 lb
--99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2 lb
-120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2 lb
+513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 7.00153 lb
+513.857 -446.322 575.52 -315.656 637.183 -184.989 0 0 0 7.00153 lb
+393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 7.00153 lb
+393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 7.00153 lb
+393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 7.00153 lb
+869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 7.00153 lb
+869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 7.00153 lb
+-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 7.00153 lb
+-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 7.00153 lb
+-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 7.00153 lb
+-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 7.00153 lb
+-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 7.00153 lb
+-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 7.00153 lb
+-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 7.00153 lb
+-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 7.00153 lb
+-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 7.00153 lb
+-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 7.00153 lb
+-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 7.00153 lb
+79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 7.00153 lb
+637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 7.00153 lb
+205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 7.00153 lb
+399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 7.00153 lb
+399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 7.00153 lb
+-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 7.00153 lb
+-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 7.00153 lb
+-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 7.00153 lb
+-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 7.00153 lb
+-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 7.00153 lb
+-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 7.00153 lb
+120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 7.00153 lb
 grestore
 %Nodes:
 gsave
--274 -131 20 1 0 0 nc
--607.82 -246.651 20 1 0 0 nc
--484.494 328.869 20 0 0 1 nc
-108.644 334.741 20 0 0 1 nc
-120.389 -129.198 20 0 0 1 nc
--99.8351 99.8351 20 1 0 0 nc
--211.415 -452.194 20 1 0 0 nc
--860.344 -29.3633 20 0 0 1 nc
--842.726 243.715 20 0 0 1 nc
-399.34 88.0898 20 1 0 0 nc
-205.543 -322.996 20 1 0 0 nc
-637.183 -184.989 20 0 0 1 nc
-79.2808 -528.539 20 0 0 1 nc
--499.175 -499.175 20 0 0 1 nc
--880.898 -528.539 20 0 0 1 nc
--1177.47 -234.906 20 1 0 0 nc
--1077.63 161.498 20 1 0 0 nc
--663.61 546.157 20 1 0 0 nc
--82.2171 593.138 20 0 0 1 nc
-596.074 302.442 20 0 0 1 nc
-869.153 52.8539 20 1 0 0 nc
-393.468 566.711 20 1 0 0 nc
-513.857 -446.322 20 1 0 0 nc
+-274 -131 23.3384 1 0 0 nc
+-607.82 -246.651 23.3384 1 0 0 nc
+-484.494 328.869 23.3384 0 0 1 nc
+108.644 334.741 23.3384 0 0 1 nc
+120.389 -129.198 23.3384 0 0 1 nc
+-99.8351 99.8351 23.3384 1 0 0 nc
+-211.415 -452.194 23.3384 1 0 0 nc
+-860.344 -29.3633 23.3384 0 0 1 nc
+-842.726 243.715 23.3384 0 0 1 nc
+399.34 88.0898 23.3384 1 0 0 nc
+205.543 -322.996 23.3384 1 0 0 nc
+637.183 -184.989 23.3384 0 0 1 nc
+79.2808 -528.539 23.3384 0 0 1 nc
+-499.175 -499.175 23.3384 0 0 1 nc
+-880.898 -528.539 23.3384 0 0 1 nc
+-1177.47 -234.906 23.3384 1 0 0 nc
+-1077.63 161.498 23.3384 1 0 0 nc
+-663.61 546.157 23.3384 1 0 0 nc
+-82.2171 593.138 23.3384 0 0 1 nc
+596.074 302.442 23.3384 0 0 1 nc
+869.153 52.8539 23.3384 1 0 0 nc
+393.468 566.711 23.3384 1 0 0 nc
+513.857 -446.322 23.3384 1 0 0 nc
 grestore
 grestore
Index: doc/images/connected_components.eps
===================================================================
--- doc/images/connected_components.eps	(revision 634)
+++ doc/images/connected_components.eps	(revision 1213)
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0 EPSF-2.0
 %%Creator: LEMON, graphToEps()
-%%CreationDate: Fri Nov  4 13:47:12 2005
+%%CreationDate: Fri Mar  8 00:18:43 2013
 %%BoundingBox: 0 0 842 596
 %%EndComments
@@ -54,105 +54,105 @@
 %Edges:
 gsave
-574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2 lb
-694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2 lb
-280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2 lb
-280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2 lb
-212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2 lb
-286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2 lb
-286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2 lb
-438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2 lb
-438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2 lb
-397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2 lb
-366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2 lb
-271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2 lb
-271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2 lb
-277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2 lb
--840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2 lb
--579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2 lb
--579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2 lb
--767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2 lb
-906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2 lb
-906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2 lb
-986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2 lb
--470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2 lb
-422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2 lb
-422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2 lb
-422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2 lb
--5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2 lb
-329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2 lb
--67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2 lb
-762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2 lb
-762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2 lb
-526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2 lb
-730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2 lb
-415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2 lb
--67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2 lb
--67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2 lb
--309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2 lb
--323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2 lb
--26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2 lb
--26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2 lb
--26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2 lb
--26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2 lb
-116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2 lb
--262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2 lb
--262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2 lb
--13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2 lb
--180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 0 2 lb
--180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 0 2 lb
--416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2 lb
--416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2 lb
--132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2 lb
-670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2 lb
-670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2 lb
-588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2 lb
--689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 0 2 lb
--689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 0 2 lb
+574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 6.25356 lb
+694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 6.25356 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 6.25356 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 6.25356 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 6.25356 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 6.25356 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 6.25356 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 6.25356 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 6.25356 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 6.25356 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 6.25356 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 6.25356 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 6.25356 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 6.25356 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 6.25356 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 6.25356 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 6.25356 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 6.25356 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 6.25356 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 6.25356 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 6.25356 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 6.25356 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 6.25356 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 6.25356 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 6.25356 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 6.25356 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 6.25356 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 6.25356 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 6.25356 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 6.25356 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 6.25356 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 6.25356 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 6.25356 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 6.25356 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 6.25356 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 6.25356 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 6.25356 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 6.25356 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 6.25356 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 6.25356 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 6.25356 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 6.25356 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 6.25356 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 6.25356 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 6.25356 lb
+-180.397 245.045 -113.509 338.465 -132.697 451.748 0 0 0 6.25356 lb
+-180.397 245.045 -199.585 358.328 -132.697 451.748 0 0 0 6.25356 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 6.25356 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 6.25356 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 6.25356 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 6.25356 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 6.25356 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 6.25356 lb
+-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 0 6.25356 lb
+-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 0 6.25356 lb
 grestore
 %Nodes:
 gsave
--567.302 43.6423 20 0 0 0 nc
--689.204 -237.261 20 0 0 0 nc
-924.667 409.347 20 1 0 0 nc
-588.113 544.499 20 1 0 0 nc
-670.264 274.195 20 1 0 0 nc
--371.2 568.349 20 0 1 0 nc
--132.697 451.748 20 0 1 0 nc
--416.25 345.746 20 0 1 0 nc
--180.397 245.045 20 0 1 0 nc
--13.4452 133.743 20 0 1 0 nc
--262.548 107.243 20 0 1 0 nc
-201.208 38.3422 20 0 1 0 nc
-116.407 -173.66 20 0 1 0 nc
--26.6953 -19.9585 20 0 1 0 nc
--539.894 -262.64 20 0 0 1 nc
--323.543 -433.964 20 0 0 1 nc
--309.657 -57.9033 20 0 0 1 nc
--67.9734 -347.42 20 0 0 1 nc
-415.393 -289.516 20 0 0 1 nc
-730.084 -307.139 20 0 0 1 nc
-526.164 32.7279 20 0 0 1 nc
-762.812 -17.6227 20 0 0 1 nc
--67.9734 319.727 20 0 0 1 nc
-329.797 314.692 20 0 0 1 nc
--5.03507 561.41 20 0 0 1 nc
-422.945 521.129 20 0 0 1 nc
--470.779 158.605 20 0 0 1 nc
-986.873 -115.807 20 0 0 1 nc
-906.312 201.403 20 0 0 1 nc
--767.847 113.289 20 0 0 1 nc
--579.033 445.603 20 0 0 1 nc
--840.856 -246.718 20 0 0 1 nc
-206.221 -205.967 20 1 1 0 nc
-277.311 -252.33 20 1 1 0 nc
-271.13 -175.058 20 1 1 0 nc
-366.947 -110.15 20 1 1 0 nc
-397.855 -196.694 20 1 1 0 nc
-438.037 -88.514 20 1 1 0 nc
-286.584 -48.3327 20 1 1 0 nc
-212.403 -23.6057 20 1 1 0 nc
-280.402 10.3938 20 1 1 0 nc
-694.579 115.483 20 1 0 0 nc
-574.035 177.301 20 1 0 0 nc
+-567.302 43.6423 20.8452 0 0 0 nc
+-689.204 -237.261 20.8452 0 0 0 nc
+924.667 409.347 20.8452 1 0 0 nc
+588.113 544.499 20.8452 1 0 0 nc
+670.264 274.195 20.8452 1 0 0 nc
+-371.2 568.349 20.8452 0 1 0 nc
+-132.697 451.748 20.8452 0 1 0 nc
+-416.25 345.746 20.8452 0 1 0 nc
+-180.397 245.045 20.8452 0 1 0 nc
+-13.4452 133.743 20.8452 0 1 0 nc
+-262.548 107.243 20.8452 0 1 0 nc
+201.208 38.3422 20.8452 0 1 0 nc
+116.407 -173.66 20.8452 0 1 0 nc
+-26.6953 -19.9585 20.8452 0 1 0 nc
+-539.894 -262.64 20.8452 0 0 1 nc
+-323.543 -433.964 20.8452 0 0 1 nc
+-309.657 -57.9033 20.8452 0 0 1 nc
+-67.9734 -347.42 20.8452 0 0 1 nc
+415.393 -289.516 20.8452 0 0 1 nc
+730.084 -307.139 20.8452 0 0 1 nc
+526.164 32.7279 20.8452 0 0 1 nc
+762.812 -17.6227 20.8452 0 0 1 nc
+-67.9734 319.727 20.8452 0 0 1 nc
+329.797 314.692 20.8452 0 0 1 nc
+-5.03507 561.41 20.8452 0 0 1 nc
+422.945 521.129 20.8452 0 0 1 nc
+-470.779 158.605 20.8452 0 0 1 nc
+986.873 -115.807 20.8452 0 0 1 nc
+906.312 201.403 20.8452 0 0 1 nc
+-767.847 113.289 20.8452 0 0 1 nc
+-579.033 445.603 20.8452 0 0 1 nc
+-840.856 -246.718 20.8452 0 0 1 nc
+206.221 -205.967 20.8452 1 1 0 nc
+277.311 -252.33 20.8452 1 1 0 nc
+271.13 -175.058 20.8452 1 1 0 nc
+366.947 -110.15 20.8452 1 1 0 nc
+397.855 -196.694 20.8452 1 1 0 nc
+438.037 -88.514 20.8452 1 1 0 nc
+286.584 -48.3327 20.8452 1 1 0 nc
+212.403 -23.6057 20.8452 1 1 0 nc
+280.402 10.3938 20.8452 1 1 0 nc
+694.579 115.483 20.8452 1 0 0 nc
+574.035 177.301 20.8452 1 0 0 nc
 grestore
 grestore
Index: doc/images/edge_biconnected_components.eps
===================================================================
--- doc/images/edge_biconnected_components.eps	(revision 634)
+++ doc/images/edge_biconnected_components.eps	(revision 1213)
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0 EPSF-2.0
 %%Creator: LEMON, graphToEps()
-%%CreationDate: Fri Nov  4 13:47:12 2005
+%%CreationDate: Fri Mar  8 00:18:43 2013
 %%BoundingBox: 0 0 842 596
 %%EndComments
@@ -54,105 +54,105 @@
 %Edges:
 gsave
-574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2 lb
-694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2 lb
-280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2 lb
-280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2 lb
-212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2 lb
-286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2 lb
-286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2 lb
-438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2 lb
-438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2 lb
-397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2 lb
-366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2 lb
-271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2 lb
-271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2 lb
-277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2 lb
--840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2 lb
--579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2 lb
--579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2 lb
--767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2 lb
-906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2 lb
-906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2 lb
-986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2 lb
--470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2 lb
-422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2 lb
-422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2 lb
-422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2 lb
--5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2 lb
-329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2 lb
--67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2 lb
-762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2 lb
-762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2 lb
-526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2 lb
-730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2 lb
-415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2 lb
--67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2 lb
--67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2 lb
--309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2 lb
--323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2 lb
--26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2 lb
--26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2 lb
--26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2 lb
--26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2 lb
-116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2 lb
--262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2 lb
--262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2 lb
--13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2 lb
--180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 1 2 lb
--180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 1 2 lb
--416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2 lb
--416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2 lb
--132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2 lb
-670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2 lb
-670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2 lb
-588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2 lb
--689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 1 2 lb
--689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 1 2 lb
+574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 6.25356 lb
+694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 6.25356 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 6.25356 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 6.25356 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 6.25356 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 6.25356 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 6.25356 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 6.25356 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 6.25356 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 6.25356 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 6.25356 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 6.25356 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 6.25356 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 6.25356 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 6.25356 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 6.25356 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 6.25356 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 6.25356 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 6.25356 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 6.25356 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 6.25356 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 6.25356 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 6.25356 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 6.25356 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 6.25356 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 6.25356 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 6.25356 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 6.25356 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 6.25356 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 6.25356 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 6.25356 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 6.25356 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 6.25356 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 6.25356 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 6.25356 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 6.25356 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 6.25356 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 6.25356 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 6.25356 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 6.25356 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 6.25356 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 6.25356 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 6.25356 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 6.25356 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 6.25356 lb
+-180.397 245.045 -113.509 338.465 -132.697 451.748 0 0 1 6.25356 lb
+-180.397 245.045 -199.585 358.328 -132.697 451.748 0 0 1 6.25356 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 6.25356 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 6.25356 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 6.25356 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 6.25356 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 6.25356 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 6.25356 lb
+-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 1 6.25356 lb
+-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 1 6.25356 lb
 grestore
 %Nodes:
 gsave
--567.302 43.6423 20 0 0 0 nc
--689.204 -237.261 20 0 0 0 nc
-924.667 409.347 20 0 0 1 nc
-588.113 544.499 20 0 0 1 nc
-670.264 274.195 20 0 0 1 nc
--371.2 568.349 20 1 1 0 nc
--132.697 451.748 20 1 1 0 nc
--416.25 345.746 20 1 1 0 nc
--180.397 245.045 20 1 1 0 nc
--13.4452 133.743 20 1 1 0 nc
--262.548 107.243 20 1 1 0 nc
-201.208 38.3422 20 1 1 0 nc
-116.407 -173.66 20 1 1 0 nc
--26.6953 -19.9585 20 1 1 0 nc
--539.894 -262.64 20 0 0.5 0 nc
--323.543 -433.964 20 0 0.5 0 nc
--309.657 -57.9033 20 0 0.5 0 nc
--67.9734 -347.42 20 0 0.5 0 nc
-415.393 -289.516 20 0.5 0 0 nc
-730.084 -307.139 20 0.5 0 0 nc
-526.164 32.7279 20 0.5 0 0 nc
-762.812 -17.6227 20 0.5 0 0 nc
--67.9734 319.727 20 0.5 0 0 nc
-329.797 314.692 20 0.5 0 0 nc
--5.03507 561.41 20 0.5 0 0 nc
-422.945 521.129 20 0.5 0 0 nc
--470.779 158.605 20 0 1 1 nc
-986.873 -115.807 20 0.5 0 0 nc
-906.312 201.403 20 0.5 0 0 nc
--767.847 113.289 20 0 1 1 nc
--579.033 445.603 20 0 1 1 nc
--840.856 -246.718 20 1 0 1 nc
-206.221 -205.967 20 0 0 0.5 nc
-277.311 -252.33 20 0 0 0.5 nc
-271.13 -175.058 20 0 0 0.5 nc
-366.947 -110.15 20 0 0 0.5 nc
-397.855 -196.694 20 0 0 0.5 nc
-438.037 -88.514 20 0 0 0.5 nc
-286.584 -48.3327 20 0 0 0.5 nc
-212.403 -23.6057 20 0 0 0.5 nc
-280.402 10.3938 20 0 0 0.5 nc
-694.579 115.483 20 1 0 0 nc
-574.035 177.301 20 0 1 0 nc
+-567.302 43.6423 20.8452 0 0 0 nc
+-689.204 -237.261 20.8452 0 0 0 nc
+924.667 409.347 20.8452 0 0 1 nc
+588.113 544.499 20.8452 0 0 1 nc
+670.264 274.195 20.8452 0 0 1 nc
+-371.2 568.349 20.8452 1 1 0 nc
+-132.697 451.748 20.8452 1 1 0 nc
+-416.25 345.746 20.8452 1 1 0 nc
+-180.397 245.045 20.8452 1 1 0 nc
+-13.4452 133.743 20.8452 1 1 0 nc
+-262.548 107.243 20.8452 1 1 0 nc
+201.208 38.3422 20.8452 1 1 0 nc
+116.407 -173.66 20.8452 1 1 0 nc
+-26.6953 -19.9585 20.8452 1 1 0 nc
+-539.894 -262.64 20.8452 0 0.5 0 nc
+-323.543 -433.964 20.8452 0 0.5 0 nc
+-309.657 -57.9033 20.8452 0 0.5 0 nc
+-67.9734 -347.42 20.8452 0 0.5 0 nc
+415.393 -289.516 20.8452 0.5 0 0 nc
+730.084 -307.139 20.8452 0.5 0 0 nc
+526.164 32.7279 20.8452 0.5 0 0 nc
+762.812 -17.6227 20.8452 0.5 0 0 nc
+-67.9734 319.727 20.8452 0.5 0 0 nc
+329.797 314.692 20.8452 0.5 0 0 nc
+-5.03507 561.41 20.8452 0.5 0 0 nc
+422.945 521.129 20.8452 0.5 0 0 nc
+-470.779 158.605 20.8452 0 1 1 nc
+986.873 -115.807 20.8452 0.5 0 0 nc
+906.312 201.403 20.8452 0.5 0 0 nc
+-767.847 113.289 20.8452 0 1 1 nc
+-579.033 445.603 20.8452 0 1 1 nc
+-840.856 -246.718 20.8452 1 0 1 nc
+206.221 -205.967 20.8452 0 0 0.5 nc
+277.311 -252.33 20.8452 0 0 0.5 nc
+271.13 -175.058 20.8452 0 0 0.5 nc
+366.947 -110.15 20.8452 0 0 0.5 nc
+397.855 -196.694 20.8452 0 0 0.5 nc
+438.037 -88.514 20.8452 0 0 0.5 nc
+286.584 -48.3327 20.8452 0 0 0.5 nc
+212.403 -23.6057 20.8452 0 0 0.5 nc
+280.402 10.3938 20.8452 0 0 0.5 nc
+694.579 115.483 20.8452 1 0 0 nc
+574.035 177.301 20.8452 0 1 0 nc
 grestore
 grestore
Index: doc/images/node_biconnected_components.eps
===================================================================
--- doc/images/node_biconnected_components.eps	(revision 634)
+++ doc/images/node_biconnected_components.eps	(revision 1213)
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0 EPSF-2.0
 %%Creator: LEMON, graphToEps()
-%%CreationDate: Fri Nov  4 13:47:12 2005
+%%CreationDate: Fri Mar  8 00:18:43 2013
 %%BoundingBox: 0 0 842 596
 %%EndComments
@@ -54,105 +54,105 @@
 %Edges:
 gsave
-574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 5 lb
-694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5 lb
-280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5 lb
-280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5 lb
-212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5 lb
-286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5 lb
-286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5 lb
-438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5 lb
-438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5 lb
-397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5 lb
-366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5 lb
-271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5 lb
-271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5 lb
-277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5 lb
--840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5 lb
--579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5 lb
--579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5 lb
--767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5 lb
-906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5 lb
-906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5 lb
-986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5 lb
--470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5 lb
-422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5 lb
-422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5 lb
-422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5 lb
--5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5 lb
-329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5 lb
--67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5 lb
-762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5 lb
-762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5 lb
-526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5 lb
-730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5 lb
-415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5 lb
--67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5 lb
--67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5 lb
--309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5 lb
--323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5 lb
--26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5 lb
--26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5 lb
--26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5 lb
--26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5 lb
-116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5 lb
--262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5 lb
--262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5 lb
--13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5 lb
--180.397 245.045 -140.307 344.649 -132.697 451.748 0 1 1 5 lb
--180.397 245.045 -172.787 352.144 -132.697 451.748 0 1 1 5 lb
--416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5 lb
--416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5 lb
--132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5 lb
-670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5 lb
-670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5 lb
-588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5 lb
--689.204 -237.261 -612.964 -103.444 -567.302 43.6423 0 0 0 5 lb
--689.204 -237.261 -643.542 -90.1744 -567.302 43.6423 0 0 0 5 lb
+574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 6.25356 lb
+694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 6.25356 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 6.25356 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 6.25356 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 6.25356 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 6.25356 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 6.25356 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 6.25356 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 6.25356 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 6.25356 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 6.25356 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 6.25356 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 6.25356 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 6.25356 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 6.25356 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 6.25356 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 6.25356 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 6.25356 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 6.25356 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 6.25356 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 6.25356 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 6.25356 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 6.25356 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 6.25356 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 6.25356 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 6.25356 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 6.25356 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 6.25356 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 6.25356 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 6.25356 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 6.25356 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 6.25356 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 6.25356 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 6.25356 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 6.25356 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 6.25356 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 6.25356 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 6.25356 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 6.25356 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 6.25356 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 6.25356 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 6.25356 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 6.25356 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 6.25356 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 6.25356 lb
+-180.397 245.045 -113.509 338.465 -132.697 451.748 0 1 1 6.25356 lb
+-180.397 245.045 -199.585 358.328 -132.697 451.748 0 1 1 6.25356 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 6.25356 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 6.25356 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 6.25356 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 6.25356 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 6.25356 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 6.25356 lb
+-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 0 6.25356 lb
+-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 0 6.25356 lb
 grestore
 %Nodes:
 gsave
--567.302 43.6423 20 0 0 1 nc
--689.204 -237.261 20 0 0 1 nc
-924.667 409.347 20 0 0 1 nc
-588.113 544.499 20 0 0 1 nc
-670.264 274.195 20 1 0 0 nc
--371.2 568.349 20 0 0 1 nc
--132.697 451.748 20 1 0 0 nc
--416.25 345.746 20 0 0 1 nc
--180.397 245.045 20 1 0 0 nc
--13.4452 133.743 20 0 0 1 nc
--262.548 107.243 20 0 0 1 nc
-201.208 38.3422 20 0 0 1 nc
-116.407 -173.66 20 0 0 1 nc
--26.6953 -19.9585 20 1 0 0 nc
--539.894 -262.64 20 0 0 1 nc
--323.543 -433.964 20 0 0 1 nc
--309.657 -57.9033 20 1 0 0 nc
--67.9734 -347.42 20 1 0 0 nc
-415.393 -289.516 20 1 0 0 nc
-730.084 -307.139 20 0 0 1 nc
-526.164 32.7279 20 1 0 0 nc
-762.812 -17.6227 20 1 0 0 nc
--67.9734 319.727 20 0 0 1 nc
-329.797 314.692 20 0 0 1 nc
--5.03507 561.41 20 0 0 1 nc
-422.945 521.129 20 0 0 1 nc
--470.779 158.605 20 1 0 0 nc
-986.873 -115.807 20 0 0 1 nc
-906.312 201.403 20 0 0 1 nc
--767.847 113.289 20 1 0 0 nc
--579.033 445.603 20 0 0 1 nc
--840.856 -246.718 20 0 0 1 nc
-206.221 -205.967 20 0 0 1 nc
-277.311 -252.33 20 0 0 1 nc
-271.13 -175.058 20 1 0 0 nc
-366.947 -110.15 20 1 0 0 nc
-397.855 -196.694 20 0 0 1 nc
-438.037 -88.514 20 0 0 1 nc
-286.584 -48.3327 20 1 0 0 nc
-212.403 -23.6057 20 0 0 1 nc
-280.402 10.3938 20 0 0 1 nc
-694.579 115.483 20 0 0 1 nc
-574.035 177.301 20 0 0 1 nc
+-567.302 43.6423 20.8452 0 0 1 nc
+-689.204 -237.261 20.8452 0 0 1 nc
+924.667 409.347 20.8452 0 0 1 nc
+588.113 544.499 20.8452 0 0 1 nc
+670.264 274.195 20.8452 1 0 0 nc
+-371.2 568.349 20.8452 0 0 1 nc
+-132.697 451.748 20.8452 1 0 0 nc
+-416.25 345.746 20.8452 0 0 1 nc
+-180.397 245.045 20.8452 1 0 0 nc
+-13.4452 133.743 20.8452 0 0 1 nc
+-262.548 107.243 20.8452 0 0 1 nc
+201.208 38.3422 20.8452 0 0 1 nc
+116.407 -173.66 20.8452 0 0 1 nc
+-26.6953 -19.9585 20.8452 1 0 0 nc
+-539.894 -262.64 20.8452 0 0 1 nc
+-323.543 -433.964 20.8452 0 0 1 nc
+-309.657 -57.9033 20.8452 1 0 0 nc
+-67.9734 -347.42 20.8452 1 0 0 nc
+415.393 -289.516 20.8452 1 0 0 nc
+730.084 -307.139 20.8452 0 0 1 nc
+526.164 32.7279 20.8452 1 0 0 nc
+762.812 -17.6227 20.8452 1 0 0 nc
+-67.9734 319.727 20.8452 0 0 1 nc
+329.797 314.692 20.8452 0 0 1 nc
+-5.03507 561.41 20.8452 0 0 1 nc
+422.945 521.129 20.8452 0 0 1 nc
+-470.779 158.605 20.8452 1 0 0 nc
+986.873 -115.807 20.8452 0 0 1 nc
+906.312 201.403 20.8452 0 0 1 nc
+-767.847 113.289 20.8452 1 0 0 nc
+-579.033 445.603 20.8452 0 0 1 nc
+-840.856 -246.718 20.8452 0 0 1 nc
+206.221 -205.967 20.8452 0 0 1 nc
+277.311 -252.33 20.8452 0 0 1 nc
+271.13 -175.058 20.8452 1 0 0 nc
+366.947 -110.15 20.8452 1 0 0 nc
+397.855 -196.694 20.8452 0 0 1 nc
+438.037 -88.514 20.8452 0 0 1 nc
+286.584 -48.3327 20.8452 1 0 0 nc
+212.403 -23.6057 20.8452 0 0 1 nc
+280.402 10.3938 20.8452 0 0 1 nc
+694.579 115.483 20.8452 0 0 1 nc
+574.035 177.301 20.8452 0 0 1 nc
 grestore
 grestore
Index: doc/images/strongly_connected_components.eps
===================================================================
--- doc/images/strongly_connected_components.eps	(revision 634)
+++ doc/images/strongly_connected_components.eps	(revision 1213)
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0 EPSF-2.0
 %%Creator: LEMON, graphToEps()
-%%CreationDate: Fri Nov  4 13:47:12 2005
+%%CreationDate: Fri Mar  8 00:22:15 2013
 %%BoundingBox: 0 0 842 596
 %%EndComments
@@ -54,126 +54,126 @@
 %Edges:
 gsave
-2 setlinewidth 0 0 1 setrgbcolor newpath
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 218.178 27.2723 moveto
-192.373 -40.1551 188.622 -49.9556 169.228 -100.631 curveto stroke
-newpath 164.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+195.849 -31.0725 190.033 -46.2697 176.306 -82.1369 curveto stroke
+newpath 163.235 -116.291 moveto 165.206 -77.8889 lineto 187.405 -86.3849 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 44.8044 15.5841 moveto
-119.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke
-newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill
-2 setlinewidth 1 0 0 setrgbcolor newpath
+109.705 19.9594 126.016 21.0591 166.493 23.7879 curveto stroke
+newpath 202.98 26.2477 moveto 167.292 11.9299 lineto 165.694 35.6458 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
 218.178 27.2723 moveto
-285.395 -87.4449 290.763 -96.6058 348.102 -194.464 curveto stroke
-newpath 354.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+281.264 -80.3935 289.87 -95.0808 338.092 -177.379 curveto stroke
+newpath 356.579 -208.932 moveto 327.837 -183.388 lineto 348.346 -171.371 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 157.79 -130.517 moveto
-108.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke
-newpath 57.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765 lineto closepath fill
-2 setlinewidth 1 0 0 setrgbcolor newpath
+114.446 -74.4692 104.358 -61.4239 76.4943 -25.394 curveto stroke
+newpath 54.1228 3.53455 moveto 85.8959 -18.1234 lineto 67.0928 -32.6646 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
 -105.193 -261.035 moveto
--35.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464 curveto stroke
-newpath 35.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-39.4801 -139.85 -31.344 -124.846 20.1113 -29.9539 curveto stroke
+newpath 37.5434 2.19358 moveto 30.559 -35.6192 lineto 9.66361 -24.2886 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -465.576 -42.8564 moveto
--559.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke
-newpath -656.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-550.335 -27.1603 -566.8 -24.1113 -625.027 -13.3286 curveto stroke
+newpath -660.985 -6.66971 moveto -622.863 -1.64245 lineto -627.191 -25.0148 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -574.666 -153.893 moveto
--528.842 -107.252 -521.515 -99.794 -488.002 -65.683 curveto stroke
-newpath -479.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797 lineto closepath fill
-2 setlinewidth 1 0 0 setrgbcolor newpath
+-535.911 -114.447 -524.692 -103.027 -501.88 -79.8085 curveto stroke
+newpath -476.251 -53.7222 moveto -493.402 -88.1377 lineto -510.358 -71.4793 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
 -490.901 120.777 moveto
--480.122 51.1328 -478.519 40.7713 -470.47 -11.2329 curveto stroke
-newpath -468.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-481.623 60.8277 -479.143 44.8049 -473.499 8.33636 curveto stroke
+newpath -467.906 -27.8032 moveto -485.244 6.51862 lineto -461.754 10.1541 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -675.963 -3.89604 moveto
--632.116 -68.8235 -626.228 -77.5422 -592.575 -127.374 curveto stroke
-newpath -585.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-637.405 -60.9909 -628.201 -74.6206 -603.658 -110.963 curveto stroke
+newpath -583.191 -141.27 moveto -613.507 -117.615 lineto -593.808 -104.312 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -490.901 120.777 moveto
--435.445 215.844 -430.107 224.995 -384.3 303.522 curveto stroke
-newpath -378.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-439.75 208.465 -431.238 223.057 -394.278 286.417 curveto stroke
+newpath -375.851 318.006 moveto -384.012 280.429 lineto -404.543 292.406 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -266.879 114.933 moveto
--367.067 117.547 -377.642 117.822 -458.912 119.943 curveto stroke
-newpath -470.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-358.311 117.318 -375.109 117.756 -439.117 119.426 curveto stroke
+newpath -475.674 120.38 moveto -438.807 131.307 lineto -439.426 107.545 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -368.176 331.163 moveto
--322.511 233.685 -318.018 224.095 -280.454 143.911 curveto stroke
-newpath -275.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608 lineto closepath fill
-2 setlinewidth 1 0 0 setrgbcolor newpath
+-326.156 241.466 -318.997 226.186 -288.855 161.843 curveto stroke
+newpath -273.341 128.727 moveto -299.617 156.801 lineto -278.092 166.885 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
 -266.879 114.933 moveto
--224.004 235.52 -220.448 245.52 -184.094 347.765 curveto stroke
-newpath -180.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-226.764 227.755 -221.069 243.774 -190.728 329.107 curveto stroke
+newpath -178.477 363.564 moveto -179.53 325.126 lineto -201.926 333.089 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -251.294 -335.059 moveto
--189.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke
-newpath -123.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-198.044 -308.079 -183.61 -300.766 -151.402 -284.448 curveto stroke
+newpath -118.781 -267.92 moveto -146.031 -295.049 lineto -156.774 -273.846 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -389.604 -136.361 moveto
--327.15 -226.083 -321.098 -234.777 -269.576 -308.795 curveto stroke
-newpath -262.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51 lineto closepath fill
-2 setlinewidth 1 0 0 setrgbcolor newpath
+-332.039 -219.059 -322.392 -232.919 -280.889 -292.543 curveto stroke
+newpath -259.996 -322.557 moveto -290.643 -299.333 lineto -271.134 -285.753 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
 5.84406 175.322 moveto
--76.0754 267.926 -83.1051 275.873 -152.172 353.948 curveto stroke
-newpath -160.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-70.5724 261.706 -81.8227 274.423 -139.051 339.116 curveto stroke
+newpath -163.281 366.507 moveto -130.149 346.991 lineto -147.953 331.242 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 169.478 311.683 moveto
-96.8003 251.119 88.6819 244.353 30.4273 195.808 curveto stroke
-newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+103.641 256.819 90.7821 246.103 45.6398 208.485 curveto stroke
+newpath 17.546 185.074 moveto 38.0313 217.615 lineto 53.2483 199.355 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 342.851 111.037 moveto
-263.766 202.563 256.831 210.589 190.4 287.47 curveto stroke
-newpath 182.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+269.224 196.246 258.132 209.083 203.347 272.486 curveto stroke
+newpath 179.437 300.157 moveto 212.34 280.257 lineto 194.354 264.716 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 5.84406 175.322 moveto
-163.16 145.314 173.605 143.321 311.418 117.033 curveto stroke
-newpath 323.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+155.419 146.79 172.221 143.585 291.966 120.743 curveto stroke
+newpath 327.888 113.891 moveto 289.739 109.069 lineto 294.193 132.418 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 342.851 111.037 moveto
-497.255 2.58683 505.964 -3.53033 643.932 -100.436 curveto stroke
-newpath 653.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+490.978 6.99574 505.015 -2.86383 627.727 -89.0547 curveto stroke
+newpath 657.653 -110.074 moveto 620.896 -98.7802 lineto 634.558 -79.3291 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 364.28 -222.074 moveto
-354.298 -66.9063 353.616 -56.2971 344.905 79.1029 curveto stroke
-newpath 344.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+354.807 -74.8128 353.709 -57.7536 346.177 59.3416 curveto stroke
+newpath 343.829 95.836 moveto 358.037 60.1045 lineto 334.316 58.5786 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 670.118 -118.829 moveto
-528.037 -166.793 517.967 -170.192 394.599 -211.839 curveto stroke
-newpath 383.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629 lineto closepath fill
-2 setlinewidth 1 0 0 setrgbcolor newpath
+535.595 -164.241 519.412 -169.704 413.361 -205.505 curveto stroke
+newpath 378.712 -217.202 moveto 409.559 -194.245 lineto 417.162 -216.766 lineto closepath fill
+4.56973 setlinewidth 1 0 0 setrgbcolor newpath
 -105.193 -261.035 moveto
-118.401 -242.479 129.015 -241.598 332.39 -224.721 curveto stroke
-newpath 344.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+110.939 -243.099 128.069 -241.677 312.655 -226.358 curveto stroke
+newpath 349.1 -223.334 moveto 313.638 -238.202 lineto 311.672 -214.514 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -105.193 -261.035 moveto
--160.867 -161.176 -166.028 -151.918 -212.336 -68.858 curveto stroke
-newpath -218.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058 lineto closepath fill
-2 setlinewidth 0 0 1 setrgbcolor newpath
+-156.746 -168.566 -164.987 -153.784 -202.693 -86.1539 curveto stroke
+newpath -220.5 -54.2129 moveto -192.312 -80.3665 lineto -213.073 -91.9413 lineto closepath fill
+4.56973 setlinewidth 0 0 1 setrgbcolor newpath
 -227.918 -40.9084 moveto
--298.35 -82.4884 -307.42 -87.8432 -362.048 -120.093 curveto stroke
-newpath -372.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537 lineto closepath fill
+-290.327 -77.7521 -304.558 -86.1532 -344.995 -110.026 curveto stroke
+newpath -376.487 -128.617 moveto -351.037 -99.7914 lineto -338.953 -120.26 lineto closepath fill
 grestore
 %Nodes:
 gsave
--389.604 -136.361 20 0 1 0 nc
--227.918 -40.9084 20 0 1 0 nc
--105.193 -261.035 20 0 1 0 nc
-364.28 -222.074 20 1 1 0 nc
-670.118 -118.829 20 1 1 0 nc
-342.851 111.037 20 1 1 0 nc
-5.84406 175.322 20 1 1 0 nc
-169.478 311.683 20 1 1 0 nc
--173.374 377.916 20 1 0 1 nc
--251.294 -335.059 20 0 1 0 nc
--266.879 114.933 20 0 0 0 nc
--368.176 331.163 20 0 0 0 nc
--490.901 120.777 20 0 0 0 nc
--574.666 -153.893 20 1 0 0 nc
--675.963 -3.89604 20 1 0 0 nc
--465.576 -42.8564 20 1 0 0 nc
-44.8044 15.5841 20 0 0 1 nc
-157.79 -130.517 20 0 0 1 nc
-218.178 27.2723 20 0 0 1 nc
+-389.604 -136.361 15.2324 0 1 0 nc
+-227.918 -40.9084 15.2324 0 1 0 nc
+-105.193 -261.035 15.2324 0 1 0 nc
+364.28 -222.074 15.2324 1 1 0 nc
+670.118 -118.829 15.2324 1 1 0 nc
+342.851 111.037 15.2324 1 1 0 nc
+5.84406 175.322 15.2324 1 1 0 nc
+169.478 311.683 15.2324 1 1 0 nc
+-173.374 377.916 15.2324 1 0 1 nc
+-251.294 -335.059 15.2324 0 1 0 nc
+-266.879 114.933 15.2324 0 0 0 nc
+-368.176 331.163 15.2324 0 0 0 nc
+-490.901 120.777 15.2324 0 0 0 nc
+-574.666 -153.893 15.2324 1 0 0 nc
+-675.963 -3.89604 15.2324 1 0 0 nc
+-465.576 -42.8564 15.2324 1 0 0 nc
+44.8044 15.5841 15.2324 0 0 1 nc
+157.79 -130.517 15.2324 0 0 1 nc
+218.178 27.2723 15.2324 0 0 1 nc
 grestore
 grestore
Index: doc/images/tsp.eps
===================================================================
--- doc/images/tsp.eps	(revision 1200)
+++ doc/images/tsp.eps	(revision 1200)
@@ -0,0 +1,229 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Tue Jun 15 00:58:57 2010
+%%BoundingBox: 31 41 649 709
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
+  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
+  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
+  5 index 5 index 5 index c fill
+  setrgbcolor 1.1 div c fill
+  } bind def
+/nmale {
+  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto
+  5 index 4 index 1 mul 1.5 mul add
+  5 index 5 index 3 sqrt 1.5 mul mul add
+  1 index 1 index lineto
+  1 index 1 index 7 index sub moveto
+  1 index 1 index lineto
+  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
+  stroke
+  5 index 5 index 5 index c fill
+  setrgbcolor 1.1 div c fill
+  } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+10 dup scale
+%Arcs:
+gsave
+27 68 37 69 0 0 1 0.513798 l
+37 69 27 68 0 0 1 0.513798 l
+8 52 5 64 0 0 1 0.513798 l
+5 64 8 52 0 0 1 0.513798 l
+16 57 25 55 0 0 1 0.513798 l
+25 55 16 57 0 0 1 0.513798 l
+43 67 37 69 0 0 1 0.513798 l
+37 69 43 67 0 0 1 0.513798 l
+42 57 43 67 0 0 1 0.513798 l
+43 67 42 57 0 0 1 0.513798 l
+62 42 61 33 0 0 1 0.513798 l
+61 33 62 42 0 0 1 0.513798 l
+62 42 58 48 0 0 1 0.513798 l
+58 48 62 42 0 0 1 0.513798 l
+58 27 61 33 0 0 1 0.513798 l
+61 33 58 27 0 0 1 0.513798 l
+57 58 62 63 0 0 1 0.513798 l
+62 63 57 58 0 0 1 0.513798 l
+13 13 21 10 0 0 1 0.513798 l
+21 10 13 13 0 0 1 0.513798 l
+13 13 5 6 0 0 1 0.513798 l
+5 6 13 13 0 0 1 0.513798 l
+17 33 7 38 0 0 1 0.513798 l
+7 38 17 33 0 0 1 0.513798 l
+46 10 59 15 0 0 1 0.513798 l
+59 15 46 10 0 0 1 0.513798 l
+46 10 39 10 0 0 1 0.513798 l
+39 10 46 10 0 0 1 0.513798 l
+27 23 21 10 0 0 1 0.513798 l
+21 10 27 23 0 0 1 0.513798 l
+52 41 56 37 0 0 1 0.513798 l
+56 37 52 41 0 0 1 0.513798 l
+62 63 63 69 0 0 1 0.513798 l
+63 69 62 63 0 0 1 0.513798 l
+36 16 39 10 0 0 1 0.513798 l
+39 10 36 16 0 0 1 0.513798 l
+36 16 30 15 0 0 1 0.513798 l
+30 15 36 16 0 0 1 0.513798 l
+12 42 7 38 0 0 1 0.513798 l
+7 38 12 42 0 0 1 0.513798 l
+12 42 8 52 0 0 1 0.513798 l
+8 52 12 42 0 0 1 0.513798 l
+32 22 30 15 0 0 1 0.513798 l
+30 15 32 22 0 0 1 0.513798 l
+5 25 10 17 0 0 1 0.513798 l
+10 17 5 25 0 0 1 0.513798 l
+5 25 17 33 0 0 1 0.513798 l
+17 33 5 25 0 0 1 0.513798 l
+45 35 48 28 0 0 1 0.513798 l
+48 28 45 35 0 0 1 0.513798 l
+31 32 25 32 0 0 1 0.513798 l
+25 32 31 32 0 0 1 0.513798 l
+31 32 32 39 0 0 1 0.513798 l
+32 39 31 32 0 0 1 0.513798 l
+42 41 38 46 0 0 1 0.513798 l
+38 46 42 41 0 0 1 0.513798 l
+42 41 52 41 0 0 1 0.513798 l
+52 41 42 41 0 0 1 0.513798 l
+5 6 10 17 0 0 1 0.513798 l
+10 17 5 6 0 0 1 0.513798 l
+51 21 59 15 0 0 1 0.513798 l
+59 15 51 21 0 0 1 0.513798 l
+51 21 58 27 0 0 1 0.513798 l
+58 27 51 21 0 0 1 0.513798 l
+52 33 56 37 0 0 1 0.513798 l
+56 37 52 33 0 0 1 0.513798 l
+52 33 48 28 0 0 1 0.513798 l
+48 28 52 33 0 0 1 0.513798 l
+31 62 25 55 0 0 1 0.513798 l
+25 55 31 62 0 0 1 0.513798 l
+31 62 27 68 0 0 1 0.513798 l
+27 68 31 62 0 0 1 0.513798 l
+17 63 5 64 0 0 1 0.513798 l
+5 64 17 63 0 0 1 0.513798 l
+17 63 16 57 0 0 1 0.513798 l
+16 57 17 63 0 0 1 0.513798 l
+21 47 30 40 0 0 1 0.513798 l
+30 40 21 47 0 0 1 0.513798 l
+21 47 30 48 0 0 1 0.513798 l
+30 48 21 47 0 0 1 0.513798 l
+40 30 45 35 0 0 1 0.513798 l
+45 35 40 30 0 0 1 0.513798 l
+40 30 32 22 0 0 1 0.513798 l
+32 22 40 30 0 0 1 0.513798 l
+32 39 30 40 0 0 1 0.513798 l
+30 40 32 39 0 0 1 0.513798 l
+20 26 25 32 0 0 1 0.513798 l
+25 32 20 26 0 0 1 0.513798 l
+20 26 27 23 0 0 1 0.513798 l
+27 23 20 26 0 0 1 0.513798 l
+52 64 63 69 0 0 1 0.513798 l
+63 69 52 64 0 0 1 0.513798 l
+52 64 42 57 0 0 1 0.513798 l
+42 57 52 64 0 0 1 0.513798 l
+49 49 58 48 0 0 1 0.513798 l
+58 48 49 49 0 0 1 0.513798 l
+49 49 57 58 0 0 1 0.513798 l
+57 58 49 49 0 0 1 0.513798 l
+37 52 38 46 0 0 1 0.513798 l
+38 46 37 52 0 0 1 0.513798 l
+37 52 30 48 0 0 1 0.513798 l
+30 48 37 52 0 0 1 0.513798 l
+grestore
+%Nodes:
+gsave
+30 40 0.856329 1 1 1 nc
+56 37 0.856329 1 1 1 nc
+48 28 0.856329 1 1 1 nc
+25 55 0.856329 1 1 1 nc
+25 32 0.856329 1 1 1 nc
+32 39 0.856329 1 1 1 nc
+39 10 0.856329 1 1 1 nc
+30 15 0.856329 1 1 1 nc
+5 64 0.856329 1 1 1 nc
+21 10 0.856329 1 1 1 nc
+10 17 0.856329 1 1 1 nc
+5 6 0.856329 1 1 1 nc
+59 15 0.856329 1 1 1 nc
+45 35 0.856329 1 1 1 nc
+32 22 0.856329 1 1 1 nc
+63 69 0.856329 1 1 1 nc
+62 63 0.856329 1 1 1 nc
+61 33 0.856329 1 1 1 nc
+46 10 0.856329 1 1 1 nc
+38 46 0.856329 1 1 1 nc
+37 69 0.856329 1 1 1 nc
+58 27 0.856329 1 1 1 nc
+58 48 0.856329 1 1 1 nc
+43 67 0.856329 1 1 1 nc
+30 48 0.856329 1 1 1 nc
+27 68 0.856329 1 1 1 nc
+7 38 0.856329 1 1 1 nc
+8 52 0.856329 1 1 1 nc
+16 57 0.856329 1 1 1 nc
+42 57 0.856329 1 1 1 nc
+62 42 0.856329 1 1 1 nc
+57 58 0.856329 1 1 1 nc
+13 13 0.856329 1 1 1 nc
+17 33 0.856329 1 1 1 nc
+27 23 0.856329 1 1 1 nc
+52 41 0.856329 1 1 1 nc
+36 16 0.856329 1 1 1 nc
+12 42 0.856329 1 1 1 nc
+5 25 0.856329 1 1 1 nc
+31 32 0.856329 1 1 1 nc
+42 41 0.856329 1 1 1 nc
+51 21 0.856329 1 1 1 nc
+52 33 0.856329 1 1 1 nc
+31 62 0.856329 1 1 1 nc
+17 63 0.856329 1 1 1 nc
+21 47 0.856329 1 1 1 nc
+40 30 0.856329 1 1 1 nc
+20 26 0.856329 1 1 1 nc
+52 64 0.856329 1 1 1 nc
+49 49 0.856329 1 1 1 nc
+37 52 0.856329 1 1 1 nc
+grestore
+grestore
+showpage
Index: doc/lgf.dox
===================================================================
--- doc/lgf.dox	(revision 1081)
+++ doc/lgf.dox	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -64,9 +64,26 @@
 \endcode
 
-The \c \@arcs section is very similar to the \c \@nodes section, it
-again starts with a header line describing the names of the maps, but
-the \c "label" map is not obligatory here. The following lines
-describe the arcs. The first two tokens of each line are the source
-and the target node of the arc, respectively, then come the map
+The \e LGF files can also contain bipartite graphs, in this case a
+\c \@red_nodes and a \c \@blue_nodes sections describe the node set of the
+graph. If a map is in both of these sections, then it can be used as a
+regular node map.
+
+\code
+ @red_nodes
+ label  only_red_map   name
+ 1      "cherry"       "John"
+ 2      "Santa Claus"  "Jack"
+ 3      "blood"        "Jason"
+ @blue_nodes
+ label  name
+ 4      "Elisabeth"
+ 5      "Eve"
+\endcode
+
+The \c \@arcs section is very similar to the \c \@nodes section,
+it again starts with a header line describing the names of the maps,
+but the \c "label" map is not obligatory here. The following lines
+describe the arcs. The first two tokens of each line are
+the source and the target node of the arc, respectively, then come the map
 values. The source and target tokens must be node labels.
 
Index: doc/mainpage.dox.in
===================================================================
--- doc/mainpage.dox.in	(revision 1039)
+++ doc/mainpage.dox.in	(revision 1221)
@@ -26,5 +26,5 @@
 It is a C++ template library providing efficient implementations of common
 data structures and algorithms with focus on combinatorial optimization
-tasks connected mainly with graphs and networks.
+tasks connected mainly with graphs and networks \cite DezsoJuttnerKovacs11Lemon.
 
 <b>
@@ -38,10 +38,10 @@
 The project is maintained by the
 <a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
-Combinatorial Optimization</a> \ref egres
+Combinatorial Optimization</a> \cite egres
 at the Operations Research Department of the
 <a href="http://www.elte.hu/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
 Budapest, Hungary.
 LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
-initiative \ref coinor.
+initiative \cite coinor.
 
 \section howtoread How to Read the Documentation
Index: doc/min_cost_flow.dox
===================================================================
--- doc/min_cost_flow.dox	(revision 956)
+++ doc/min_cost_flow.dox	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -27,5 +27,5 @@
 minimum total cost from a set of supply nodes to a set of demand nodes
 in a network with capacity constraints (lower and upper bounds)
-and arc costs \ref amo93networkflows.
+and arc costs \cite amo93networkflows.
 
 Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
@@ -102,5 +102,5 @@
 \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
 
-However if the sum of the supply values is zero, then these two problems
+However, if the sum of the supply values is zero, then these two problems
 are equivalent.
 The \ref min_cost_flow_algs "algorithms" in LEMON support the general
Index: doc/references.bib
===================================================================
--- doc/references.bib	(revision 802)
+++ doc/references.bib	(revision 1219)
@@ -5,6 +5,5 @@
   title =        {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
                   {O}ptimization in {N}etworks},
-  howpublished = {\url{http://lemon.cs.elte.hu/}},
-  year =         2009
+  howpublished = {\url{http://lemon.cs.elte.hu/}}
 }
 
@@ -21,4 +20,26 @@
                   {O}perations {R}esearch},
   url =          {http://www.coin-or.org/}
+}
+
+
+%%%%% Papers related to LEMON %%%%%
+
+@article{DezsoJuttnerKovacs11Lemon,
+  author =       {B. Dezs{\H o} and A. J\"uttner and P. Kov\'acs},
+  title =        {{LEMON} -- an open source {C++} graph template library},
+  journal =      {Electronic Notes in Theoretical Computer Science},
+  volume =       {264},
+  pages =        {23--45},
+  year =         {2011},
+  note =         {Proc. 2nd Workshop on Generative Technologies}
+}
+
+@article{KiralyKovacs12MCF,
+  author =       {Z. Kir\'aly and P. Kov\'acs},
+  title =        {Efficient implementations of minimum-cost flow algorithms},
+  journal =      {Acta Universitatis Sapientiae, Informatica},
+  year =         {2012},
+  volume =       {4},
+  pages =        {67--118}
 }
 
@@ -212,4 +233,14 @@
   volume =       23,
   pages =        {309-311}
+}
+
+@article{hartmann93finding,
+  author =       {Mark Hartmann and James B. Orlin},
+  title =        {Finding minimum cost to time ratio cycles with small
+                  integral transit times},
+  journal =      {Networks},
+  year =         1993,
+  volume =       23,
+  pages =        {567-574}
 }
 
@@ -226,4 +257,15 @@
 }
 
+@article{dasdan04experimental,
+  author =       {Ali Dasdan},
+  title =        {Experimental analysis of the fastest optimum cycle
+                  ratio and mean algorithms},
+  journal =      {ACM Trans. Des. Autom. Electron. Syst.},
+  year =         2004,
+  volume =       9,
+  issue =        4,
+  pages =        {385-418}
+} 
+
 
 %%%%% Minimum cost flow algorithms %%%%%
@@ -298,4 +340,17 @@
   address =      {Dublin, Ireland},
   year =         1991,
-  month =        sep,
-}
+  month =        sep
+}
+
+%%%%% Other algorithms %%%%%
+
+@article{grosso08maxclique,
+  author =       {Andrea Grosso and Marco Locatelli and Wayne Pullan},
+  title =        {Simple ingredients leading to very efficient
+                  heuristics for the maximum clique problem},
+  journal =      {Journal of Heuristics},
+  year =         2008,
+  volume =       14,
+  number =       6,
+  pages =        {587--612}
+}
Index: lemon/CMakeLists.txt
===================================================================
--- lemon/CMakeLists.txt	(revision 1113)
+++ lemon/CMakeLists.txt	(revision 1315)
@@ -5,10 +5,10 @@
 
 CONFIGURE_FILE(
-  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
+  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
   ${CMAKE_CURRENT_BINARY_DIR}/config.h
 )
 
 CONFIGURE_FILE(
-  ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.cmake
+  ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.in
   ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc
   @ONLY
@@ -37,5 +37,5 @@
 IF(LEMON_HAVE_CPLEX)
   SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
-  INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
+  INCLUDE_DIRECTORIES(${ILOG_INCLUDE_DIRS})
 ENDIF()
 
@@ -50,7 +50,17 @@
 ENDIF()
 
+IF(LEMON_HAVE_SOPLEX)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} soplex.cc)
+  INCLUDE_DIRECTORIES(${SOPLEX_INCLUDE_DIRS})
+ENDIF()
+
 ADD_LIBRARY(lemon ${LEMON_SOURCES})
+
+TARGET_LINK_LIBRARIES(lemon
+  ${GLPK_LIBRARIES} ${COIN_LIBRARIES} ${ILOG_LIBRARIES} ${SOPLEX_LIBRARIES}
+  )
+
 IF(UNIX)
-  SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon)
+  SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon VERSION ${LEMON_VERSION} SOVERSION ${LEMON_VERSION})
 ENDIF()
 
Index: mon/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 1110)
+++ 	(revision )
@@ -1,151 +1,0 @@
-EXTRA_DIST += \
-	lemon/lemon.pc.in \
-	lemon/lemon.pc.cmake \
-	lemon/CMakeLists.txt \
-	lemon/config.h.cmake
-
-pkgconfig_DATA += lemon/lemon.pc
-
-lib_LTLIBRARIES += lemon/libemon.la
-
-lemon_libemon_la_SOURCES = \
-	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
-
-nodist_lemon_HEADERS = lemon/config.h	
-
-lemon_libemon_la_CXXFLAGS = \
-	$(AM_CXXFLAGS) \
-	$(GLPK_CFLAGS) \
-	$(CPLEX_CFLAGS) \
-	$(SOPLEX_CXXFLAGS) \
-	$(CLP_CXXFLAGS) \
-	$(CBC_CXXFLAGS)
-
-lemon_libemon_la_LDFLAGS = \
-	$(GLPK_LIBS) \
-	$(CPLEX_LIBS) \
-	$(SOPLEX_LIBS) \
-	$(CLP_LIBS) \
-	$(CBC_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
-
-if HAVE_CBC
-lemon_libemon_la_SOURCES += lemon/cbc.cc
-endif
-
-lemon_HEADERS += \
-	lemon/adaptors.h \
-	lemon/arg_parser.h \
-	lemon/assert.h \
-	lemon/bellman_ford.h \
-	lemon/bfs.h \
-	lemon/bin_heap.h \
-	lemon/binomial_heap.h \
-	lemon/bucket_heap.h \
-	lemon/capacity_scaling.h \
-	lemon/cbc.h \
-	lemon/circulation.h \
-	lemon/clp.h \
-	lemon/color.h \
-	lemon/concept_check.h \
-	lemon/connectivity.h \
-	lemon/core.h \
-	lemon/cost_scaling.h \
-	lemon/counter.h \
-	lemon/cplex.h \
-	lemon/cycle_canceling.h \
-	lemon/dfs.h \
-	lemon/dheap.h \
-	lemon/dijkstra.h \
-	lemon/dim2.h \
-	lemon/dimacs.h \
-	lemon/edge_set.h \
-	lemon/elevator.h \
-	lemon/error.h \
-	lemon/euler.h \
-	lemon/fib_heap.h \
-	lemon/fractional_matching.h \
-	lemon/full_graph.h \
-	lemon/glpk.h \
-	lemon/gomory_hu.h \
-	lemon/graph_to_eps.h \
-	lemon/grid_graph.h \
-	lemon/hartmann_orlin_mmc.h \
-	lemon/howard_mmc.h \
-	lemon/hypercube_graph.h \
-	lemon/karp_mmc.h \
-	lemon/kruskal.h \
-	lemon/hao_orlin.h \
-	lemon/lgf_reader.h \
-	lemon/lgf_writer.h \
-	lemon/list_graph.h \
-	lemon/lp.h \
-	lemon/lp_base.h \
-	lemon/lp_skeleton.h \
-	lemon/maps.h \
-	lemon/matching.h \
-	lemon/math.h \
-	lemon/min_cost_arborescence.h \
-	lemon/nauty_reader.h \
-	lemon/network_simplex.h \
-	lemon/pairing_heap.h \
-	lemon/path.h \
-	lemon/planarity.h \
-	lemon/preflow.h \
-	lemon/quad_heap.h \
-	lemon/radix_heap.h \
-	lemon/radix_sort.h \
-	lemon/random.h \
-	lemon/smart_graph.h \
-	lemon/soplex.h \
-	lemon/static_graph.h \
-	lemon/suurballe.h \
-	lemon/time_measure.h \
-	lemon/tolerance.h \
-	lemon/unionfind.h \
-	lemon/bits/windows.h
-
-bits_HEADERS += \
-	lemon/bits/alteration_notifier.h \
-	lemon/bits/array_map.h \
-	lemon/bits/bezier.h \
-	lemon/bits/default_map.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 \
-	lemon/bits/vector_map.h
-
-concept_HEADERS += \
-	lemon/concepts/digraph.h \
-	lemon/concepts/graph.h \
-	lemon/concepts/graph_components.h \
-	lemon/concepts/heap.h \
-	lemon/concepts/maps.h \
-	lemon/concepts/path.h
Index: lemon/adaptors.h
===================================================================
--- lemon/adaptors.h	(revision 1159)
+++ lemon/adaptors.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/assert.h
===================================================================
--- lemon/assert.h	(revision 1242)
+++ lemon/assert.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/base.cc
===================================================================
--- lemon/base.cc	(revision 554)
+++ lemon/base.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -22,4 +22,5 @@
 #include<lemon/tolerance.h>
 #include<lemon/core.h>
+#include<lemon/time_measure.h>
 namespace lemon {
 
@@ -32,3 +33,5 @@
 #endif
 
+  TimeStamp::Format TimeStamp::_format = TimeStamp::NORMAL;
+
 } //namespace lemon
Index: lemon/bellman_ford.h
===================================================================
--- lemon/bellman_ford.h	(revision 960)
+++ lemon/bellman_ford.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -150,5 +150,5 @@
   /// This class provides an efficient implementation of the Bellman-Ford
   /// algorithm. The maximum time complexity of the algorithm is
-  /// <tt>O(ne)</tt>.
+  /// <tt>O(nm)</tt>.
   ///
   /// The Bellman-Ford algorithm solves the single-source shortest path
@@ -201,9 +201,10 @@
     /// The type of the paths.
     typedef PredMapPath<Digraph, PredMap> Path;
-    ///\brief The \ref BellmanFordDefaultOperationTraits
+    ///\brief The \ref lemon::BellmanFordDefaultOperationTraits
     /// "operation traits class" of the algorithm.
     typedef typename TR::OperationTraits OperationTraits;
 
-    ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
+    ///\brief The \ref lemon::BellmanFordDefaultTraits "traits class"
+    ///of the algorithm.
     typedef TR Traits;
 
Index: lemon/bfs.h
===================================================================
--- lemon/bfs.h	(revision 1127)
+++ lemon/bfs.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -153,5 +153,5 @@
     typedef PredMapPath<Digraph, PredMap> Path;
 
-    ///The \ref BfsDefaultTraits "traits class" of the algorithm.
+    ///The \ref lemon::BfsDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
 
Index: lemon/bin_heap.h
===================================================================
--- lemon/bin_heap.h	(revision 758)
+++ lemon/bin_heap.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/alteration_notifier.h
===================================================================
--- lemon/bits/alteration_notifier.h	(revision 463)
+++ lemon/bits/alteration_notifier.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -24,4 +24,5 @@
 
 #include <lemon/core.h>
+#include <lemon/bits/lock.h>
 
 //\ingroup graphbits
@@ -252,5 +253,5 @@
     typedef std::list<ObserverBase*> Observers;
     Observers _observers;
-
+    lemon::bits::Lock _lock;
 
   public:
@@ -333,12 +334,16 @@
 
     void attach(ObserverBase& observer) {
+      _lock.lock();
       observer._index = _observers.insert(_observers.begin(), &observer);
       observer._notifier = this;
+      _lock.unlock();
     }
 
     void detach(ObserverBase& observer) {
+      _lock.lock();
       _observers.erase(observer._index);
       observer._index = _observers.end();
       observer._notifier = 0;
+      _lock.unlock();
     }
 
Index: lemon/bits/array_map.h
===================================================================
--- lemon/bits/array_map.h	(revision 956)
+++ lemon/bits/array_map.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/bezier.h
===================================================================
--- lemon/bits/bezier.h	(revision 1157)
+++ lemon/bits/bezier.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/default_map.h
===================================================================
--- lemon/bits/default_map.h	(revision 956)
+++ lemon/bits/default_map.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/edge_set_extender.h
===================================================================
--- lemon/bits/edge_set_extender.h	(revision 1161)
+++ lemon/bits/edge_set_extender.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * 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 1081)
+++ lemon/bits/graph_adaptor_extender.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 1159)
+++ lemon/bits/graph_extender.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -747,4 +747,585 @@
   };
 
+  // \ingroup _graphbits
+  //
+  // \brief Extender for the BpGraphs
+  template <typename Base>
+  class BpGraphExtender : public Base {
+    typedef Base Parent;
+
+  public:
+
+    typedef BpGraphExtender BpGraph;
+
+    typedef True UndirectedTag;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::RedNode RedNode;
+    typedef typename Parent::BlueNode BlueNode;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    // BpGraph extension
+
+    using Parent::first;
+    using Parent::next;
+    using Parent::id;
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(RedNode) const {
+      return Parent::maxRedId();
+    }
+
+    int maxId(BlueNode) const {
+      return Parent::maxBlueId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    int maxId(Edge) const {
+      return Parent::maxEdgeId();
+    }
+
+    static Node fromId(int id, Node) {
+      return Parent::nodeFromId(id);
+    }
+
+    static Arc fromId(int id, Arc) {
+      return Parent::arcFromId(id);
+    }
+
+    static Edge fromId(int id, Edge) {
+      return Parent::edgeFromId(id);
+    }
+
+    Node u(Edge e) const { return this->redNode(e); }
+    Node v(Edge e) const { return this->blueNode(e); }
+
+    Node oppositeNode(const Node &n, const Edge &e) const {
+      if( n == u(e))
+        return v(e);
+      else if( n == v(e))
+        return u(e);
+      else
+        return INVALID;
+    }
+
+    Arc oppositeArc(const Arc &arc) const {
+      return Parent::direct(arc, !Parent::direction(arc));
+    }
+
+    using Parent::direct;
+    Arc direct(const Edge &edge, const Node &node) const {
+      return Parent::direct(edge, Parent::redNode(edge) == node);
+    }
+
+    RedNode asRedNode(const Node& node) const {
+      if (node == INVALID || Parent::blue(node)) {
+        return INVALID;
+      } else {
+        return Parent::asRedNodeUnsafe(node);
+      }
+    }
+
+    BlueNode asBlueNode(const Node& node) const {
+      if (node == INVALID || Parent::red(node)) {
+        return INVALID;
+      } else {
+        return Parent::asBlueNodeUnsafe(node);
+      }
+    }
+
+    // Alterable extension
+
+    typedef AlterationNotifier<BpGraphExtender, Node> NodeNotifier;
+    typedef AlterationNotifier<BpGraphExtender, RedNode> RedNodeNotifier;
+    typedef AlterationNotifier<BpGraphExtender, BlueNode> BlueNodeNotifier;
+    typedef AlterationNotifier<BpGraphExtender, Arc> ArcNotifier;
+    typedef AlterationNotifier<BpGraphExtender, Edge> EdgeNotifier;
+
+
+  protected:
+
+    mutable NodeNotifier node_notifier;
+    mutable RedNodeNotifier red_node_notifier;
+    mutable BlueNodeNotifier blue_node_notifier;
+    mutable ArcNotifier arc_notifier;
+    mutable EdgeNotifier edge_notifier;
+
+  public:
+
+    NodeNotifier& notifier(Node) const {
+      return node_notifier;
+    }
+
+    RedNodeNotifier& notifier(RedNode) const {
+      return red_node_notifier;
+    }
+
+    BlueNodeNotifier& notifier(BlueNode) const {
+      return blue_node_notifier;
+    }
+
+    ArcNotifier& notifier(Arc) const {
+      return arc_notifier;
+    }
+
+    EdgeNotifier& notifier(Edge) const {
+      return edge_notifier;
+    }
+
+
+
+    class NodeIt : public Node {
+      const BpGraph* _graph;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const BpGraph& graph, const Node& node)
+        : Node(node), _graph(&graph) {}
+
+      NodeIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+    class RedNodeIt : public RedNode {
+      const BpGraph* _graph;
+    public:
+
+      RedNodeIt() {}
+
+      RedNodeIt(Invalid i) : RedNode(i) { }
+
+      explicit RedNodeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<RedNode&>(*this));
+      }
+
+      RedNodeIt(const BpGraph& graph, const RedNode& node)
+        : RedNode(node), _graph(&graph) {}
+
+      RedNodeIt& operator++() {
+        _graph->next(static_cast<RedNode&>(*this));
+        return *this;
+      }
+
+    };
+
+    class BlueNodeIt : public BlueNode {
+      const BpGraph* _graph;
+    public:
+
+      BlueNodeIt() {}
+
+      BlueNodeIt(Invalid i) : BlueNode(i) { }
+
+      explicit BlueNodeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<BlueNode&>(*this));
+      }
+
+      BlueNodeIt(const BpGraph& graph, const BlueNode& node)
+        : BlueNode(node), _graph(&graph) {}
+
+      BlueNodeIt& operator++() {
+        _graph->next(static_cast<BlueNode&>(*this));
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const BpGraph& graph, const Arc& arc) :
+        Arc(arc), _graph(&graph) { }
+
+      ArcIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const BpGraph& graph, const Node& node)
+        : _graph(&graph) {
+        _graph->firstOut(*this, node);
+      }
+
+      OutArcIt(const BpGraph& graph, const Arc& arc)
+        : Arc(arc), _graph(&graph) {}
+
+      OutArcIt& operator++() {
+        _graph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const BpGraph& graph, const Node& node)
+        : _graph(&graph) {
+        _graph->firstIn(*this, node);
+      }
+
+      InArcIt(const BpGraph& graph, const Arc& arc) :
+        Arc(arc), _graph(&graph) {}
+
+      InArcIt& operator++() {
+        _graph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+
+    class EdgeIt : public Parent::Edge {
+      const BpGraph* _graph;
+    public:
+
+      EdgeIt() { }
+
+      EdgeIt(Invalid i) : Edge(i) { }
+
+      explicit EdgeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const BpGraph& graph, const Edge& edge) :
+        Edge(edge), _graph(&graph) { }
+
+      EdgeIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+    class IncEdgeIt : public Parent::Edge {
+      friend class BpGraphExtender;
+      const BpGraph* _graph;
+      bool _direction;
+    public:
+
+      IncEdgeIt() { }
+
+      IncEdgeIt(Invalid i) : Edge(i), _direction(false) { }
+
+      IncEdgeIt(const BpGraph& graph, const Node &node) : _graph(&graph) {
+        _graph->firstInc(*this, _direction, node);
+      }
+
+      IncEdgeIt(const BpGraph& graph, const Edge &edge, const Node &node)
+        : _graph(&graph), Edge(edge) {
+        _direction = (_graph->source(edge) == node);
+      }
+
+      IncEdgeIt& operator++() {
+        _graph->nextInc(*this, _direction);
+        return *this;
+      }
+    };
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the source in this case) of the iterator
+    Node baseNode(const OutArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the target in this case) of the
+    // iterator
+    Node runningNode(const OutArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the target in this case) of the iterator
+    Node baseNode(const InArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the source in this case) of the
+    // iterator
+    Node runningNode(const InArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+    // Base node of the iterator
+    //
+    // Returns the base node of the iterator
+    Node baseNode(const IncEdgeIt &edge) const {
+      return edge._direction ? this->u(edge) : this->v(edge);
+    }
+    // Running node of the iterator
+    //
+    // Returns the running node of the iterator
+    Node runningNode(const IncEdgeIt &edge) const {
+      return edge._direction ? this->v(edge) : this->u(edge);
+    }
+
+    // Mappable extension
+
+    template <typename _Value>
+    class NodeMap
+      : public MapExtender<DefaultMap<BpGraph, Node, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Node, _Value> > Parent;
+
+    public:
+      explicit NodeMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      NodeMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class RedNodeMap
+      : public MapExtender<DefaultMap<BpGraph, RedNode, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, RedNode, _Value> > Parent;
+
+    public:
+      explicit RedNodeMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      RedNodeMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      RedNodeMap& operator=(const RedNodeMap& cmap) {
+        return operator=<RedNodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      RedNodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class BlueNodeMap
+      : public MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > Parent;
+
+    public:
+      explicit BlueNodeMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      BlueNodeMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      BlueNodeMap& operator=(const BlueNodeMap& cmap) {
+        return operator=<BlueNodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      BlueNodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap
+      : public MapExtender<DefaultMap<BpGraph, Arc, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Arc, _Value> > Parent;
+
+    public:
+      explicit ArcMap(const BpGraph& graph)
+        : Parent(graph) {}
+      ArcMap(const BpGraph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+
+    template <typename _Value>
+    class EdgeMap
+      : public MapExtender<DefaultMap<BpGraph, Edge, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Edge, _Value> > Parent;
+
+    public:
+      explicit EdgeMap(const BpGraph& graph)
+        : Parent(graph) {}
+
+      EdgeMap(const BpGraph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    // Alteration extension
+
+    RedNode addRedNode() {
+      RedNode node = Parent::addRedNode();
+      notifier(RedNode()).add(node);
+      notifier(Node()).add(node);
+      return node;
+    }
+
+    BlueNode addBlueNode() {
+      BlueNode node = Parent::addBlueNode();
+      notifier(BlueNode()).add(node);
+      notifier(Node()).add(node);
+      return node;
+    }
+
+    Edge addEdge(const RedNode& from, const BlueNode& to) {
+      Edge edge = Parent::addEdge(from, to);
+      notifier(Edge()).add(edge);
+      std::vector<Arc> av;
+      av.push_back(Parent::direct(edge, true));
+      av.push_back(Parent::direct(edge, false));
+      notifier(Arc()).add(av);
+      return edge;
+    }
+
+    void clear() {
+      notifier(Arc()).clear();
+      notifier(Edge()).clear();
+      notifier(Node()).clear();
+      notifier(BlueNode()).clear();
+      notifier(RedNode()).clear();
+      Parent::clear();
+    }
+
+    template <typename BpGraph, typename NodeRefMap, typename EdgeRefMap>
+    void build(const BpGraph& graph, NodeRefMap& nodeRef,
+               EdgeRefMap& edgeRef) {
+      Parent::build(graph, nodeRef, edgeRef);
+      notifier(RedNode()).build();
+      notifier(BlueNode()).build();
+      notifier(Node()).build();
+      notifier(Edge()).build();
+      notifier(Arc()).build();
+    }
+
+    void erase(const Node& node) {
+      Arc arc;
+      Parent::firstOut(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstOut(arc, node);
+      }
+
+      Parent::firstIn(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstIn(arc, node);
+      }
+
+      if (Parent::red(node)) {
+        notifier(RedNode()).erase(this->asRedNodeUnsafe(node));
+      } else {
+        notifier(BlueNode()).erase(this->asBlueNodeUnsafe(node));
+      }
+
+      notifier(Node()).erase(node);
+      Parent::erase(node);
+    }
+
+    void erase(const Edge& edge) {
+      std::vector<Arc> av;
+      av.push_back(Parent::direct(edge, true));
+      av.push_back(Parent::direct(edge, false));
+      notifier(Arc()).erase(av);
+      notifier(Edge()).erase(edge);
+      Parent::erase(edge);
+    }
+
+    BpGraphExtender() {
+      red_node_notifier.setContainer(*this);
+      blue_node_notifier.setContainer(*this);
+      node_notifier.setContainer(*this);
+      arc_notifier.setContainer(*this);
+      edge_notifier.setContainer(*this);
+    }
+
+    ~BpGraphExtender() {
+      edge_notifier.clear();
+      arc_notifier.clear();
+      node_notifier.clear();
+      blue_node_notifier.clear();
+      red_node_notifier.clear();
+    }
+
+  };
+
 }
 
Index: lemon/bits/lock.h
===================================================================
--- lemon/bits/lock.h	(revision 1270)
+++ lemon/bits/lock.h	(revision 1270)
@@ -0,0 +1,65 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_LOCK_H
+#define LEMON_BITS_LOCK_H
+
+#include <lemon/config.h>
+#if defined(LEMON_USE_PTHREAD)
+#include <pthread.h>
+#elif defined(LEMON_USE_WIN32_THREADS)
+#include <lemon/bits/windows.h>
+#endif
+
+namespace lemon {
+  namespace bits {
+
+#if defined(LEMON_USE_PTHREAD)
+    class Lock {
+    public:
+      Lock() {
+        pthread_mutex_init(&_lock, 0);
+      }
+      ~Lock() {
+        pthread_mutex_destroy(&_lock);
+      }
+      void lock() {
+        pthread_mutex_lock(&_lock);
+      }
+      void unlock() {
+        pthread_mutex_unlock(&_lock);
+      }
+
+    private:
+      pthread_mutex_t _lock;
+    };
+#elif defined(LEMON_USE_WIN32_THREADS)
+    class Lock : public WinLock {};
+#else
+    class Lock {
+    public:
+      Lock() {}
+      ~Lock() {}
+      void lock() {}
+      void unlock() {}
+    };
+#endif
+  }
+}
+
+#endif
Index: lemon/bits/map_extender.h
===================================================================
--- lemon/bits/map_extender.h	(revision 867)
+++ lemon/bits/map_extender.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/path_dump.h
===================================================================
--- lemon/bits/path_dump.h	(revision 1081)
+++ lemon/bits/path_dump.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/solver_bits.h
===================================================================
--- lemon/bits/solver_bits.h	(revision 1142)
+++ lemon/bits/solver_bits.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/traits.h
===================================================================
--- lemon/bits/traits.h	(revision 663)
+++ lemon/bits/traits.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -149,4 +149,86 @@
         : Parent(_digraph, _value) {}
     };
+
+  };
+
+  template <typename GR, typename Enable = void>
+  struct RedNodeNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct RedNodeNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::RedNodeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::RedNodeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::RedNode> {
+  public:
+
+    typedef GR BpGraph;
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::RedNode Item;
+    typedef typename GR::RedNodeIt ItemIt;
+
+    typedef typename RedNodeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template RedNodeMap<V> {
+      typedef typename GR::template RedNodeMap<V> Parent;
+
+    public:
+      typedef typename GR::template RedNodeMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _bpgraph) : Parent(_bpgraph) {}
+      Map(const GR& _bpgraph, const Value& _value)
+        : Parent(_bpgraph, _value) {}
+
+     };
+
+  };
+
+  template <typename GR, typename Enable = void>
+  struct BlueNodeNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct BlueNodeNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::BlueNodeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::BlueNodeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::BlueNode> {
+  public:
+
+    typedef GR BpGraph;
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::BlueNode Item;
+    typedef typename GR::BlueNodeIt ItemIt;
+
+    typedef typename BlueNodeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template BlueNodeMap<V> {
+      typedef typename GR::template BlueNodeMap<V> Parent;
+
+    public:
+      typedef typename GR::template BlueNodeMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _bpgraph) : Parent(_bpgraph) {}
+      Map(const GR& _bpgraph, const Value& _value)
+        : Parent(_bpgraph, _value) {}
+
+     };
 
   };
Index: lemon/bits/windows.cc
===================================================================
--- lemon/bits/windows.cc	(revision 1084)
+++ lemon/bits/windows.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -131,4 +131,36 @@
 #endif
     }
+
+    WinLock::WinLock() {
+#ifdef WIN32
+      CRITICAL_SECTION *lock = new CRITICAL_SECTION;
+      InitializeCriticalSection(lock);
+      _repr = lock;
+#else
+      _repr = 0; //Just to avoid 'unused variable' warning with clang
+#endif
+    }
+
+    WinLock::~WinLock() {
+#ifdef WIN32
+      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
+      DeleteCriticalSection(lock);
+      delete lock;
+#endif
+    }
+
+    void WinLock::lock() {
+#ifdef WIN32
+      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
+      EnterCriticalSection(lock);
+#endif
+    }
+
+    void WinLock::unlock() {
+#ifdef WIN32
+      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
+      LeaveCriticalSection(lock);
+#endif
+    }
   }
 }
Index: lemon/bits/windows.h
===================================================================
--- lemon/bits/windows.h	(revision 576)
+++ lemon/bits/windows.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -29,4 +29,14 @@
     std::string getWinFormattedDate();
     int getWinRndSeed();
+
+    class WinLock {
+    public:
+      WinLock();
+      ~WinLock();
+      void lock();
+      void unlock();
+    private:
+      void *_repr;
+    };
   }
 }
Index: lemon/capacity_scaling.h
===================================================================
--- lemon/capacity_scaling.h	(revision 956)
+++ lemon/capacity_scaling.h	(revision 1298)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -67,7 +67,14 @@
   /// \ref CapacityScaling implements the capacity scaling version
   /// of the successive shortest path algorithm for finding a
-  /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows,
-  /// \ref edmondskarp72theoretical. It is an efficient dual
-  /// solution method.
+  /// \ref min_cost_flow "minimum cost flow" \cite amo93networkflows,
+  /// \cite edmondskarp72theoretical. It is an efficient dual
+  /// solution method, which runs in polynomial time
+  /// \f$O(m\log U (n+m)\log n)\f$, where <i>U</i> denotes the maximum
+  /// of node supply and arc capacity values.
+  ///
+  /// This algorithm is typically slower than \ref CostScaling and
+  /// \ref NetworkSimplex, but in special cases, it can be more
+  /// efficient than them.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
   ///
   /// Most of the parameters of the problem (except for the digraph)
@@ -87,8 +94,9 @@
   /// consider to use the named template parameters instead.
   ///
-  /// \warning Both number types must be signed and all input data must
-  /// be integer.
-  /// \warning This algorithm does not support negative costs for such
-  /// arcs that have infinite upper bound.
+  /// \warning Both \c V and \c C must be signed number types.
+  /// \warning Capacity bounds and supply values must be integer, but
+  /// arc costs can be arbitrary real numbers.
+  /// \warning This algorithm does not support negative costs for
+  /// arcs having infinite upper bound.
 #ifdef DOXYGEN
   template <typename GR, typename V, typename C, typename TR>
@@ -111,5 +119,6 @@
     typedef typename TR::Heap Heap;
 
-    /// The \ref CapacityScalingDefaultTraits "traits class" of the algorithm
+    /// \brief The \ref lemon::CapacityScalingDefaultTraits "traits class"
+    /// of the algorithm
     typedef TR Traits;
 
@@ -155,5 +164,5 @@
 
     // Parameters of the problem
-    bool _have_lower;
+    bool _has_lower;
     Value _sum_supply;
 
@@ -348,8 +357,7 @@
     template <typename LowerMap>
     CapacityScaling& lowerMap(const LowerMap& map) {
-      _have_lower = true;
+      _has_lower = true;
       for (ArcIt a(_graph); a != INVALID; ++a) {
         _lower[_arc_idf[a]] = map[a];
-        _lower[_arc_idb[a]] = map[a];
       }
       return *this;
@@ -423,5 +431,5 @@
     ///
     /// Using this function has the same effect as using \ref supplyMap()
-    /// with such a map in which \c k is assigned to \c s, \c -k is
+    /// with a map in which \c k is assigned to \c s, \c -k is
     /// assigned to \c t and all other nodes have zero supply value.
     ///
@@ -535,5 +543,5 @@
         _cost[j] = _forward[j] ? 1 : -1;
       }
-      _have_lower = false;
+      _has_lower = false;
       return *this;
     }
@@ -638,5 +646,5 @@
     ///
     /// This function returns the total cost of the found flow.
-    /// Its complexity is O(e).
+    /// Its complexity is O(m).
     ///
     /// \note The return type of the function can be specified as a
@@ -676,5 +684,6 @@
     }
 
-    /// \brief Return the flow map (the primal solution).
+    /// \brief Copy the flow values (the primal solution) into the
+    /// given map.
     ///
     /// This function copies the flow value on each arc into the given
@@ -700,5 +709,6 @@
     }
 
-    /// \brief Return the potential map (the dual solution).
+    /// \brief Copy the potential values (the dual solution) into the
+    /// given map.
     ///
     /// This function copies the potential (dual value) of each node
@@ -730,4 +740,9 @@
       if (_sum_supply > 0) return INFEASIBLE;
 
+      // Check lower and upper bounds
+      LEMON_DEBUG(checkBoundMaps(),
+          "Upper bounds must be greater or equal to the lower bounds");
+
+
       // Initialize vectors
       for (int i = 0; i != _root; ++i) {
@@ -739,5 +754,5 @@
       const Value MAX = std::numeric_limits<Value>::max();
       int last_out;
-      if (_have_lower) {
+      if (_has_lower) {
         for (int i = 0; i != _root; ++i) {
           last_out = _first_out[i+1];
@@ -824,4 +839,13 @@
     }
 
+    // Check if the upper bound is greater than or equal to the lower bound
+    // on each forward arc.
+    bool checkBoundMaps() {
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_forward[j] && _upper[j] < _lower[j]) return false;
+      }
+      return true;
+    }
+
     ProblemType start() {
       // Execute the algorithm
@@ -833,8 +857,8 @@
 
       // Handle non-zero lower bounds
-      if (_have_lower) {
+      if (_has_lower) {
         int limit = _first_out[_root];
         for (int j = 0; j != limit; ++j) {
-          if (!_forward[j]) _res_cap[j] += _lower[j];
+          if (_forward[j]) _res_cap[_reverse[j]] += _lower[j];
         }
       }
Index: lemon/cbc.cc
===================================================================
--- lemon/cbc.cc	(revision 1161)
+++ lemon/cbc.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/cbc.h
===================================================================
--- lemon/cbc.h	(revision 956)
+++ lemon/cbc.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -17,5 +17,4 @@
  */
 
-// -*- C++ -*-
 #ifndef LEMON_CBC_H
 #define LEMON_CBC_H
Index: lemon/christofides_tsp.h
===================================================================
--- lemon/christofides_tsp.h	(revision 1270)
+++ lemon/christofides_tsp.h	(revision 1270)
@@ -0,0 +1,254 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_CHRISTOFIDES_TSP_H
+#define LEMON_CHRISTOFIDES_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief Christofides algorithm for symmetric TSP
+
+#include <lemon/full_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/kruskal.h>
+#include <lemon/matching.h>
+#include <lemon/euler.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief Christofides algorithm for symmetric TSP.
+  ///
+  /// ChristofidesTsp implements Christofides' heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This a well-known approximation method for the TSP problem with
+  /// metric cost function.
+  /// It has a guaranteed approximation factor of 3/2 (i.e. it finds a tour
+  /// whose total cost is at most 3/2 of the optimum), but it usually
+  /// provides better solutions in practice.
+  /// This implementation runs in O(n<sup>3</sup>log(n)) time.
+  ///
+  /// The algorithm starts with a \ref spantree "minimum cost spanning tree" and
+  /// finds a \ref MaxWeightedPerfectMatching "minimum cost perfect matching"
+  /// in the subgraph induced by the nodes that have odd degree in the
+  /// spanning tree.
+  /// Finally, it constructs the tour from the \ref EulerIt "Euler traversal"
+  /// of the union of the spanning tree and the matching.
+  /// During this last step, the algorithm simply skips the visited nodes
+  /// (i.e. creates shortcuts) assuming that the triangle inequality holds
+  /// for the cost function.
+  ///
+  /// \tparam CM Type of the cost map.
+  ///
+  /// \warning CM::Value must be a signed number type.
+  template <typename CM>
+  class ChristofidesTsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      std::vector<Node> _path;
+      Cost _sum;
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      ChristofidesTsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm.
+      ///
+      /// This function runs the algorithm.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run() {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 2) {
+          _path.push_back(_gr(0));
+          _path.push_back(_gr(1));
+          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
+        }
+
+        // Compute min. cost spanning tree
+        std::vector<Edge> tree;
+        kruskal(_gr, _cost, std::back_inserter(tree));
+
+        FullGraph::NodeMap<int> deg(_gr, 0);
+        for (int i = 0; i != int(tree.size()); ++i) {
+          Edge e = tree[i];
+          ++deg[_gr.u(e)];
+          ++deg[_gr.v(e)];
+        }
+
+        // Copy the induced subgraph of odd nodes
+        std::vector<Node> odd_nodes;
+        for (NodeIt u(_gr); u != INVALID; ++u) {
+          if (deg[u] % 2 == 1) odd_nodes.push_back(u);
+        }
+
+        SmartGraph sgr;
+        SmartGraph::EdgeMap<Cost> scost(sgr);
+        for (int i = 0; i != int(odd_nodes.size()); ++i) {
+          sgr.addNode();
+        }
+        for (int i = 0; i != int(odd_nodes.size()); ++i) {
+          for (int j = 0; j != int(odd_nodes.size()); ++j) {
+            if (j == i) continue;
+            SmartGraph::Edge e =
+              sgr.addEdge(sgr.nodeFromId(i), sgr.nodeFromId(j));
+            scost[e] = -_cost[_gr.edge(odd_nodes[i], odd_nodes[j])];
+          }
+        }
+
+        // Compute min. cost perfect matching
+        MaxWeightedPerfectMatching<SmartGraph, SmartGraph::EdgeMap<Cost> >
+          mwpm(sgr, scost);
+        mwpm.run();
+
+        for (SmartGraph::EdgeIt e(sgr); e != INVALID; ++e) {
+          if (mwpm.matching(e)) {
+            tree.push_back( _gr.edge(odd_nodes[sgr.id(sgr.u(e))],
+                                     odd_nodes[sgr.id(sgr.v(e))]) );
+          }
+        }
+
+        // Join the spanning tree and the matching
+        sgr.clear();
+        for (int i = 0; i != _gr.nodeNum(); ++i) {
+          sgr.addNode();
+        }
+        for (int i = 0; i != int(tree.size()); ++i) {
+          int ui = _gr.id(_gr.u(tree[i])),
+              vi = _gr.id(_gr.v(tree[i]));
+          sgr.addEdge(sgr.nodeFromId(ui), sgr.nodeFromId(vi));
+        }
+
+        // Compute the tour from the Euler traversal
+        SmartGraph::NodeMap<bool> visited(sgr, false);
+        for (EulerIt<SmartGraph> e(sgr); e != INVALID; ++e) {
+          SmartGraph::Node n = sgr.target(e);
+          if (!visited[n]) {
+            _path.push_back(_gr(sgr.id(n)));
+            visited[n] = true;
+          }
+        }
+
+        _sum = _cost[_gr.edge(_path.back(), _path.front())];
+        for (int i = 0; i < int(_path.size())-1; ++i) {
+          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
+        }
+
+        return _sum;
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _path;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_path.begin(), _path.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_path.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_path[i], _path[i+1]));
+        }
+        if (int(_path.size()) >= 2) {
+          path.addBack(_gr.arc(_path.back(), _path.front()));
+        }
+      }
+
+      /// @}
+
+  };
+
+}; // namespace lemon
+
+#endif
Index: lemon/circulation.h
===================================================================
--- lemon/circulation.h	(revision 1159)
+++ lemon/circulation.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -196,5 +196,6 @@
   public:
 
-    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
+    /// \brief The \ref lemon::CirculationDefaultTraits "traits class"
+    /// of the algorithm.
     typedef TR Traits;
     ///The type of the digraph the algorithm runs on.
Index: lemon/clp.cc
===================================================================
--- lemon/clp.cc	(revision 1142)
+++ lemon/clp.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/clp.h
===================================================================
--- lemon/clp.h	(revision 956)
+++ lemon/clp.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concept_check.h
===================================================================
--- lemon/concept_check.h	(revision 1257)
+++ lemon/concept_check.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/bpgraph.h
===================================================================
--- lemon/concepts/bpgraph.h	(revision 1270)
+++ lemon/concepts/bpgraph.h	(revision 1270)
@@ -0,0 +1,1029 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup graph_concepts
+///\file
+///\brief The concept of undirected graphs.
+
+#ifndef LEMON_CONCEPTS_BPGRAPH_H
+#define LEMON_CONCEPTS_BPGRAPH_H
+
+#include <lemon/concepts/graph_components.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concept_check.h>
+#include <lemon/core.h>
+
+namespace lemon {
+  namespace concepts {
+
+    /// \ingroup graph_concepts
+    ///
+    /// \brief Class describing the concept of undirected bipartite graphs.
+    ///
+    /// This class describes the common interface of all undirected
+    /// bipartite graphs.
+    ///
+    /// Like all concept classes, it only provides an interface
+    /// without any sensible implementation. So any general algorithm for
+    /// undirected bipartite graphs should compile with this class,
+    /// but it will not run properly, of course.
+    /// An actual graph implementation like \ref ListBpGraph or
+    /// \ref SmartBpGraph may have additional functionality.
+    ///
+    /// The bipartite graphs also fulfill the concept of \ref Graph
+    /// "undirected graphs". Bipartite graphs provide a bipartition of
+    /// the node set, namely a red and blue set of the nodes. The
+    /// nodes can be iterated with the RedNodeIt and BlueNodeIt in the
+    /// two node sets. With RedNodeMap and BlueNodeMap values can be
+    /// assigned to the nodes in the two sets.
+    ///
+    /// The edges of the graph cannot connect two nodes of the same
+    /// set. The edges inherent orientation is from the red nodes to
+    /// the blue nodes.
+    ///
+    /// \sa Graph
+    class BpGraph {
+    private:
+      /// BpGraphs are \e not copy constructible. Use bpGraphCopy instead.
+      BpGraph(const BpGraph&) {}
+      /// \brief Assignment of a graph to another one is \e not allowed.
+      /// Use bpGraphCopy instead.
+      void operator=(const BpGraph&) {}
+
+    public:
+      /// Default constructor.
+      BpGraph() {}
+
+      /// \brief Undirected graphs should be tagged with \c UndirectedTag.
+      ///
+      /// Undirected graphs should be tagged with \c UndirectedTag.
+      ///
+      /// This tag helps the \c enable_if technics to make compile time
+      /// specializations for undirected graphs.
+      typedef True UndirectedTag;
+
+      /// The node type of the graph
+
+      /// This class identifies a node of the graph. It also serves
+      /// as a base class of the node iterators,
+      /// thus they convert to this type.
+      class Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Node() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Node(const Node&) { }
+
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        Node(Invalid) { }
+        /// Equality operator
+
+        /// Equality operator.
+        ///
+        /// Two iterators are equal if and only if they point to the
+        /// same object or both are \c INVALID.
+        bool operator==(Node) const { return true; }
+
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Node) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// Artificial ordering operator.
+        ///
+        /// \note This operator only has to define some strict ordering of
+        /// the items; this order has nothing to do with the iteration
+        /// ordering of the items.
+        bool operator<(Node) const { return false; }
+
+      };
+
+      /// Class to represent red nodes.
+
+      /// This class represents the red nodes of the graph. It does
+      /// not supposed to be used directly, because the nodes can be
+      /// represented as Node instances. This class can be used as
+      /// template parameter for special map classes.
+      class RedNode : public Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        RedNode() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        RedNode(const RedNode&) : Node() { }
+
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        RedNode(Invalid) { }
+
+      };
+
+      /// Class to represent blue nodes.
+
+      /// This class represents the blue nodes of the graph. It does
+      /// not supposed to be used directly, because the nodes can be
+      /// represented as Node instances. This class can be used as
+      /// template parameter for special map classes.
+      class BlueNode : public Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        BlueNode() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        BlueNode(const BlueNode&) : Node() { }
+
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        BlueNode(Invalid) { }
+
+      };
+
+      /// Iterator class for the red nodes.
+
+      /// This iterator goes through each red node of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of red nodes in a graph \c g of type \c %BpGraph like this:
+      ///\code
+      /// int count=0;
+      /// for (BpGraph::RedNodeIt n(g); n!=INVALID; ++n) ++count;
+      ///\endcode
+      class RedNodeIt : public RedNode {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        RedNodeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        RedNodeIt(const RedNodeIt& n) : RedNode(n) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        RedNodeIt(Invalid) { }
+        /// Sets the iterator to the first red node.
+
+        /// Sets the iterator to the first red node of the given
+        /// digraph.
+        explicit RedNodeIt(const BpGraph&) { }
+        /// Sets the iterator to the given red node.
+
+        /// Sets the iterator to the given red node of the given
+        /// digraph.
+        RedNodeIt(const BpGraph&, const RedNode&) { }
+        /// Next node.
+
+        /// Assign the iterator to the next red node.
+        ///
+        RedNodeIt& operator++() { return *this; }
+      };
+
+      /// Iterator class for the blue nodes.
+
+      /// This iterator goes through each blue node of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of blue nodes in a graph \c g of type \c %BpGraph like this:
+      ///\code
+      /// int count=0;
+      /// for (BpGraph::BlueNodeIt n(g); n!=INVALID; ++n) ++count;
+      ///\endcode
+      class BlueNodeIt : public BlueNode {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        BlueNodeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        BlueNodeIt(const BlueNodeIt& n) : BlueNode(n) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        BlueNodeIt(Invalid) { }
+        /// Sets the iterator to the first blue node.
+
+        /// Sets the iterator to the first blue node of the given
+        /// digraph.
+        explicit BlueNodeIt(const BpGraph&) { }
+        /// Sets the iterator to the given blue node.
+
+        /// Sets the iterator to the given blue node of the given
+        /// digraph.
+        BlueNodeIt(const BpGraph&, const BlueNode&) { }
+        /// Next node.
+
+        /// Assign the iterator to the next blue node.
+        ///
+        BlueNodeIt& operator++() { return *this; }
+      };
+
+      /// Iterator class for the nodes.
+
+      /// This iterator goes through each node of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of nodes in a graph \c g of type \c %BpGraph like this:
+      ///\code
+      /// int count=0;
+      /// for (BpGraph::NodeIt n(g); n!=INVALID; ++n) ++count;
+      ///\endcode
+      class NodeIt : public Node {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        NodeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        NodeIt(const NodeIt& n) : Node(n) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        NodeIt(Invalid) { }
+        /// Sets the iterator to the first node.
+
+        /// Sets the iterator to the first node of the given digraph.
+        ///
+        explicit NodeIt(const BpGraph&) { }
+        /// Sets the iterator to the given node.
+
+        /// Sets the iterator to the given node of the given digraph.
+        ///
+        NodeIt(const BpGraph&, const Node&) { }
+        /// Next node.
+
+        /// Assign the iterator to the next node.
+        ///
+        NodeIt& operator++() { return *this; }
+      };
+
+
+      /// The edge type of the graph
+
+      /// This class identifies an edge of the graph. It also serves
+      /// as a base class of the edge iterators,
+      /// thus they will convert to this type.
+      class Edge {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Edge() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Edge(const Edge&) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        Edge(Invalid) { }
+        /// Equality operator
+
+        /// Equality operator.
+        ///
+        /// Two iterators are equal if and only if they point to the
+        /// same object or both are \c INVALID.
+        bool operator==(Edge) const { return true; }
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Edge) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// Artificial ordering operator.
+        ///
+        /// \note This operator only has to define some strict ordering of
+        /// the edges; this order has nothing to do with the iteration
+        /// ordering of the edges.
+        bool operator<(Edge) const { return false; }
+      };
+
+      /// Iterator class for the edges.
+
+      /// This iterator goes through each edge of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of edges in a graph \c g of type \c %BpGraph as follows:
+      ///\code
+      /// int count=0;
+      /// for(BpGraph::EdgeIt e(g); e!=INVALID; ++e) ++count;
+      ///\endcode
+      class EdgeIt : public Edge {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        EdgeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        EdgeIt(const EdgeIt& e) : Edge(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        EdgeIt(Invalid) { }
+        /// Sets the iterator to the first edge.
+
+        /// Sets the iterator to the first edge of the given graph.
+        ///
+        explicit EdgeIt(const BpGraph&) { }
+        /// Sets the iterator to the given edge.
+
+        /// Sets the iterator to the given edge of the given graph.
+        ///
+        EdgeIt(const BpGraph&, const Edge&) { }
+        /// Next edge
+
+        /// Assign the iterator to the next edge.
+        ///
+        EdgeIt& operator++() { return *this; }
+      };
+
+      /// Iterator class for the incident edges of a node.
+
+      /// This iterator goes trough the incident undirected edges
+      /// of a certain node of a graph.
+      /// Its usage is quite simple, for example, you can compute the
+      /// degree (i.e. the number of incident edges) of a node \c n
+      /// in a graph \c g of type \c %BpGraph as follows.
+      ///
+      ///\code
+      /// int count=0;
+      /// for(BpGraph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
+      ///\endcode
+      ///
+      /// \warning Loop edges will be iterated twice.
+      class IncEdgeIt : public Edge {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        IncEdgeIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        IncEdgeIt(Invalid) { }
+        /// Sets the iterator to the first incident edge.
+
+        /// Sets the iterator to the first incident edge of the given node.
+        ///
+        IncEdgeIt(const BpGraph&, const Node&) { }
+        /// Sets the iterator to the given edge.
+
+        /// Sets the iterator to the given edge of the given graph.
+        ///
+        IncEdgeIt(const BpGraph&, const Edge&) { }
+        /// Next incident edge
+
+        /// Assign the iterator to the next incident edge
+        /// of the corresponding node.
+        IncEdgeIt& operator++() { return *this; }
+      };
+
+      /// The arc type of the graph
+
+      /// This class identifies a directed arc of the graph. It also serves
+      /// as a base class of the arc iterators,
+      /// thus they will convert to this type.
+      class Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
+        Arc() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        Arc(const Arc&) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
+        Arc(Invalid) { }
+        /// Equality operator
+
+        /// Equality operator.
+        ///
+        /// Two iterators are equal if and only if they point to the
+        /// same object or both are \c INVALID.
+        bool operator==(Arc) const { return true; }
+        /// Inequality operator
+
+        /// Inequality operator.
+        bool operator!=(Arc) const { return true; }
+
+        /// Artificial ordering operator.
+
+        /// Artificial ordering operator.
+        ///
+        /// \note This operator only has to define some strict ordering of
+        /// the arcs; this order has nothing to do with the iteration
+        /// ordering of the arcs.
+        bool operator<(Arc) const { return false; }
+
+        /// Converison to \c Edge
+
+        /// Converison to \c Edge.
+        ///
+        operator Edge() const { return Edge(); }
+      };
+
+      /// Iterator class for the arcs.
+
+      /// This iterator goes through each directed arc of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of arcs in a graph \c g of type \c %BpGraph as follows:
+      ///\code
+      /// int count=0;
+      /// for(BpGraph::ArcIt a(g); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class ArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        ArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        ArcIt(const ArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        ArcIt(Invalid) { }
+        /// Sets the iterator to the first arc.
+
+        /// Sets the iterator to the first arc of the given graph.
+        ///
+        explicit ArcIt(const BpGraph &g)
+        {
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
+        ArcIt(const BpGraph&, const Arc&) { }
+        /// Next arc
+
+        /// Assign the iterator to the next arc.
+        ///
+        ArcIt& operator++() { return *this; }
+      };
+
+      /// Iterator class for the outgoing arcs of a node.
+
+      /// This iterator goes trough the \e outgoing directed arcs of a
+      /// certain node of a graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of outgoing arcs of a node \c n
+      /// in a graph \c g of type \c %BpGraph as follows.
+      ///\code
+      /// int count=0;
+      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class OutArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        OutArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        OutArcIt(const OutArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        OutArcIt(Invalid) { }
+        /// Sets the iterator to the first outgoing arc.
+
+        /// Sets the iterator to the first outgoing arc of the given node.
+        ///
+        OutArcIt(const BpGraph& n, const Node& g) {
+          ::lemon::ignore_unused_variable_warning(n);
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
+        OutArcIt(const BpGraph&, const Arc&) { }
+        /// Next outgoing arc
+
+        /// Assign the iterator to the next
+        /// outgoing arc of the corresponding node.
+        OutArcIt& operator++() { return *this; }
+      };
+
+      /// Iterator class for the incoming arcs of a node.
+
+      /// This iterator goes trough the \e incoming directed arcs of a
+      /// certain node of a graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of incoming arcs of a node \c n
+      /// in a graph \c g of type \c %BpGraph as follows.
+      ///\code
+      /// int count=0;
+      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
+      ///\endcode
+      class InArcIt : public Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
+        InArcIt() { }
+        /// Copy constructor.
+
+        /// Copy constructor.
+        ///
+        InArcIt(const InArcIt& e) : Arc(e) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
+        InArcIt(Invalid) { }
+        /// Sets the iterator to the first incoming arc.
+
+        /// Sets the iterator to the first incoming arc of the given node.
+        ///
+        InArcIt(const BpGraph& g, const Node& n) {
+          ::lemon::ignore_unused_variable_warning(n);
+          ::lemon::ignore_unused_variable_warning(g);
+        }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
+        InArcIt(const BpGraph&, const Arc&) { }
+        /// Next incoming arc
+
+        /// Assign the iterator to the next
+        /// incoming arc of the corresponding node.
+        InArcIt& operator++() { return *this; }
+      };
+
+      /// \brief Standard graph map type for the nodes.
+      ///
+      /// Standard graph map type for the nodes.
+      /// It conforms to the ReferenceMap concept.
+      template<class T>
+      class NodeMap : public ReferenceMap<Node, T, T&, const T&>
+      {
+      public:
+
+        /// Constructor
+        explicit NodeMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        NodeMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        NodeMap(const NodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
+        ///Assignment operator
+        template <typename CMap>
+        NodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \brief Standard graph map type for the red nodes.
+      ///
+      /// Standard graph map type for the red nodes.
+      /// It conforms to the ReferenceMap concept.
+      template<class T>
+      class RedNodeMap : public ReferenceMap<Node, T, T&, const T&>
+      {
+      public:
+
+        /// Constructor
+        explicit RedNodeMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        RedNodeMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        RedNodeMap(const RedNodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
+        ///Assignment operator
+        template <typename CMap>
+        RedNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \brief Standard graph map type for the blue nodes.
+      ///
+      /// Standard graph map type for the blue nodes.
+      /// It conforms to the ReferenceMap concept.
+      template<class T>
+      class BlueNodeMap : public ReferenceMap<Node, T, T&, const T&>
+      {
+      public:
+
+        /// Constructor
+        explicit BlueNodeMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        BlueNodeMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        BlueNodeMap(const BlueNodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
+        ///Assignment operator
+        template <typename CMap>
+        BlueNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \brief Standard graph map type for the arcs.
+      ///
+      /// Standard graph map type for the arcs.
+      /// It conforms to the ReferenceMap concept.
+      template<class T>
+      class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
+      {
+      public:
+
+        /// Constructor
+        explicit ArcMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        ArcMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        ArcMap(const ArcMap& em) :
+          ReferenceMap<Arc, T, T&, const T&>(em) { }
+        ///Assignment operator
+        template <typename CMap>
+        ArcMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Arc, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \brief Standard graph map type for the edges.
+      ///
+      /// Standard graph map type for the edges.
+      /// It conforms to the ReferenceMap concept.
+      template<class T>
+      class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
+      {
+      public:
+
+        /// Constructor
+        explicit EdgeMap(const BpGraph&) { }
+        /// Constructor with given initial value
+        EdgeMap(const BpGraph&, T) { }
+
+      private:
+        ///Copy constructor
+        EdgeMap(const EdgeMap& em) :
+          ReferenceMap<Edge, T, T&, const T&>(em) {}
+        ///Assignment operator
+        template <typename CMap>
+        EdgeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Edge, T>, CMap>();
+          return *this;
+        }
+      };
+
+      /// \brief Gives back %true for red nodes.
+      ///
+      /// Gives back %true for red nodes.
+      bool red(const Node&) const { return true; }
+
+      /// \brief Gives back %true for blue nodes.
+      ///
+      /// Gives back %true for blue nodes.
+      bool blue(const Node&) const { return true; }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts unsafely the node to red node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts safely the node to red node
+      /// object. If the node is not from the red partition, then it
+      /// returns INVALID.
+      RedNode asRedNode(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. If the node is not from the blue partition, then it
+      /// returns INVALID.
+      BlueNode asBlueNode(const Node&) const { return BlueNode(); }
+
+      /// \brief Gives back the red end node of the edge.
+      ///
+      /// Gives back the red end node of the edge.
+      RedNode redNode(const Edge&) const { return RedNode(); }
+
+      /// \brief Gives back the blue end node of the edge.
+      ///
+      /// Gives back the blue end node of the edge.
+      BlueNode blueNode(const Edge&) const { return BlueNode(); }
+
+      /// \brief The first node of the edge.
+      ///
+      /// It is a synonim for the \c redNode().
+      Node u(Edge) const { return INVALID; }
+
+      /// \brief The second node of the edge.
+      ///
+      /// It is a synonim for the \c blueNode().
+      Node v(Edge) const { return INVALID; }
+
+      /// \brief The source node of the arc.
+      ///
+      /// Returns the source node of the given arc.
+      Node source(Arc) const { return INVALID; }
+
+      /// \brief The target node of the arc.
+      ///
+      /// Returns the target node of the given arc.
+      Node target(Arc) const { return INVALID; }
+
+      /// \brief The ID of the node.
+      ///
+      /// Returns the ID of the given node.
+      int id(Node) const { return -1; }
+
+      /// \brief The red ID of the node.
+      ///
+      /// Returns the red ID of the given node.
+      int id(RedNode) const { return -1; }
+
+      /// \brief The blue ID of the node.
+      ///
+      /// Returns the blue ID of the given node.
+      int id(BlueNode) const { return -1; }
+
+      /// \brief The ID of the edge.
+      ///
+      /// Returns the ID of the given edge.
+      int id(Edge) const { return -1; }
+
+      /// \brief The ID of the arc.
+      ///
+      /// Returns the ID of the given arc.
+      int id(Arc) const { return -1; }
+
+      /// \brief The node with the given ID.
+      ///
+      /// Returns the node with the given ID.
+      /// \pre The argument should be a valid node ID in the graph.
+      Node nodeFromId(int) const { return INVALID; }
+
+      /// \brief The edge with the given ID.
+      ///
+      /// Returns the edge with the given ID.
+      /// \pre The argument should be a valid edge ID in the graph.
+      Edge edgeFromId(int) const { return INVALID; }
+
+      /// \brief The arc with the given ID.
+      ///
+      /// Returns the arc with the given ID.
+      /// \pre The argument should be a valid arc ID in the graph.
+      Arc arcFromId(int) const { return INVALID; }
+
+      /// \brief An upper bound on the node IDs.
+      ///
+      /// Returns an upper bound on the node IDs.
+      int maxNodeId() const { return -1; }
+
+      /// \brief An upper bound on the red IDs.
+      ///
+      /// Returns an upper bound on the red IDs.
+      int maxRedId() const { return -1; }
+
+      /// \brief An upper bound on the blue IDs.
+      ///
+      /// Returns an upper bound on the blue IDs.
+      int maxBlueId() const { return -1; }
+
+      /// \brief An upper bound on the edge IDs.
+      ///
+      /// Returns an upper bound on the edge IDs.
+      int maxEdgeId() const { return -1; }
+
+      /// \brief An upper bound on the arc IDs.
+      ///
+      /// Returns an upper bound on the arc IDs.
+      int maxArcId() const { return -1; }
+
+      /// \brief The direction of the arc.
+      ///
+      /// Returns \c true if the given arc goes from a red node to a blue node.
+      bool direction(Arc) const { return true; }
+
+      /// \brief Direct the edge.
+      ///
+      /// Direct the given edge. The returned arc
+      /// represents the given edge and its direction comes
+      /// from the bool parameter. If it is \c true, then the source of the node
+      /// will be a red node.
+      Arc direct(Edge, bool) const {
+        return INVALID;
+      }
+
+      /// \brief Direct the edge.
+      ///
+      /// Direct the given edge. The returned arc represents the given
+      /// edge and its source node is the given node.
+      Arc direct(Edge, Node) const {
+        return INVALID;
+      }
+
+      /// \brief The oppositely directed arc.
+      ///
+      /// Returns the oppositely directed arc representing the same edge.
+      Arc oppositeArc(Arc) const { return INVALID; }
+
+      /// \brief The opposite node on the edge.
+      ///
+      /// Returns the opposite node on the given edge.
+      Node oppositeNode(Node, Edge) const { return INVALID; }
+
+      void first(Node&) const {}
+      void next(Node&) const {}
+
+      void firstRed(RedNode&) const {}
+      void nextRed(RedNode&) const {}
+
+      void firstBlue(BlueNode&) const {}
+      void nextBlue(BlueNode&) const {}
+
+      void first(Edge&) const {}
+      void next(Edge&) const {}
+
+      void first(Arc&) const {}
+      void next(Arc&) const {}
+
+      void firstOut(Arc&, Node) const {}
+      void nextOut(Arc&) const {}
+
+      void firstIn(Arc&, Node) const {}
+      void nextIn(Arc&) const {}
+
+      void firstInc(Edge &, bool &, const Node &) const {}
+      void nextInc(Edge &, bool &) const {}
+
+      // The second parameter is dummy.
+      Node fromId(int, Node) const { return INVALID; }
+      // The second parameter is dummy.
+      Edge fromId(int, Edge) const { return INVALID; }
+      // The second parameter is dummy.
+      Arc fromId(int, Arc) const { return INVALID; }
+
+      // Dummy parameter.
+      int maxId(Node) const { return -1; }
+      // Dummy parameter.
+      int maxId(RedNode) const { return -1; }
+      // Dummy parameter.
+      int maxId(BlueNode) const { return -1; }
+      // Dummy parameter.
+      int maxId(Edge) const { return -1; }
+      // Dummy parameter.
+      int maxId(Arc) const { return -1; }
+
+      /// \brief The base node of the iterator.
+      ///
+      /// Returns the base node of the given incident edge iterator.
+      Node baseNode(IncEdgeIt) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// Returns the running node of the given incident edge iterator.
+      Node runningNode(IncEdgeIt) const { return INVALID; }
+
+      /// \brief The base node of the iterator.
+      ///
+      /// Returns the base node of the given outgoing arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node baseNode(OutArcIt) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// Returns the running node of the given outgoing arc iterator
+      /// (i.e. the target node of the corresponding arc).
+      Node runningNode(OutArcIt) const { return INVALID; }
+
+      /// \brief The base node of the iterator.
+      ///
+      /// Returns the base node of the given incoming arc iterator
+      /// (i.e. the target node of the corresponding arc).
+      Node baseNode(InArcIt) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// Returns the running node of the given incoming arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node runningNode(InArcIt) const { return INVALID; }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<BaseBpGraphComponent, _BpGraph>();
+          checkConcept<IterableBpGraphComponent<>, _BpGraph>();
+          checkConcept<IDableBpGraphComponent<>, _BpGraph>();
+          checkConcept<MappableBpGraphComponent<>, _BpGraph>();
+        }
+      };
+
+    };
+
+  }
+
+}
+
+#endif
Index: lemon/concepts/digraph.h
===================================================================
--- lemon/concepts/digraph.h	(revision 1259)
+++ lemon/concepts/digraph.h	(revision 1271)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -313,5 +313,7 @@
         /// Sets the iterator to the first arc of the given digraph.
         ///
-        explicit ArcIt(const Digraph& g) { ::lemon::ignore_unused_variable_warning(g); }
+        explicit ArcIt(const Digraph& g) {
+          ::lemon::ignore_unused_variable_warning(g);
+        }
         /// Sets the iterator to the given arc.
 
@@ -410,5 +412,5 @@
       /// \brief The base node of the iterator.
       ///
-      /// Returns the base node of the given incomming arc iterator
+      /// Returns the base node of the given incoming arc iterator
       /// (i.e. the target node of the corresponding arc).
       Node baseNode(InArcIt) const { return INVALID; }
@@ -416,5 +418,5 @@
       /// \brief The running node of the iterator.
       ///
-      /// Returns the running node of the given incomming arc iterator
+      /// Returns the running node of the given incoming arc iterator
       /// (i.e. the source node of the corresponding arc).
       Node runningNode(InArcIt) const { return INVALID; }
Index: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 1259)
+++ lemon/concepts/graph.h	(revision 1271)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -73,8 +73,8 @@
     class Graph {
     private:
-      /// Graphs are \e not copy constructible. Use DigraphCopy instead.
+      /// Graphs are \e not copy constructible. Use GraphCopy instead.
       Graph(const Graph&) {}
       /// \brief Assignment of a graph to another one is \e not allowed.
-      /// Use DigraphCopy instead.
+      /// Use GraphCopy instead.
       void operator=(const Graph&) {}
 
@@ -397,5 +397,7 @@
         /// Sets the iterator to the first arc of the given graph.
         ///
-        explicit ArcIt(const Graph &g) { ::lemon::ignore_unused_variable_warning(g); }
+        explicit ArcIt(const Graph &g) {
+          ::lemon::ignore_unused_variable_warning(g);
+        }
         /// Sets the iterator to the given arc.
 
@@ -758,5 +760,5 @@
       /// \brief The base node of the iterator.
       ///
-      /// Returns the base node of the given incomming arc iterator
+      /// Returns the base node of the given incoming arc iterator
       /// (i.e. the target node of the corresponding arc).
       Node baseNode(InArcIt) const { return INVALID; }
@@ -764,5 +766,5 @@
       /// \brief The running node of the iterator.
       ///
-      /// Returns the running node of the given incomming arc iterator
+      /// Returns the running node of the given incoming arc iterator
       /// (i.e. the source node of the corresponding arc).
       Node runningNode(InArcIt) const { return INVALID; }
Index: lemon/concepts/graph_components.h
===================================================================
--- lemon/concepts/graph_components.h	(revision 1263)
+++ lemon/concepts/graph_components.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -300,4 +300,170 @@
     };
 
+    /// \brief Base skeleton class for undirected bipartite graphs.
+    ///
+    /// This class describes the base interface of undirected
+    /// bipartite graph types.  All bipartite graph %concepts have to
+    /// conform to this class.  It extends the interface of \ref
+    /// BaseGraphComponent with an \c Edge type and functions to get
+    /// the end nodes of edges, to convert from arcs to edges and to
+    /// get both direction of edges.
+    class BaseBpGraphComponent : public BaseGraphComponent {
+    public:
+
+      typedef BaseBpGraphComponent BpGraph;
+
+      typedef BaseDigraphComponent::Node Node;
+      typedef BaseDigraphComponent::Arc Arc;
+
+      /// \brief Class to represent red nodes.
+      ///
+      /// This class represents the red nodes of the graph. The red
+      /// nodes can also be used as normal nodes.
+      class RedNode : public Node {
+        typedef Node Parent;
+
+      public:
+        /// \brief Default constructor.
+        ///
+        /// Default constructor.
+        /// \warning The default constructor is not required to set
+        /// the item to some well-defined value. So you should consider it
+        /// as uninitialized.
+        RedNode() {}
+
+        /// \brief Copy constructor.
+        ///
+        /// Copy constructor.
+        RedNode(const RedNode &) : Parent() {}
+
+        /// \brief Constructor for conversion from \c INVALID.
+        ///
+        /// Constructor for conversion from \c INVALID.
+        /// It initializes the item to be invalid.
+        /// \sa Invalid for more details.
+        RedNode(Invalid) {}
+      };
+
+      /// \brief Class to represent blue nodes.
+      ///
+      /// This class represents the blue nodes of the graph. The blue
+      /// nodes can also be used as normal nodes.
+      class BlueNode : public Node {
+        typedef Node Parent;
+
+      public:
+        /// \brief Default constructor.
+        ///
+        /// Default constructor.
+        /// \warning The default constructor is not required to set
+        /// the item to some well-defined value. So you should consider it
+        /// as uninitialized.
+        BlueNode() {}
+
+        /// \brief Copy constructor.
+        ///
+        /// Copy constructor.
+        BlueNode(const BlueNode &) : Parent() {}
+
+        /// \brief Constructor for conversion from \c INVALID.
+        ///
+        /// Constructor for conversion from \c INVALID.
+        /// It initializes the item to be invalid.
+        /// \sa Invalid for more details.
+        BlueNode(Invalid) {}
+
+        /// \brief Constructor for conversion from a node.
+        ///
+        /// Constructor for conversion from a node. The conversion can
+        /// be invalid, since the Node can be member of the red
+        /// set.
+        BlueNode(const Node&) {}
+      };
+
+      /// \brief Gives back %true for red nodes.
+      ///
+      /// Gives back %true for red nodes.
+      bool red(const Node&) const { return true; }
+
+      /// \brief Gives back %true for blue nodes.
+      ///
+      /// Gives back %true for blue nodes.
+      bool blue(const Node&) const { return true; }
+
+      /// \brief Gives back the red end node of the edge.
+      ///
+      /// Gives back the red end node of the edge.
+      RedNode redNode(const Edge&) const { return RedNode(); }
+
+      /// \brief Gives back the blue end node of the edge.
+      ///
+      /// Gives back the blue end node of the edge.
+      BlueNode blueNode(const Edge&) const { return BlueNode(); }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts unsafely the node to red node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts safely the node to red node
+      /// object. If the node is not from the red partition, then it
+      /// returns INVALID.
+      RedNode asRedNode(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. If the node is not from the blue partition, then it
+      /// returns INVALID.
+      BlueNode asBlueNode(const Node&) const { return BlueNode(); }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        typedef typename _BpGraph::Node Node;
+        typedef typename _BpGraph::RedNode RedNode;
+        typedef typename _BpGraph::BlueNode BlueNode;
+        typedef typename _BpGraph::Arc Arc;
+        typedef typename _BpGraph::Edge Edge;
+
+        void constraints() {
+          checkConcept<BaseGraphComponent, _BpGraph>();
+          checkConcept<GraphItem<'n'>, RedNode>();
+          checkConcept<GraphItem<'n'>, BlueNode>();
+          {
+            Node n;
+            RedNode rn;
+            BlueNode bn;
+            Node rnan = rn;
+            Node bnan = bn;
+            Edge e;
+            bool b;
+            b = bpgraph.red(rnan);
+            b = bpgraph.blue(bnan);
+            rn = bpgraph.redNode(e);
+            bn = bpgraph.blueNode(e);
+            rn = bpgraph.asRedNodeUnsafe(rnan);
+            bn = bpgraph.asBlueNodeUnsafe(bnan);
+            rn = bpgraph.asRedNode(rnan);
+            bn = bpgraph.asBlueNode(bnan);
+            ::lemon::ignore_unused_variable_warning(b);
+          }
+        }
+
+        const _BpGraph& bpgraph;
+      };
+
+    };
+
     /// \brief Skeleton class for \e idable directed graphs.
     ///
@@ -432,4 +598,68 @@
     };
 
+    /// \brief Skeleton class for \e idable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of \e idable undirected
+    /// bipartite graphs. It extends \ref IDableGraphComponent with
+    /// the core ID functions of undirected bipartite graphs. Beside
+    /// the regular node ids, this class also provides ids within the
+    /// the red and blue sets of the nodes. This concept is part of
+    /// the BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class IDableBpGraphComponent : public IDableGraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef IDableGraphComponent<BAS> Parent;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+
+      using Parent::id;
+
+      /// \brief Return a unique integer id for the given node in the red set.
+      ///
+      /// Return a unique integer id for the given node in the red set.
+      int id(const RedNode&) const { return -1; }
+
+      /// \brief Return a unique integer id for the given node in the blue set.
+      ///
+      /// Return a unique integer id for the given node in the blue set.
+      int id(const BlueNode&) const { return -1; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// node id in the red set.
+      ///
+      /// Return an integer greater or equal to the maximum
+      /// node id in the red set.
+      int maxRedId() const { return -1; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// node id in the blue set.
+      ///
+      /// Return an integer greater or equal to the maximum
+      /// node id in the blue set.
+      int maxBlueId() const { return -1; }
+
+      template <typename _BpGraph>
+      struct Constraints {
+
+        void constraints() {
+          checkConcept<IDableGraphComponent<Base>, _BpGraph>();
+          typename _BpGraph::Node node;
+          typename _BpGraph::RedNode red;
+          typename _BpGraph::BlueNode blue;
+          int rid = bpgraph.id(red);
+          int bid = bpgraph.id(blue);
+          rid = bpgraph.maxRedId();
+          bid = bpgraph.maxBlueId();
+          ::lemon::ignore_unused_variable_warning(rid);
+          ::lemon::ignore_unused_variable_warning(bid);
+        }
+
+        const _BpGraph& bpgraph;
+      };
+    };
+
     /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
     ///
@@ -646,13 +876,13 @@
       void next(Arc&) const {}
 
-      /// \brief Return the first arc incomming to the given node.
-      ///
-      /// This function gives back the first arc incomming to the
+      /// \brief Return the first arc incoming to the given node.
+      ///
+      /// This function gives back the first arc incoming to the
       /// given node.
       void firstIn(Arc&, const Node&) const {}
 
-      /// \brief Return the next arc incomming to the given node.
-      ///
-      /// This function gives back the next arc incomming to the
+      /// \brief Return the next arc incoming to the given node.
+      ///
+      /// This function gives back the next arc incoming to the
       /// given node.
       void nextIn(Arc&) const {}
@@ -905,4 +1135,95 @@
     };
 
+    /// \brief Skeleton class for iterable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of iterable undirected
+    /// bipartite graphs. It extends \ref IterableGraphComponent with
+    /// the core iterable interface of undirected bipartite graphs.
+    /// This concept is part of the BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class IterableBpGraphComponent : public IterableGraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+      typedef typename Base::Arc Arc;
+      typedef typename Base::Edge Edge;
+
+      typedef IterableBpGraphComponent BpGraph;
+
+      using IterableGraphComponent<BAS>::first;
+      using IterableGraphComponent<BAS>::next;
+
+      /// \name Base Iteration
+      ///
+      /// This interface provides functions for iteration on red and blue nodes.
+      ///
+      /// @{
+
+      /// \brief Return the first red node.
+      ///
+      /// This function gives back the first red node in the iteration order.
+      void first(RedNode&) const {}
+
+      /// \brief Return the next red node.
+      ///
+      /// This function gives back the next red node in the iteration order.
+      void next(RedNode&) const {}
+
+      /// \brief Return the first blue node.
+      ///
+      /// This function gives back the first blue node in the iteration order.
+      void first(BlueNode&) const {}
+
+      /// \brief Return the next blue node.
+      ///
+      /// This function gives back the next blue node in the iteration order.
+      void next(BlueNode&) const {}
+
+
+      /// @}
+
+      /// \name Class Based Iteration
+      ///
+      /// This interface provides iterator classes for red and blue nodes.
+      ///
+      /// @{
+
+      /// \brief This iterator goes through each red node.
+      ///
+      /// This iterator goes through each red node.
+      typedef GraphItemIt<BpGraph, RedNode> RedNodeIt;
+
+      /// \brief This iterator goes through each blue node.
+      ///
+      /// This iterator goes through each blue node.
+      typedef GraphItemIt<BpGraph, BlueNode> BlueNodeIt;
+
+      /// @}
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<IterableGraphComponent<Base>, _BpGraph>();
+
+          typename _BpGraph::RedNode rn(INVALID);
+          bpgraph.first(rn);
+          bpgraph.next(rn);
+          typename _BpGraph::BlueNode bn(INVALID);
+          bpgraph.first(bn);
+          bpgraph.next(bn);
+
+          checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::RedNode>,
+            typename _BpGraph::RedNodeIt>();
+          checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::BlueNode>,
+            typename _BpGraph::BlueNodeIt>();
+        }
+
+        const _BpGraph& bpgraph;
+      };
+    };
+
     /// \brief Skeleton class for alterable directed graphs.
     ///
@@ -930,9 +1251,12 @@
       ArcNotifier;
 
+      mutable NodeNotifier node_notifier;
+      mutable ArcNotifier arc_notifier;
+
       /// \brief Return the node alteration notifier.
       ///
       /// This function gives back the node alteration notifier.
       NodeNotifier& notifier(Node) const {
-         return NodeNotifier();
+        return node_notifier;
       }
 
@@ -941,5 +1265,5 @@
       /// This function gives back the arc alteration notifier.
       ArcNotifier& notifier(Arc) const {
-        return ArcNotifier();
+        return arc_notifier;
       }
 
@@ -977,4 +1301,5 @@
 
       typedef BAS Base;
+      typedef AlterableDigraphComponent<Base> Parent;
       typedef typename Base::Edge Edge;
 
@@ -984,9 +1309,13 @@
       EdgeNotifier;
 
+      mutable EdgeNotifier edge_notifier;
+
+      using Parent::notifier;
+
       /// \brief Return the edge alteration notifier.
       ///
       /// This function gives back the edge alteration notifier.
       EdgeNotifier& notifier(Edge) const {
-        return EdgeNotifier();
+        return edge_notifier;
       }
 
@@ -1002,4 +1331,66 @@
         const _Graph& graph;
         Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for alterable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of alterable undirected
+    /// bipartite graphs. It extends \ref AlterableGraphComponent with
+    /// the alteration notifier interface of bipartite graphs. It
+    /// implements an observer-notifier pattern for the red and blue
+    /// nodes. More obsevers can be registered into the notifier and
+    /// whenever an alteration occured in the graph all the observers
+    /// will be notified about it.
+    template <typename BAS = BaseBpGraphComponent>
+    class AlterableBpGraphComponent : public AlterableGraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef AlterableGraphComponent<Base> Parent;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+
+
+      /// Red node alteration notifier class.
+      typedef AlterationNotifier<AlterableBpGraphComponent, RedNode>
+      RedNodeNotifier;
+
+      /// Blue node alteration notifier class.
+      typedef AlterationNotifier<AlterableBpGraphComponent, BlueNode>
+      BlueNodeNotifier;
+
+      mutable RedNodeNotifier red_node_notifier;
+      mutable BlueNodeNotifier blue_node_notifier;
+
+      using Parent::notifier;
+
+      /// \brief Return the red node alteration notifier.
+      ///
+      /// This function gives back the red node alteration notifier.
+      RedNodeNotifier& notifier(RedNode) const {
+        return red_node_notifier;
+      }
+
+      /// \brief Return the blue node alteration notifier.
+      ///
+      /// This function gives back the blue node alteration notifier.
+      BlueNodeNotifier& notifier(BlueNode) const {
+        return blue_node_notifier;
+      }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<AlterableGraphComponent<Base>, _BpGraph>();
+          typename _BpGraph::RedNodeNotifier& rnn
+            = bpgraph.notifier(typename _BpGraph::RedNode());
+          typename _BpGraph::BlueNodeNotifier& bnn
+            = bpgraph.notifier(typename _BpGraph::BlueNode());
+          ::lemon::ignore_unused_variable_warning(rnn);
+          ::lemon::ignore_unused_variable_warning(bnn);
+        }
+
+        const _BpGraph& bpgraph;
       };
     };
@@ -1308,4 +1699,148 @@
     };
 
+    /// \brief Skeleton class for mappable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of mappable undirected
+    /// bipartite graphs.  It extends \ref MappableGraphComponent with
+    /// the standard graph map class for red and blue nodes (\c
+    /// RedNodeMap and BlueNodeMap). This concept is part of the
+    /// BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class MappableBpGraphComponent : public MappableGraphComponent<BAS>  {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+
+      typedef MappableBpGraphComponent BpGraph;
+
+      /// \brief Standard graph map for the red nodes.
+      ///
+      /// Standard graph map for the red nodes.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class RedNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> {
+        typedef GraphMap<MappableBpGraphComponent, Node, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the graph.
+        explicit RedNodeMap(const MappableBpGraphComponent& graph)
+          : Parent(graph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the graph and initalize the values.
+        RedNodeMap(const MappableBpGraphComponent& graph, const V& value)
+          : Parent(graph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        RedNodeMap(const RedNodeMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        RedNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+      /// \brief Standard graph map for the blue nodes.
+      ///
+      /// Standard graph map for the blue nodes.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class BlueNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> {
+        typedef GraphMap<MappableBpGraphComponent, Node, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the graph.
+        explicit BlueNodeMap(const MappableBpGraphComponent& graph)
+          : Parent(graph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the graph and initalize the values.
+        BlueNodeMap(const MappableBpGraphComponent& graph, const V& value)
+          : Parent(graph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        BlueNodeMap(const BlueNodeMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        BlueNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+
+      template <typename _BpGraph>
+      struct Constraints {
+
+        struct Dummy {
+          int value;
+          Dummy() : value(0) {}
+          Dummy(int _v) : value(_v) {}
+        };
+
+        void constraints() {
+          checkConcept<MappableGraphComponent<Base>, _BpGraph>();
+
+          { // int map test
+            typedef typename _BpGraph::template RedNodeMap<int>
+              IntRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, int>,
+              IntRedNodeMap >();
+          } { // bool map test
+            typedef typename _BpGraph::template RedNodeMap<bool>
+              BoolRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, bool>,
+              BoolRedNodeMap >();
+          } { // Dummy map test
+            typedef typename _BpGraph::template RedNodeMap<Dummy>
+              DummyRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, Dummy>,
+              DummyRedNodeMap >();
+          }
+
+          { // int map test
+            typedef typename _BpGraph::template BlueNodeMap<int>
+              IntBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, int>,
+              IntBlueNodeMap >();
+          } { // bool map test
+            typedef typename _BpGraph::template BlueNodeMap<bool>
+              BoolBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, bool>,
+              BoolBlueNodeMap >();
+          } { // Dummy map test
+            typedef typename _BpGraph::template BlueNodeMap<Dummy>
+              DummyBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, Dummy>,
+              DummyBlueNodeMap >();
+          }
+        }
+
+        const _BpGraph& bpgraph;
+      };
+    };
+
     /// \brief Skeleton class for extendable directed graphs.
     ///
@@ -1398,4 +1933,63 @@
     };
 
+    /// \brief Skeleton class for extendable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of extendable undirected
+    /// bipartite graphs. It extends \ref BaseGraphComponent with
+    /// functions for adding nodes and edges to the graph. This
+    /// concept requires \ref AlterableBpGraphComponent.
+    template <typename BAS = BaseBpGraphComponent>
+    class ExtendableBpGraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+      typedef typename Base::Edge Edge;
+
+      /// \brief Add a new red node to the digraph.
+      ///
+      /// This function adds a red new node to the digraph.
+      RedNode addRedNode() {
+        return INVALID;
+      }
+
+      /// \brief Add a new blue node to the digraph.
+      ///
+      /// This function adds a blue new node to the digraph.
+      BlueNode addBlueNode() {
+        return INVALID;
+      }
+
+      /// \brief Add a new edge connecting the given two nodes.
+      ///
+      /// This function adds a new edge connecting the given two nodes
+      /// of the graph. The first node has to be a red node, and the
+      /// second one a blue node.
+      Edge addEdge(const RedNode&, const BlueNode&) {
+        return INVALID;
+      }
+      Edge addEdge(const BlueNode&, const RedNode&) {
+        return INVALID;
+      }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _BpGraph>();
+          typename _BpGraph::RedNode red_node;
+          typename _BpGraph::BlueNode blue_node;
+          red_node = bpgraph.addRedNode();
+          blue_node = bpgraph.addBlueNode();
+          typename _BpGraph::Edge edge;
+          edge = bpgraph.addEdge(red_node, blue_node);
+          edge = bpgraph.addEdge(blue_node, red_node);
+        }
+
+        _BpGraph& bpgraph;
+      };
+    };
+
     /// \brief Skeleton class for erasable directed graphs.
     ///
@@ -1478,4 +2072,13 @@
     };
 
+    /// \brief Skeleton class for erasable undirected graphs.
+    ///
+    /// This class describes the interface of erasable undirected
+    /// bipartite graphs. It extends \ref BaseBpGraphComponent with
+    /// functions for removing nodes and edges from the graph. This
+    /// concept requires \ref AlterableBpGraphComponent.
+    template <typename BAS = BaseBpGraphComponent>
+    class ErasableBpGraphComponent : public ErasableGraphComponent<BAS> {};
+
     /// \brief Skeleton class for clearable directed graphs.
     ///
@@ -1514,25 +2117,14 @@
     /// This concept requires \ref AlterableGraphComponent.
     template <typename BAS = BaseGraphComponent>
-    class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {
-    public:
-
-      typedef BAS Base;
-
-      /// \brief Erase all nodes and edges from the graph.
-      ///
-      /// This function erases all nodes and edges from the graph.
-      void clear() {}
-
-      template <typename _Graph>
-      struct Constraints {
-        void constraints() {
-          checkConcept<Base, _Graph>();
-          graph.clear();
-        }
-
-        _Graph& graph;
-        Constraints() {}
-      };
-    };
+    class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {};
+
+    /// \brief Skeleton class for clearable undirected biparite graphs.
+    ///
+    /// This class describes the interface of clearable undirected
+    /// bipartite graphs. It extends \ref BaseBpGraphComponent with a
+    /// function for clearing the graph.  This concept requires \ref
+    /// AlterableBpGraphComponent.
+    template <typename BAS = BaseBpGraphComponent>
+    class ClearableBpGraphComponent : public ClearableGraphComponent<BAS> {};
 
   }
Index: lemon/concepts/heap.h
===================================================================
--- lemon/concepts/heap.h	(revision 1259)
+++ lemon/concepts/heap.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/maps.h
===================================================================
--- lemon/concepts/maps.h	(revision 1257)
+++ lemon/concepts/maps.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/path.h
===================================================================
--- lemon/concepts/path.h	(revision 1259)
+++ lemon/concepts/path.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: mon/config.h.cmake
===================================================================
--- lemon/config.h.cmake	(revision 725)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#define LEMON_VERSION "@PROJECT_VERSION@"
-#cmakedefine LEMON_HAVE_LONG_LONG 1
-#cmakedefine LEMON_HAVE_LP 1
-#cmakedefine LEMON_HAVE_MIP 1
-#cmakedefine LEMON_HAVE_GLPK 1
-#cmakedefine LEMON_HAVE_CPLEX 1
-#cmakedefine LEMON_HAVE_CLP 1
-#cmakedefine LEMON_HAVE_CBC 1
Index: lemon/config.h.in
===================================================================
--- lemon/config.h.in	(revision 725)
+++ lemon/config.h.in	(revision 1306)
@@ -1,26 +1,22 @@
-/* The version string */
-#undef LEMON_VERSION
+#define LEMON_VERSION "@PROJECT_VERSION@"
+#cmakedefine LEMON_HAVE_LONG_LONG 1
 
-/* Define to 1 if you have long long */
-#undef LEMON_HAVE_LONG_LONG
+#cmakedefine LEMON_HAVE_LP 1
+#cmakedefine LEMON_HAVE_MIP 1
+#cmakedefine LEMON_HAVE_GLPK 1
+#cmakedefine LEMON_HAVE_CPLEX 1
+#cmakedefine LEMON_HAVE_SOPLEX 1
+#cmakedefine LEMON_HAVE_CLP 1
+#cmakedefine LEMON_HAVE_CBC 1
 
-/* Define to 1 if you have any LP solver. */
-#undef LEMON_HAVE_LP
+#define _LEMON_CPLEX 1
+#define _LEMON_CLP 2
+#define _LEMON_GLPK 3
+#define _LEMON_SOPLEX 4
+#define _LEMON_CBC 5
 
-/* Define to 1 if you have any MIP solver. */
-#undef LEMON_HAVE_MIP
+#cmakedefine LEMON_DEFAULT_LP _LEMON_@LEMON_DEFAULT_LP@
+#cmakedefine LEMON_DEFAULT_MIP _LEMON_@LEMON_DEFAULT_MIP@
 
-/* Define to 1 if you have CPLEX. */
-#undef LEMON_HAVE_CPLEX
-
-/* Define to 1 if you have GLPK. */
-#undef LEMON_HAVE_GLPK
-
-/* Define to 1 if you have SOPLEX */
-#undef LEMON_HAVE_SOPLEX
-
-/* Define to 1 if you have CLP */
-#undef LEMON_HAVE_CLP
-
-/* Define to 1 if you have CBC */
-#undef LEMON_HAVE_CBC
+#cmakedefine LEMON_USE_PTHREAD 1
+#cmakedefine LEMON_USE_WIN32_THREADS 1
Index: lemon/connectivity.h
===================================================================
--- lemon/connectivity.h	(revision 1268)
+++ lemon/connectivity.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/core.h
===================================================================
--- lemon/core.h	(revision 1263)
+++ lemon/core.h	(revision 1325)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -38,11 +38,5 @@
 #endif
 
-#ifdef __GNUC__
-#define GCC_VERSION (__GNUC__ * 10000                   \
-                     + __GNUC_MINOR__ * 100             \
-                     + __GNUC_PATCHLEVEL__)
-#endif
-
-#if GCC_VERSION >= 40800
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
 // Needed by the [DI]GRAPH_TYPEDEFS marcos for gcc 4.8
 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
@@ -160,4 +154,47 @@
   typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
 
+  ///Create convenience typedefs for the bipartite graph types and iterators
+
+  ///This \c \#define creates the same convenient type definitions as
+  ///defined by \ref GRAPH_TYPEDEFS(BpGraph) and ten more, namely it
+  ///creates \c RedNode, \c RedNodeIt, \c BoolRedNodeMap,
+  ///\c IntRedNodeMap, \c DoubleRedNodeMap, \c BlueNode, \c BlueNodeIt,
+  ///\c BoolBlueNodeMap, \c IntBlueNodeMap, \c DoubleBlueNodeMap.
+  ///
+  ///\note If the graph type is a dependent type, ie. the graph type depend
+  ///on a template parameter, then use \c TEMPLATE_BPGRAPH_TYPEDEFS()
+  ///macro.
+#define BPGRAPH_TYPEDEFS(BpGraph)                                       \
+  GRAPH_TYPEDEFS(BpGraph);                                              \
+  typedef BpGraph::RedNode RedNode;                                     \
+  typedef BpGraph::RedNodeIt RedNodeIt;                                 \
+  typedef BpGraph::RedNodeMap<bool> BoolRedNodeMap;                     \
+  typedef BpGraph::RedNodeMap<int> IntRedNodeMap;                       \
+  typedef BpGraph::RedNodeMap<double> DoubleRedNodeMap;                 \
+  typedef BpGraph::BlueNode BlueNode;                                   \
+  typedef BpGraph::BlueNodeIt BlueNodeIt;                               \
+  typedef BpGraph::BlueNodeMap<bool> BoolBlueNodeMap;                   \
+  typedef BpGraph::BlueNodeMap<int> IntBlueNodeMap;                     \
+  typedef BpGraph::BlueNodeMap<double> DoubleBlueNodeMap
+
+  ///Create convenience typedefs for the bipartite graph types and iterators
+
+  ///\see BPGRAPH_TYPEDEFS
+  ///
+  ///\note Use this macro, if the graph type is a dependent type,
+  ///ie. the graph type depend on a template parameter.
+#define TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph)                                  \
+  TEMPLATE_GRAPH_TYPEDEFS(BpGraph);                                         \
+  typedef typename BpGraph::RedNode RedNode;                                \
+  typedef typename BpGraph::RedNodeIt RedNodeIt;                            \
+  typedef typename BpGraph::template RedNodeMap<bool> BoolRedNodeMap;       \
+  typedef typename BpGraph::template RedNodeMap<int> IntRedNodeMap;         \
+  typedef typename BpGraph::template RedNodeMap<double> DoubleRedNodeMap;   \
+  typedef typename BpGraph::BlueNode BlueNode;                              \
+  typedef typename BpGraph::BlueNodeIt BlueNodeIt;                          \
+  typedef typename BpGraph::template BlueNodeMap<bool> BoolBlueNodeMap;     \
+  typedef typename BpGraph::template BlueNodeMap<int> IntBlueNodeMap;       \
+  typedef typename BpGraph::template BlueNodeMap<double> DoubleBlueNodeMap
+
   /// \brief Function to count the items in a graph.
   ///
@@ -211,4 +248,72 @@
   }
 
+  namespace _graph_utils_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct CountRedNodesSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::RedNode>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountRedNodesSelector<
+      Graph, typename
+      enable_if<typename Graph::NodeNumTag, void>::type>
+    {
+      static int count(const Graph &g) {
+        return g.redNum();
+      }
+    };
+  }
+
+  /// \brief Function to count the red nodes in the graph.
+  ///
+  /// This function counts the red nodes in the graph.
+  /// The complexity of the function is O(n) but for some
+  /// graph structures it is specialized to run in O(1).
+  ///
+  /// If the graph contains a \e redNum() member function and a
+  /// \e NodeNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the node set.
+  template <typename Graph>
+  inline int countRedNodes(const Graph& g) {
+    return _graph_utils_bits::CountRedNodesSelector<Graph>::count(g);
+  }
+
+  namespace _graph_utils_bits {
+
+    template <typename Graph, typename Enable = void>
+    struct CountBlueNodesSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::BlueNode>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountBlueNodesSelector<
+      Graph, typename
+      enable_if<typename Graph::NodeNumTag, void>::type>
+    {
+      static int count(const Graph &g) {
+        return g.blueNum();
+      }
+    };
+  }
+
+  /// \brief Function to count the blue nodes in the graph.
+  ///
+  /// This function counts the blue nodes in the graph.
+  /// The complexity of the function is O(n) but for some
+  /// graph structures it is specialized to run in O(1).
+  ///
+  /// If the graph contains a \e blueNum() member function and a
+  /// \e NodeNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the node set.
+  template <typename Graph>
+  inline int countBlueNodes(const Graph& g) {
+    return _graph_utils_bits::CountBlueNodesSelector<Graph>::count(g);
+  }
+
   // Arc counting:
 
@@ -452,10 +557,67 @@
       template <typename From, typename NodeRefMap, typename EdgeRefMap>
       static void copy(const From& from, Graph &to,
-                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
+                       NodeRefMap& nodeRefMap,
+                       EdgeRefMap& edgeRefMap) {
         to.build(from, nodeRefMap, edgeRefMap);
       }
     };
 
+    template <typename BpGraph, typename Enable = void>
+    struct BpGraphCopySelector {
+      template <typename From, typename RedNodeRefMap,
+                typename BlueNodeRefMap, typename EdgeRefMap>
+      static void copy(const From& from, BpGraph &to,
+                       RedNodeRefMap& redNodeRefMap,
+                       BlueNodeRefMap& blueNodeRefMap,
+                       EdgeRefMap& edgeRefMap) {
+        to.clear();
+        for (typename From::RedNodeIt it(from); it != INVALID; ++it) {
+          redNodeRefMap[it] = to.addRedNode();
+        }
+        for (typename From::BlueNodeIt it(from); it != INVALID; ++it) {
+          blueNodeRefMap[it] = to.addBlueNode();
+        }
+        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
+          edgeRefMap[it] = to.addEdge(redNodeRefMap[from.redNode(it)],
+                                      blueNodeRefMap[from.blueNode(it)]);
+        }
+      }
+    };
+
+    template <typename BpGraph>
+    struct BpGraphCopySelector<
+      BpGraph,
+      typename enable_if<typename BpGraph::BuildTag, void>::type>
+    {
+      template <typename From, typename RedNodeRefMap,
+                typename BlueNodeRefMap, typename EdgeRefMap>
+      static void copy(const From& from, BpGraph &to,
+                       RedNodeRefMap& redNodeRefMap,
+                       BlueNodeRefMap& blueNodeRefMap,
+                       EdgeRefMap& edgeRefMap) {
+        to.build(from, redNodeRefMap, blueNodeRefMap, edgeRefMap);
+      }
+    };
+
   }
+
+  /// \brief Check whether a graph is undirected.
+  ///
+  /// This function returns \c true if the given graph is undirected.
+#ifdef DOXYGEN
+  template <typename GR>
+  bool undirected(const GR& g) { return false; }
+#else
+  template <typename GR>
+  typename enable_if<UndirectedTagIndicator<GR>, bool>::type
+  undirected(const GR&) {
+    return true;
+  }
+  template <typename GR>
+  typename disable_if<UndirectedTagIndicator<GR>, bool>::type
+  undirected(const GR&) {
+    return false;
+  }
+#endif
 
   /// \brief Class to copy a digraph.
@@ -982,4 +1144,452 @@
   graphCopy(const From& from, To& to) {
     return GraphCopy<From, To>(from, to);
+  }
+
+  /// \brief Class to copy a bipartite graph.
+  ///
+  /// Class to copy a bipartite graph to another graph (duplicate a
+  /// graph). The simplest way of using it is through the
+  /// \c bpGraphCopy() function.
+  ///
+  /// This class not only make a copy of a bipartite graph, but it can
+  /// create references and cross references between the nodes, edges
+  /// and arcs of the two graphs, and it can copy maps for using with
+  /// the newly created graph.
+  ///
+  /// To make a copy from a graph, first an instance of BpGraphCopy
+  /// should be created, then the data belongs to the graph should
+  /// assigned to copy. In the end, the \c run() member should be
+  /// called.
+  ///
+  /// The next code copies a graph with several data:
+  ///\code
+  ///  BpGraphCopy<OrigBpGraph, NewBpGraph> cg(orig_graph, new_graph);
+  ///  // Create references for the nodes
+  ///  OrigBpGraph::NodeMap<NewBpGraph::Node> nr(orig_graph);
+  ///  cg.nodeRef(nr);
+  ///  // Create cross references (inverse) for the edges
+  ///  NewBpGraph::EdgeMap<OrigBpGraph::Edge> ecr(new_graph);
+  ///  cg.edgeCrossRef(ecr);
+  ///  // Copy a red node map
+  ///  OrigBpGraph::RedNodeMap<double> ormap(orig_graph);
+  ///  NewBpGraph::RedNodeMap<double> nrmap(new_graph);
+  ///  cg.redNodeMap(ormap, nrmap);
+  ///  // Copy a node
+  ///  OrigBpGraph::Node on;
+  ///  NewBpGraph::Node nn;
+  ///  cg.node(on, nn);
+  ///  // Execute copying
+  ///  cg.run();
+  ///\endcode
+  template <typename From, typename To>
+  class BpGraphCopy {
+  private:
+
+    typedef typename From::Node Node;
+    typedef typename From::RedNode RedNode;
+    typedef typename From::BlueNode BlueNode;
+    typedef typename From::NodeIt NodeIt;
+    typedef typename From::Arc Arc;
+    typedef typename From::ArcIt ArcIt;
+    typedef typename From::Edge Edge;
+    typedef typename From::EdgeIt EdgeIt;
+
+    typedef typename To::Node TNode;
+    typedef typename To::RedNode TRedNode;
+    typedef typename To::BlueNode TBlueNode;
+    typedef typename To::Arc TArc;
+    typedef typename To::Edge TEdge;
+
+    typedef typename From::template RedNodeMap<TRedNode> RedNodeRefMap;
+    typedef typename From::template BlueNodeMap<TBlueNode> BlueNodeRefMap;
+    typedef typename From::template EdgeMap<TEdge> EdgeRefMap;
+
+    struct NodeRefMap {
+      NodeRefMap(const From& from, const RedNodeRefMap& red_node_ref,
+                 const BlueNodeRefMap& blue_node_ref)
+        : _from(from), _red_node_ref(red_node_ref),
+          _blue_node_ref(blue_node_ref) {}
+
+      typedef typename From::Node Key;
+      typedef typename To::Node Value;
+
+      Value operator[](const Key& key) const {
+        if (_from.red(key)) {
+          return _red_node_ref[_from.asRedNodeUnsafe(key)];
+        } else {
+          return _blue_node_ref[_from.asBlueNodeUnsafe(key)];
+        }
+      }
+
+      const From& _from;
+      const RedNodeRefMap& _red_node_ref;
+      const BlueNodeRefMap& _blue_node_ref;
+    };
+
+    struct ArcRefMap {
+      ArcRefMap(const From& from, const To& to, const EdgeRefMap& edge_ref)
+        : _from(from), _to(to), _edge_ref(edge_ref) {}
+
+      typedef typename From::Arc Key;
+      typedef typename To::Arc Value;
+
+      Value operator[](const Key& key) const {
+        return _to.direct(_edge_ref[key], _from.direction(key));
+      }
+
+      const From& _from;
+      const To& _to;
+      const EdgeRefMap& _edge_ref;
+    };
+
+  public:
+
+    /// \brief Constructor of BpGraphCopy.
+    ///
+    /// Constructor of BpGraphCopy for copying the content of the
+    /// \c from graph into the \c to graph.
+    BpGraphCopy(const From& from, To& to)
+      : _from(from), _to(to) {}
+
+    /// \brief Destructor of BpGraphCopy
+    ///
+    /// Destructor of BpGraphCopy.
+    ~BpGraphCopy() {
+      for (int i = 0; i < int(_node_maps.size()); ++i) {
+        delete _node_maps[i];
+      }
+      for (int i = 0; i < int(_red_maps.size()); ++i) {
+        delete _red_maps[i];
+      }
+      for (int i = 0; i < int(_blue_maps.size()); ++i) {
+        delete _blue_maps[i];
+      }
+      for (int i = 0; i < int(_arc_maps.size()); ++i) {
+        delete _arc_maps[i];
+      }
+      for (int i = 0; i < int(_edge_maps.size()); ++i) {
+        delete _edge_maps[i];
+      }
+    }
+
+    /// \brief Copy the node references into the given map.
+    ///
+    /// This function copies the node references into the given map.
+    /// The parameter should be a map, whose key type is the Node type of
+    /// the source graph, while the value type is the Node type of the
+    /// destination graph.
+    template <typename NodeRef>
+    BpGraphCopy& nodeRef(NodeRef& map) {
+      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
+                           NodeRefMap, NodeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the node cross references into the given map.
+    ///
+    /// This function copies the node cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Node type of the destination graph, while the value type is
+    /// the Node type of the source graph.
+    template <typename NodeCrossRef>
+    BpGraphCopy& nodeCrossRef(NodeCrossRef& map) {
+      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
+                           NodeRefMap, NodeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node map.
+    ///
+    /// This function makes a copy of the given node map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Node type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Node type of the source graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
+      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
+                           NodeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node.
+    ///
+    /// This function makes a copy of the given node.
+    BpGraphCopy& node(const Node& node, TNode& tnode) {
+      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
+                           NodeRefMap, TNode>(node, tnode));
+      return *this;
+    }
+
+    /// \brief Copy the red node references into the given map.
+    ///
+    /// This function copies the red node references into the given
+    /// map.  The parameter should be a map, whose key type is the
+    /// Node type of the source graph with the red item set, while the
+    /// value type is the Node type of the destination graph.
+    template <typename RedRef>
+    BpGraphCopy& redRef(RedRef& map) {
+      _red_maps.push_back(new _core_bits::RefCopy<From, RedNode,
+                          RedNodeRefMap, RedRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the red node cross references into the given map.
+    ///
+    /// This function copies the red node cross references (reverse
+    /// references) into the given map. The parameter should be a map,
+    /// whose key type is the Node type of the destination graph with
+    /// the red item set, while the value type is the Node type of the
+    /// source graph.
+    template <typename RedCrossRef>
+    BpGraphCopy& redCrossRef(RedCrossRef& map) {
+      _red_maps.push_back(new _core_bits::CrossRefCopy<From, RedNode,
+                          RedNodeRefMap, RedCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given red node map.
+    ///
+    /// This function makes a copy of the given red node map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Node type of
+    /// the destination graph with the red items, and the key type of
+    /// the original map \c map should be the Node type of the source
+    /// graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& redNodeMap(const FromMap& map, ToMap& tmap) {
+      _red_maps.push_back(new _core_bits::MapCopy<From, RedNode,
+                          RedNodeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given red node.
+    ///
+    /// This function makes a copy of the given red node.
+    BpGraphCopy& redNode(const RedNode& node, TRedNode& tnode) {
+      _red_maps.push_back(new _core_bits::ItemCopy<From, RedNode,
+                          RedNodeRefMap, TRedNode>(node, tnode));
+      return *this;
+    }
+
+    /// \brief Copy the blue node references into the given map.
+    ///
+    /// This function copies the blue node references into the given
+    /// map.  The parameter should be a map, whose key type is the
+    /// Node type of the source graph with the blue item set, while the
+    /// value type is the Node type of the destination graph.
+    template <typename BlueRef>
+    BpGraphCopy& blueRef(BlueRef& map) {
+      _blue_maps.push_back(new _core_bits::RefCopy<From, BlueNode,
+                           BlueNodeRefMap, BlueRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the blue node cross references into the given map.
+    ///
+    /// This function copies the blue node cross references (reverse
+    /// references) into the given map. The parameter should be a map,
+    /// whose key type is the Node type of the destination graph with
+    /// the blue item set, while the value type is the Node type of the
+    /// source graph.
+    template <typename BlueCrossRef>
+    BpGraphCopy& blueCrossRef(BlueCrossRef& map) {
+      _blue_maps.push_back(new _core_bits::CrossRefCopy<From, BlueNode,
+                           BlueNodeRefMap, BlueCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given blue node map.
+    ///
+    /// This function makes a copy of the given blue node map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Node type of
+    /// the destination graph with the blue items, and the key type of
+    /// the original map \c map should be the Node type of the source
+    /// graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& blueNodeMap(const FromMap& map, ToMap& tmap) {
+      _blue_maps.push_back(new _core_bits::MapCopy<From, BlueNode,
+                           BlueNodeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given blue node.
+    ///
+    /// This function makes a copy of the given blue node.
+    BpGraphCopy& blueNode(const BlueNode& node, TBlueNode& tnode) {
+      _blue_maps.push_back(new _core_bits::ItemCopy<From, BlueNode,
+                           BlueNodeRefMap, TBlueNode>(node, tnode));
+      return *this;
+    }
+
+    /// \brief Copy the arc references into the given map.
+    ///
+    /// This function copies the arc references into the given map.
+    /// The parameter should be a map, whose key type is the Arc type of
+    /// the source graph, while the value type is the Arc type of the
+    /// destination graph.
+    template <typename ArcRef>
+    BpGraphCopy& arcRef(ArcRef& map) {
+      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
+                          ArcRefMap, ArcRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the arc cross references into the given map.
+    ///
+    /// This function copies the arc cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Arc type of the destination graph, while the value type is
+    /// the Arc type of the source graph.
+    template <typename ArcCrossRef>
+    BpGraphCopy& arcCrossRef(ArcCrossRef& map) {
+      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
+                          ArcRefMap, ArcCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given arc map.
+    ///
+    /// This function makes a copy of the given arc map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Arc type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Arc type of the source graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
+      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
+                          ArcRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given arc.
+    ///
+    /// This function makes a copy of the given arc.
+    BpGraphCopy& arc(const Arc& arc, TArc& tarc) {
+      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
+                          ArcRefMap, TArc>(arc, tarc));
+      return *this;
+    }
+
+    /// \brief Copy the edge references into the given map.
+    ///
+    /// This function copies the edge references into the given map.
+    /// The parameter should be a map, whose key type is the Edge type of
+    /// the source graph, while the value type is the Edge type of the
+    /// destination graph.
+    template <typename EdgeRef>
+    BpGraphCopy& edgeRef(EdgeRef& map) {
+      _edge_maps.push_back(new _core_bits::RefCopy<From, Edge,
+                           EdgeRefMap, EdgeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copy the edge cross references into the given map.
+    ///
+    /// This function copies the edge cross references (reverse references)
+    /// into the given map. The parameter should be a map, whose key type
+    /// is the Edge type of the destination graph, while the value type is
+    /// the Edge type of the source graph.
+    template <typename EdgeCrossRef>
+    BpGraphCopy& edgeCrossRef(EdgeCrossRef& map) {
+      _edge_maps.push_back(new _core_bits::CrossRefCopy<From,
+                           Edge, EdgeRefMap, EdgeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given edge map.
+    ///
+    /// This function makes a copy of the given edge map for the newly
+    /// created graph.
+    /// The key type of the new map \c tmap should be the Edge type of the
+    /// destination graph, and the key type of the original map \c map
+    /// should be the Edge type of the source graph.
+    template <typename FromMap, typename ToMap>
+    BpGraphCopy& edgeMap(const FromMap& map, ToMap& tmap) {
+      _edge_maps.push_back(new _core_bits::MapCopy<From, Edge,
+                           EdgeRefMap, FromMap, ToMap>(map, tmap));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given edge.
+    ///
+    /// This function makes a copy of the given edge.
+    BpGraphCopy& edge(const Edge& edge, TEdge& tedge) {
+      _edge_maps.push_back(new _core_bits::ItemCopy<From, Edge,
+                           EdgeRefMap, TEdge>(edge, tedge));
+      return *this;
+    }
+
+    /// \brief Execute copying.
+    ///
+    /// This function executes the copying of the graph along with the
+    /// copying of the assigned data.
+    void run() {
+      RedNodeRefMap redNodeRefMap(_from);
+      BlueNodeRefMap blueNodeRefMap(_from);
+      NodeRefMap nodeRefMap(_from, redNodeRefMap, blueNodeRefMap);
+      EdgeRefMap edgeRefMap(_from);
+      ArcRefMap arcRefMap(_from, _to, edgeRefMap);
+      _core_bits::BpGraphCopySelector<To>::
+        copy(_from, _to, redNodeRefMap, blueNodeRefMap, edgeRefMap);
+      for (int i = 0; i < int(_node_maps.size()); ++i) {
+        _node_maps[i]->copy(_from, nodeRefMap);
+      }
+      for (int i = 0; i < int(_red_maps.size()); ++i) {
+        _red_maps[i]->copy(_from, redNodeRefMap);
+      }
+      for (int i = 0; i < int(_blue_maps.size()); ++i) {
+        _blue_maps[i]->copy(_from, blueNodeRefMap);
+      }
+      for (int i = 0; i < int(_edge_maps.size()); ++i) {
+        _edge_maps[i]->copy(_from, edgeRefMap);
+      }
+      for (int i = 0; i < int(_arc_maps.size()); ++i) {
+        _arc_maps[i]->copy(_from, arcRefMap);
+      }
+    }
+
+  private:
+
+    const From& _from;
+    To& _to;
+
+    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
+      _node_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, RedNode, RedNodeRefMap>* >
+      _red_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, BlueNode, BlueNodeRefMap>* >
+      _blue_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
+      _arc_maps;
+
+    std::vector<_core_bits::MapCopyBase<From, Edge, EdgeRefMap>* >
+      _edge_maps;
+
+  };
+
+  /// \brief Copy a graph to another graph.
+  ///
+  /// This function copies a graph to another graph.
+  /// The complete usage of it is detailed in the BpGraphCopy class,
+  /// but a short example shows a basic work:
+  ///\code
+  /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run();
+  ///\endcode
+  ///
+  /// After the copy the \c nr map will contain the mapping from the
+  /// nodes of the \c from graph to the nodes of the \c to graph and
+  /// \c ecr will contain the mapping from the edges of the \c to graph
+  /// to the edges of the \c from graph.
+  ///
+  /// \see BpGraphCopy
+  template <typename From, typename To>
+  BpGraphCopy<From, To>
+  bpGraphCopy(const From& from, To& to) {
+    return BpGraphCopy<From, To>(from, to);
   }
 
Index: lemon/cost_scaling.h
===================================================================
--- lemon/cost_scaling.h	(revision 1084)
+++ lemon/cost_scaling.h	(revision 1298)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -92,9 +92,16 @@
   /// \ref CostScaling implements a cost scaling algorithm that performs
   /// push/augment and relabel operations for finding a \ref min_cost_flow
-  /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
-  /// \ref goldberg97efficient, \ref bunnagel98efficient.
+  /// "minimum cost flow" \cite amo93networkflows,
+  /// \cite goldberg90approximation,
+  /// \cite goldberg97efficient, \cite bunnagel98efficient.
   /// It is a highly efficient primal-dual solution method, which
   /// can be viewed as the generalization of the \ref Preflow
   /// "preflow push-relabel" algorithm for the maximum flow problem.
+  /// It is a polynomial algorithm, its running time complexity is
+  /// \f$O(n^2m\log(nK))\f$, where <i>K</i> denotes the maximum arc cost.
+  ///
+  /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest
+  /// implementations available in LEMON for solving this problem.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
   ///
   /// Most of the parameters of the problem (except for the digraph)
@@ -114,8 +121,9 @@
   /// consider to use the named template parameters instead.
   ///
-  /// \warning Both number types must be signed and all input data must
+  /// \warning Both \c V and \c C must be signed number types.
+  /// \warning All input data (capacities, supply values, and costs) must
   /// be integer.
-  /// \warning This algorithm does not support negative costs for such
-  /// arcs that have infinite upper bound.
+  /// \warning This algorithm does not support negative costs for
+  /// arcs having infinite upper bound.
   ///
   /// \note %CostScaling provides three different internal methods,
@@ -146,5 +154,6 @@
     typedef typename TR::LargeCost LargeCost;
 
-    /// The \ref CostScalingDefaultTraits "traits class" of the algorithm
+    /// \brief The \ref lemon::CostScalingDefaultTraits "traits class"
+    /// of the algorithm
     typedef TR Traits;
 
@@ -179,5 +188,5 @@
     /// relabel operation.
     /// By default, the so called \ref PARTIAL_AUGMENT
-    /// "Partial Augment-Relabel" method is used, which proved to be
+    /// "Partial Augment-Relabel" method is used, which turned out to be
     /// the most efficient and the most robust on various test inputs.
     /// However, the other methods can be selected using the \ref run()
@@ -206,5 +215,6 @@
     typedef std::vector<LargeCost> LargeCostVector;
     typedef std::vector<char> BoolVector;
-    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
+    // Note: vector<char> is used instead of vector<bool>
+    // for efficiency reasons
 
   private:
@@ -234,5 +244,4 @@
     };
 
-    typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
     typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
 
@@ -248,5 +257,5 @@
 
     // Parameters of the problem
-    bool _have_lower;
+    bool _has_lower;
     Value _sum_supply;
     int _sup_node_num;
@@ -285,12 +294,4 @@
     int _max_rank;
 
-    // Data for a StaticDigraph structure
-    typedef std::pair<int, int> IntPair;
-    StaticDigraph _sgr;
-    std::vector<IntPair> _arc_vec;
-    std::vector<LargeCost> _cost_vec;
-    LargeCostArcMap _cost_map;
-    LargeCostNodeMap _pi_map;
-
   public:
 
@@ -339,5 +340,4 @@
     CostScaling(const GR& graph) :
       _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
-      _cost_map(_cost_vec), _pi_map(_pi),
       INF(std::numeric_limits<Value>::has_infinity ?
           std::numeric_limits<Value>::infinity() :
@@ -373,8 +373,7 @@
     template <typename LowerMap>
     CostScaling& lowerMap(const LowerMap& map) {
-      _have_lower = true;
+      _has_lower = true;
       for (ArcIt a(_graph); a != INVALID; ++a) {
         _lower[_arc_idf[a]] = map[a];
-        _lower[_arc_idb[a]] = map[a];
       }
       return *this;
@@ -448,5 +447,5 @@
     ///
     /// Using this function has the same effect as using \ref supplyMap()
-    /// with such a map in which \c k is assigned to \c s, \c -k is
+    /// with a map in which \c k is assigned to \c s, \c -k is
     /// assigned to \c t and all other nodes have zero supply value.
     ///
@@ -494,5 +493,5 @@
     /// \param method The internal method that will be used in the
     /// algorithm. For more information, see \ref Method.
-    /// \param factor The cost scaling factor. It must be larger than one.
+    /// \param factor The cost scaling factor. It must be at least two.
     ///
     /// \return \c INFEASIBLE if no feasible flow exists,
@@ -508,5 +507,6 @@
     /// \see ProblemType, Method
     /// \see resetParams(), reset()
-    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
+    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 16) {
+      LEMON_ASSERT(factor >= 2, "The scaling factor must be at least 2");
       _alpha = factor;
       ProblemType pt = init();
@@ -568,20 +568,27 @@
         _scost[_reverse[j]] = 0;
       }
-      _have_lower = false;
+      _has_lower = false;
       return *this;
     }
 
-    /// \brief Reset all the parameters that have been given before.
-    ///
-    /// This function resets all the paramaters that have been given
-    /// before using functions \ref lowerMap(), \ref upperMap(),
-    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
-    ///
-    /// It is useful for multiple run() calls. If this function is not
-    /// used, all the parameters given before are kept for the next
-    /// \ref run() call.
-    /// However, the underlying digraph must not be modified after this
-    /// class have been constructed, since it copies and extends the graph.
+    /// \brief Reset the internal data structures and all the parameters
+    /// that have been given before.
+    ///
+    /// This function resets the internal data structures and all the
+    /// paramaters that have been given before using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
+    ///
+    /// It is useful for multiple \ref run() calls. By default, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// See \ref resetParams() for examples.
+    ///
     /// \return <tt>(*this)</tt>
+    ///
+    /// \see resetParams(), run()
     CostScaling& reset() {
       // Resize vectors
@@ -608,7 +615,4 @@
       _excess.resize(_res_node_num);
       _next_out.resize(_res_node_num);
-
-      _arc_vec.reserve(_res_arc_num);
-      _cost_vec.reserve(_res_arc_num);
 
       // Copy the graph
@@ -668,5 +672,5 @@
     ///
     /// This function returns the total cost of the found flow.
-    /// Its complexity is O(e).
+    /// Its complexity is O(m).
     ///
     /// \note The return type of the function can be specified as a
@@ -706,5 +710,6 @@
     }
 
-    /// \brief Return the flow map (the primal solution).
+    /// \brief Copy the flow values (the primal solution) into the
+    /// given map.
     ///
     /// This function copies the flow value on each arc into the given
@@ -730,5 +735,6 @@
     }
 
-    /// \brief Return the potential map (the dual solution).
+    /// \brief Copy the potential values (the dual solution) into the
+    /// given map.
     ///
     /// This function copies the potential (dual value) of each node
@@ -760,4 +766,8 @@
       if (_sum_supply > 0) return INFEASIBLE;
 
+      // Check lower and upper bounds
+      LEMON_DEBUG(checkBoundMaps(),
+          "Upper bounds must be greater or equal to the lower bounds");
+
 
       // Initialize vectors
@@ -770,5 +780,5 @@
       const Value MAX = std::numeric_limits<Value>::max();
       int last_out;
-      if (_have_lower) {
+      if (_has_lower) {
         for (int i = 0; i != _root; ++i) {
           last_out = _first_out[i+1];
@@ -827,5 +837,5 @@
         sup[n] = _supply[_node_id[n]];
       }
-      if (_have_lower) {
+      if (_has_lower) {
         for (ArcIt a(_graph); a != INVALID; ++a) {
           int j = _arc_idf[a];
@@ -887,12 +897,4 @@
       }
 
-      return OPTIMAL;
-    }
-
-    // Execute the algorithm and transform the results
-    void start(Method method) {
-      // Maximum path length for partial augment
-      const int MAX_PATH_LENGTH = 4;
-
       // Initialize data structures for buckets
       _max_rank = _alpha * _res_node_num;
@@ -902,5 +904,20 @@
       _rank.resize(_res_node_num + 1);
 
-      // Execute the algorithm
+      return OPTIMAL;
+    }
+
+    // Check if the upper bound is greater than or equal to the lower bound
+    // on each forward arc.
+    bool checkBoundMaps() {
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_forward[j] && _upper[j] < _lower[j]) return false;
+      }
+      return true;
+    }
+
+    // Execute the algorithm and transform the results
+    void start(Method method) {
+      const int MAX_PARTIAL_PATH_LENGTH = 4;
+
       switch (method) {
         case PUSH:
@@ -911,30 +928,71 @@
           break;
         case PARTIAL_AUGMENT:
-          startAugment(MAX_PATH_LENGTH);
+          startAugment(MAX_PARTIAL_PATH_LENGTH);
           break;
       }
 
-      // Compute node potentials for the original costs
-      _arc_vec.clear();
-      _cost_vec.clear();
-      for (int j = 0; j != _res_arc_num; ++j) {
-        if (_res_cap[j] > 0) {
-          _arc_vec.push_back(IntPair(_source[j], _target[j]));
-          _cost_vec.push_back(_scost[j]);
-        }
-      }
-      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
-
-      typename BellmanFord<StaticDigraph, LargeCostArcMap>
-        ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
-      bf.distMap(_pi_map);
-      bf.init(0);
-      bf.start();
+      // Compute node potentials (dual solution)
+      for (int i = 0; i != _res_node_num; ++i) {
+        _pi[i] = static_cast<Cost>(_pi[i] / (_res_node_num * _alpha));
+      }
+      bool optimal = true;
+      for (int i = 0; optimal && i != _res_node_num; ++i) {
+        LargeCost pi_i = _pi[i];
+        int last_out = _first_out[i+1];
+        for (int j = _first_out[i]; j != last_out; ++j) {
+          if (_res_cap[j] > 0 && _scost[j] + pi_i - _pi[_target[j]] < 0) {
+            optimal = false;
+            break;
+          }
+        }
+      }
+
+      if (!optimal) {
+        // Compute node potentials for the original costs with BellmanFord
+        // (if it is necessary)
+        typedef std::pair<int, int> IntPair;
+        StaticDigraph sgr;
+        std::vector<IntPair> arc_vec;
+        std::vector<LargeCost> cost_vec;
+        LargeCostArcMap cost_map(cost_vec);
+
+        arc_vec.clear();
+        cost_vec.clear();
+        for (int j = 0; j != _res_arc_num; ++j) {
+          if (_res_cap[j] > 0) {
+            int u = _source[j], v = _target[j];
+            arc_vec.push_back(IntPair(u, v));
+            cost_vec.push_back(_scost[j] + _pi[u] - _pi[v]);
+          }
+        }
+        sgr.build(_res_node_num, arc_vec.begin(), arc_vec.end());
+
+        typename BellmanFord<StaticDigraph, LargeCostArcMap>::Create
+          bf(sgr, cost_map);
+        bf.init(0);
+        bf.start();
+
+        for (int i = 0; i != _res_node_num; ++i) {
+          _pi[i] += bf.dist(sgr.node(i));
+        }
+      }
+
+      // Shift potentials to meet the requirements of the GEQ type
+      // optimality conditions
+      LargeCost max_pot = _pi[_root];
+      for (int i = 0; i != _res_node_num; ++i) {
+        if (_pi[i] > max_pot) max_pot = _pi[i];
+      }
+      if (max_pot != 0) {
+        for (int i = 0; i != _res_node_num; ++i) {
+          _pi[i] -= max_pot;
+        }
+      }
 
       // Handle non-zero lower bounds
-      if (_have_lower) {
+      if (_has_lower) {
         int limit = _first_out[_root];
         for (int j = 0; j != limit; ++j) {
-          if (!_forward[j]) _res_cap[j] += _lower[j];
+          if (_forward[j]) _res_cap[_reverse[j]] += _lower[j];
         }
       }
@@ -948,11 +1006,13 @@
         LargeCost pi_u = _pi[u];
         for (int a = _first_out[u]; a != last_out; ++a) {
-          int v = _target[a];
-          if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
-            Value delta = _res_cap[a];
-            _excess[u] -= delta;
-            _excess[v] += delta;
-            _res_cap[a] = 0;
-            _res_cap[_reverse[a]] += delta;
+          Value delta = _res_cap[a];
+          if (delta > 0) {
+            int v = _target[a];
+            if (_cost[a] + pi_u - _pi[v] < 0) {
+              _excess[u] -= delta;
+              _excess[v] += delta;
+              _res_cap[a] = 0;
+              _res_cap[_reverse[a]] += delta;
+            }
           }
         }
@@ -970,33 +1030,232 @@
     }
 
-    // Early termination heuristic
-    bool earlyTermination() {
-      const double EARLY_TERM_FACTOR = 3.0;
-
-      // Build a static residual graph
-      _arc_vec.clear();
-      _cost_vec.clear();
-      for (int j = 0; j != _res_arc_num; ++j) {
-        if (_res_cap[j] > 0) {
-          _arc_vec.push_back(IntPair(_source[j], _target[j]));
-          _cost_vec.push_back(_cost[j] + 1);
-        }
-      }
-      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
-
-      // Run Bellman-Ford algorithm to check if the current flow is optimal
-      BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
-      bf.init(0);
-      bool done = false;
-      int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
-      for (int i = 0; i < K && !done; ++i) {
-        done = bf.processNextWeakRound();
-      }
-      return done;
+    // Price (potential) refinement heuristic
+    bool priceRefinement() {
+
+      // Stack for stroing the topological order
+      IntVector stack(_res_node_num);
+      int stack_top;
+
+      // Perform phases
+      while (topologicalSort(stack, stack_top)) {
+
+        // Compute node ranks in the acyclic admissible network and
+        // store the nodes in buckets
+        for (int i = 0; i != _res_node_num; ++i) {
+          _rank[i] = 0;
+        }
+        const int bucket_end = _root + 1;
+        for (int r = 0; r != _max_rank; ++r) {
+          _buckets[r] = bucket_end;
+        }
+        int top_rank = 0;
+        for ( ; stack_top >= 0; --stack_top) {
+          int u = stack[stack_top], v;
+          int rank_u = _rank[u];
+
+          LargeCost rc, pi_u = _pi[u];
+          int last_out = _first_out[u+1];
+          for (int a = _first_out[u]; a != last_out; ++a) {
+            if (_res_cap[a] > 0) {
+              v = _target[a];
+              rc = _cost[a] + pi_u - _pi[v];
+              if (rc < 0) {
+                LargeCost nrc = static_cast<LargeCost>((-rc - 0.5) / _epsilon);
+                if (nrc < LargeCost(_max_rank)) {
+                  int new_rank_v = rank_u + static_cast<int>(nrc);
+                  if (new_rank_v > _rank[v]) {
+                    _rank[v] = new_rank_v;
+                  }
+                }
+              }
+            }
+          }
+
+          if (rank_u > 0) {
+            top_rank = std::max(top_rank, rank_u);
+            int bfirst = _buckets[rank_u];
+            _bucket_next[u] = bfirst;
+            _bucket_prev[bfirst] = u;
+            _buckets[rank_u] = u;
+          }
+        }
+
+        // Check if the current flow is epsilon-optimal
+        if (top_rank == 0) {
+          return true;
+        }
+
+        // Process buckets in top-down order
+        for (int rank = top_rank; rank > 0; --rank) {
+          while (_buckets[rank] != bucket_end) {
+            // Remove the first node from the current bucket
+            int u = _buckets[rank];
+            _buckets[rank] = _bucket_next[u];
+
+            // Search the outgoing arcs of u
+            LargeCost rc, pi_u = _pi[u];
+            int last_out = _first_out[u+1];
+            int v, old_rank_v, new_rank_v;
+            for (int a = _first_out[u]; a != last_out; ++a) {
+              if (_res_cap[a] > 0) {
+                v = _target[a];
+                old_rank_v = _rank[v];
+
+                if (old_rank_v < rank) {
+
+                  // Compute the new rank of node v
+                  rc = _cost[a] + pi_u - _pi[v];
+                  if (rc < 0) {
+                    new_rank_v = rank;
+                  } else {
+                    LargeCost nrc = rc / _epsilon;
+                    new_rank_v = 0;
+                    if (nrc < LargeCost(_max_rank)) {
+                      new_rank_v = rank - 1 - static_cast<int>(nrc);
+                    }
+                  }
+
+                  // Change the rank of node v
+                  if (new_rank_v > old_rank_v) {
+                    _rank[v] = new_rank_v;
+
+                    // Remove v from its old bucket
+                    if (old_rank_v > 0) {
+                      if (_buckets[old_rank_v] == v) {
+                        _buckets[old_rank_v] = _bucket_next[v];
+                      } else {
+                        int pv = _bucket_prev[v], nv = _bucket_next[v];
+                        _bucket_next[pv] = nv;
+                        _bucket_prev[nv] = pv;
+                      }
+                    }
+
+                    // Insert v into its new bucket
+                    int nv = _buckets[new_rank_v];
+                    _bucket_next[v] = nv;
+                    _bucket_prev[nv] = v;
+                    _buckets[new_rank_v] = v;
+                  }
+                }
+              }
+            }
+
+            // Refine potential of node u
+            _pi[u] -= rank * _epsilon;
+          }
+        }
+
+      }
+
+      return false;
+    }
+
+    // Find and cancel cycles in the admissible network and
+    // determine topological order using DFS
+    bool topologicalSort(IntVector &stack, int &stack_top) {
+      const int MAX_CYCLE_CANCEL = 1;
+
+      BoolVector reached(_res_node_num, false);
+      BoolVector processed(_res_node_num, false);
+      IntVector pred(_res_node_num);
+      for (int i = 0; i != _res_node_num; ++i) {
+        _next_out[i] = _first_out[i];
+      }
+      stack_top = -1;
+
+      int cycle_cnt = 0;
+      for (int start = 0; start != _res_node_num; ++start) {
+        if (reached[start]) continue;
+
+        // Start DFS search from this start node
+        pred[start] = -1;
+        int tip = start, v;
+        while (true) {
+          // Check the outgoing arcs of the current tip node
+          reached[tip] = true;
+          LargeCost pi_tip = _pi[tip];
+          int a, last_out = _first_out[tip+1];
+          for (a = _next_out[tip]; a != last_out; ++a) {
+            if (_res_cap[a] > 0) {
+              v = _target[a];
+              if (_cost[a] + pi_tip - _pi[v] < 0) {
+                if (!reached[v]) {
+                  // A new node is reached
+                  reached[v] = true;
+                  pred[v] = tip;
+                  _next_out[tip] = a;
+                  tip = v;
+                  a = _next_out[tip];
+                  last_out = _first_out[tip+1];
+                  break;
+                }
+                else if (!processed[v]) {
+                  // A cycle is found
+                  ++cycle_cnt;
+                  _next_out[tip] = a;
+
+                  // Find the minimum residual capacity along the cycle
+                  Value d, delta = _res_cap[a];
+                  int u, delta_node = tip;
+                  for (u = tip; u != v; ) {
+                    u = pred[u];
+                    d = _res_cap[_next_out[u]];
+                    if (d <= delta) {
+                      delta = d;
+                      delta_node = u;
+                    }
+                  }
+
+                  // Augment along the cycle
+                  _res_cap[a] -= delta;
+                  _res_cap[_reverse[a]] += delta;
+                  for (u = tip; u != v; ) {
+                    u = pred[u];
+                    int ca = _next_out[u];
+                    _res_cap[ca] -= delta;
+                    _res_cap[_reverse[ca]] += delta;
+                  }
+
+                  // Check the maximum number of cycle canceling
+                  if (cycle_cnt >= MAX_CYCLE_CANCEL) {
+                    return false;
+                  }
+
+                  // Roll back search to delta_node
+                  if (delta_node != tip) {
+                    for (u = tip; u != delta_node; u = pred[u]) {
+                      reached[u] = false;
+                    }
+                    tip = delta_node;
+                    a = _next_out[tip] + 1;
+                    last_out = _first_out[tip+1];
+                    break;
+                  }
+                }
+              }
+            }
+          }
+
+          // Step back to the previous node
+          if (a == last_out) {
+            processed[tip] = true;
+            stack[++stack_top] = tip;
+            tip = pred[tip];
+            if (tip < 0) {
+              // Finish DFS from the current start node
+              break;
+            }
+            ++_next_out[tip];
+          }
+        }
+
+      }
+
+      return (cycle_cnt == 0);
     }
 
     // Global potential update heuristic
     void globalUpdate() {
-      int bucket_end = _root + 1;
+      const int bucket_end = _root + 1;
 
       // Initialize buckets
@@ -1005,10 +1264,11 @@
       }
       Value total_excess = 0;
+      int b0 = bucket_end;
       for (int i = 0; i != _res_node_num; ++i) {
         if (_excess[i] < 0) {
           _rank[i] = 0;
-          _bucket_next[i] = _buckets[0];
-          _bucket_prev[_buckets[0]] = i;
-          _buckets[0] = i;
+          _bucket_next[i] = b0;
+          _bucket_prev[b0] = i;
+          b0 = i;
         } else {
           total_excess += _excess[i];
@@ -1017,4 +1277,5 @@
       }
       if (total_excess == 0) return;
+      _buckets[0] = b0;
 
       // Search the buckets
@@ -1026,5 +1287,5 @@
           _buckets[r] = _bucket_next[u];
 
-          // Search the incomming arcs of u
+          // Search the incoming arcs of u
           LargeCost pi_u = _pi[u];
           int last_out = _first_out[u+1];
@@ -1038,6 +1299,7 @@
                 LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
                 int new_rank_v = old_rank_v;
-                if (nrc < LargeCost(_max_rank))
-                  new_rank_v = r + 1 + int(nrc);
+                if (nrc < LargeCost(_max_rank)) {
+                  new_rank_v = r + 1 + static_cast<int>(nrc);
+                }
 
                 // Change the rank of v
@@ -1051,12 +1313,14 @@
                       _buckets[old_rank_v] = _bucket_next[v];
                     } else {
-                      _bucket_next[_bucket_prev[v]] = _bucket_next[v];
-                      _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
+                      int pv = _bucket_prev[v], nv = _bucket_next[v];
+                      _bucket_next[pv] = nv;
+                      _bucket_prev[nv] = pv;
                     }
                   }
 
-                  // Insert v to its new bucket
-                  _bucket_next[v] = _buckets[new_rank_v];
-                  _bucket_prev[_buckets[new_rank_v]] = v;
+                  // Insert v into its new bucket
+                  int nv = _buckets[new_rank_v];
+                  _bucket_next[v] = nv;
+                  _bucket_prev[nv] = v;
                   _buckets[new_rank_v] = v;
                 }
@@ -1087,21 +1351,23 @@
     void startAugment(int max_length) {
       // Paramters for heuristics
-      const int EARLY_TERM_EPSILON_LIMIT = 1000;
-      const double GLOBAL_UPDATE_FACTOR = 3.0;
-
-      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
+      const int PRICE_REFINEMENT_LIMIT = 2;
+      const double GLOBAL_UPDATE_FACTOR = 1.0;
+      const int global_update_skip = static_cast<int>(GLOBAL_UPDATE_FACTOR *
         (_res_node_num + _sup_node_num * _sup_node_num));
-      int next_update_limit = global_update_freq;
-
+      int next_global_update_limit = global_update_skip;
+
+      // Perform cost scaling phases
+      IntVector path;
+      BoolVector path_arc(_res_arc_num, false);
       int relabel_cnt = 0;
-
-      // Perform cost scaling phases
-      std::vector<int> path;
+      int eps_phase_cnt = 0;
       for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
                                         1 : _epsilon / _alpha )
       {
-        // Early termination heuristic
-        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
-          if (earlyTermination()) break;
+        ++eps_phase_cnt;
+
+        // Price refinement heuristic
+        if (eps_phase_cnt >= PRICE_REFINEMENT_LIMIT) {
+          if (priceRefinement()) continue;
         }
 
@@ -1120,30 +1386,43 @@
 
           // Find an augmenting path from the start node
-          path.clear();
           int tip = start;
-          while (_excess[tip] >= 0 && int(path.size()) < max_length) {
+          while (int(path.size()) < max_length && _excess[tip] >= 0) {
             int u;
-            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
+            LargeCost rc, min_red_cost = std::numeric_limits<LargeCost>::max();
+            LargeCost pi_tip = _pi[tip];
             int last_out = _first_out[tip+1];
             for (int a = _next_out[tip]; a != last_out; ++a) {
-              u = _target[a];
-              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
-                path.push_back(a);
-                _next_out[tip] = a;
-                tip = u;
-                goto next_step;
+              if (_res_cap[a] > 0) {
+                u = _target[a];
+                rc = _cost[a] + pi_tip - _pi[u];
+                if (rc < 0) {
+                  path.push_back(a);
+                  _next_out[tip] = a;
+                  if (path_arc[a]) {
+                    goto augment;   // a cycle is found, stop path search
+                  }
+                  tip = u;
+                  path_arc[a] = true;
+                  goto next_step;
+                }
+                else if (rc < min_red_cost) {
+                  min_red_cost = rc;
+                }
               }
             }
 
             // Relabel tip node
-            min_red_cost = std::numeric_limits<LargeCost>::max();
             if (tip != start) {
               int ra = _reverse[path.back()];
-              min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
+              min_red_cost =
+                std::min(min_red_cost, _cost[ra] + pi_tip - _pi[_target[ra]]);
             }
+            last_out = _next_out[tip];
             for (int a = _first_out[tip]; a != last_out; ++a) {
-              rc = _cost[a] + pi_tip - _pi[_target[a]];
-              if (_res_cap[a] > 0 && rc < min_red_cost) {
-                min_red_cost = rc;
+              if (_res_cap[a] > 0) {
+                rc = _cost[a] + pi_tip - _pi[_target[a]];
+                if (rc < min_red_cost) {
+                  min_red_cost = rc;
+                }
               }
             }
@@ -1154,5 +1433,7 @@
             // Step back
             if (tip != start) {
-              tip = _source[path.back()];
+              int pa = path.back();
+              path_arc[pa] = false;
+              tip = _source[pa];
               path.pop_back();
             }
@@ -1162,4 +1443,5 @@
 
           // Augment along the found path (as much flow as possible)
+        augment:
           Value delta;
           int pa, u, v = start;
@@ -1168,4 +1450,5 @@
             u = v;
             v = _target[pa];
+            path_arc[pa] = false;
             delta = std::min(_res_cap[pa], _excess[u]);
             _res_cap[pa] -= delta;
@@ -1173,15 +1456,19 @@
             _excess[u] -= delta;
             _excess[v] += delta;
-            if (_excess[v] > 0 && _excess[v] <= delta)
+            if (_excess[v] > 0 && _excess[v] <= delta) {
               _active_nodes.push_back(v);
-          }
+            }
+          }
+          path.clear();
 
           // Global update heuristic
-          if (relabel_cnt >= next_update_limit) {
+          if (relabel_cnt >= next_global_update_limit) {
             globalUpdate();
-            next_update_limit += global_update_freq;
-          }
-        }
-      }
+            next_global_update_limit += global_update_skip;
+          }
+        }
+
+      }
+
     }
 
@@ -1189,22 +1476,24 @@
     void startPush() {
       // Paramters for heuristics
-      const int EARLY_TERM_EPSILON_LIMIT = 1000;
+      const int PRICE_REFINEMENT_LIMIT = 2;
       const double GLOBAL_UPDATE_FACTOR = 2.0;
 
-      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
+      const int global_update_skip = static_cast<int>(GLOBAL_UPDATE_FACTOR *
         (_res_node_num + _sup_node_num * _sup_node_num));
-      int next_update_limit = global_update_freq;
-
-      int relabel_cnt = 0;
+      int next_global_update_limit = global_update_skip;
 
       // Perform cost scaling phases
       BoolVector hyper(_res_node_num, false);
       LargeCostVector hyper_cost(_res_node_num);
+      int relabel_cnt = 0;
+      int eps_phase_cnt = 0;
       for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
                                         1 : _epsilon / _alpha )
       {
-        // Early termination heuristic
-        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
-          if (earlyTermination()) break;
+        ++eps_phase_cnt;
+
+        // Price refinement heuristic
+        if (eps_phase_cnt >= PRICE_REFINEMENT_LIMIT) {
+          if (priceRefinement()) continue;
         }
 
@@ -1278,7 +1567,9 @@
                std::numeric_limits<LargeCost>::max();
             for (int a = _first_out[n]; a != last_out; ++a) {
-              rc = _cost[a] + pi_n - _pi[_target[a]];
-              if (_res_cap[a] > 0 && rc < min_red_cost) {
-                min_red_cost = rc;
+              if (_res_cap[a] > 0) {
+                rc = _cost[a] + pi_n - _pi[_target[a]];
+                if (rc < min_red_cost) {
+                  min_red_cost = rc;
+                }
               }
             }
@@ -1298,9 +1589,9 @@
 
           // Global update heuristic
-          if (relabel_cnt >= next_update_limit) {
+          if (relabel_cnt >= next_global_update_limit) {
             globalUpdate();
             for (int u = 0; u != _res_node_num; ++u)
               hyper[u] = false;
-            next_update_limit += global_update_freq;
+            next_global_update_limit += global_update_skip;
           }
         }
Index: lemon/cplex.cc
===================================================================
--- lemon/cplex.cc	(revision 1183)
+++ lemon/cplex.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -492,4 +492,15 @@
                    _message_enabled ? CPX_ON : CPX_OFF);
   }
+
+  void CplexBase::_write(std::string file, std::string format) const
+  {
+    if(format == "MPS" || format == "LP")
+      CPXwriteprob(cplexEnv(), cplexLp(), file.c_str(), format.c_str());
+    else if(format == "SOL")
+      CPXsolwrite(cplexEnv(), cplexLp(), file.c_str());
+    else throw UnsupportedFormatError(format);
+  }
+
+
 
   // CplexLp members
Index: lemon/cplex.h
===================================================================
--- lemon/cplex.h	(revision 793)
+++ lemon/cplex.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -151,4 +151,6 @@
     bool _message_enabled;
 
+    void _write(std::string file, std::string format) const;
+
   public:
 
@@ -171,4 +173,17 @@
     const cpxlp* cplexLp() const { return _prob; }
 
+#ifdef DOXYGEN
+    /// Write the problem or the solution to a file in the given format
+
+    /// This function writes the problem or the solution
+    /// to a file in the given format.
+    /// Trying to write in an unsupported format will trigger
+    /// \ref lemon::LpBase::UnsupportedFormatError "UnsupportedFormatError".
+    /// \param file The file path
+    /// \param format The output file format.
+    /// Supportted formats are "MPS", "LP" and "SOL".
+    void write(std::string file, std::string format = "MPS") const {}
+#endif
+
   };
 
Index: lemon/cycle_canceling.h
===================================================================
--- lemon/cycle_canceling.h	(revision 956)
+++ lemon/cycle_canceling.h	(revision 1298)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -36,4 +36,5 @@
 #include <lemon/bellman_ford.h>
 #include <lemon/howard_mmc.h>
+#include <lemon/hartmann_orlin_mmc.h>
 
 namespace lemon {
@@ -47,11 +48,12 @@
   /// \ref CycleCanceling implements three different cycle-canceling
   /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
-  /// \ref amo93networkflows, \ref klein67primal,
-  /// \ref goldberg89cyclecanceling.
-  /// The most efficent one (both theoretically and practically)
-  /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm,
-  /// thus it is the default method.
-  /// It is strongly polynomial, but in practice, it is typically much
-  /// slower than the scaling algorithms and NetworkSimplex.
+  /// \cite amo93networkflows, \cite klein67primal,
+  /// \cite goldberg89cyclecanceling.
+  /// The most efficent one is the \ref CANCEL_AND_TIGHTEN
+  /// "Cancel-and-Tighten" algorithm, thus it is the default method.
+  /// It runs in strongly polynomial time \f$O(n^2 m^2 \log n)\f$,
+  /// but in practice, it is typically orders of magnitude slower than
+  /// the scaling algorithms and \ref NetworkSimplex.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
   ///
   /// Most of the parameters of the problem (except for the digraph)
@@ -66,8 +68,9 @@
   /// algorithm. By default, it is the same as \c V.
   ///
-  /// \warning Both number types must be signed and all input data must
+  /// \warning Both \c V and \c C must be signed number types.
+  /// \warning All input data (capacities, supply values, and costs) must
   /// be integer.
-  /// \warning This algorithm does not support negative costs for such
-  /// arcs that have infinite upper bound.
+  /// \warning This algorithm does not support negative costs for
+  /// arcs having infinite upper bound.
   ///
   /// \note For more information about the three available methods,
@@ -116,25 +119,26 @@
     ///
     /// \ref CycleCanceling provides three different cycle-canceling
-    /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel and Tighten"
-    /// is used, which proved to be the most efficient and the most robust
-    /// on various test inputs.
+    /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel-and-Tighten"
+    /// is used, which is by far the most efficient and the most robust.
     /// However, the other methods can be selected using the \ref run()
     /// function with the proper parameter.
     enum Method {
       /// A simple cycle-canceling method, which uses the
-      /// \ref BellmanFord "Bellman-Ford" algorithm with limited iteration
-      /// number for detecting negative cycles in the residual network.
+      /// \ref BellmanFord "Bellman-Ford" algorithm for detecting negative
+      /// cycles in the residual network.
+      /// The number of Bellman-Ford iterations is bounded by a successively
+      /// increased limit.
       SIMPLE_CYCLE_CANCELING,
       /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
       /// well-known strongly polynomial method
-      /// \ref goldberg89cyclecanceling. It improves along a
+      /// \cite goldberg89cyclecanceling. It improves along a
       /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
-      /// Its running time complexity is O(n<sup>2</sup>m<sup>3</sup>log(n)).
+      /// Its running time complexity is \f$O(n^2 m^3 \log n)\f$.
       MINIMUM_MEAN_CYCLE_CANCELING,
-      /// The "Cancel And Tighten" algorithm, which can be viewed as an
+      /// The "Cancel-and-Tighten" algorithm, which can be viewed as an
       /// improved version of the previous method
-      /// \ref goldberg89cyclecanceling.
+      /// \cite goldberg89cyclecanceling.
       /// It is faster both in theory and in practice, its running time
-      /// complexity is O(n<sup>2</sup>m<sup>2</sup>log(n)).
+      /// complexity is \f$O(n^2 m^2 \log n)\f$.
       CANCEL_AND_TIGHTEN
     };
@@ -192,5 +196,5 @@
 
     // Parameters of the problem
-    bool _have_lower;
+    bool _has_lower;
     Value _sum_supply;
 
@@ -275,8 +279,7 @@
     template <typename LowerMap>
     CycleCanceling& lowerMap(const LowerMap& map) {
-      _have_lower = true;
+      _has_lower = true;
       for (ArcIt a(_graph); a != INVALID; ++a) {
         _lower[_arc_idf[a]] = map[a];
-        _lower[_arc_idb[a]] = map[a];
       }
       return *this;
@@ -350,5 +353,5 @@
     ///
     /// Using this function has the same effect as using \ref supplyMap()
-    /// with such a map in which \c k is assigned to \c s, \c -k is
+    /// with a map in which \c k is assigned to \c s, \c -k is
     /// assigned to \c t and all other nodes have zero supply value.
     ///
@@ -468,5 +471,5 @@
         _cost[_reverse[j]] = 0;
       }
-      _have_lower = false;
+      _has_lower = false;
       return *this;
     }
@@ -573,5 +576,5 @@
     ///
     /// This function returns the total cost of the found flow.
-    /// Its complexity is O(e).
+    /// Its complexity is O(m).
     ///
     /// \note The return type of the function can be specified as a
@@ -611,5 +614,6 @@
     }
 
-    /// \brief Return the flow map (the primal solution).
+    /// \brief Copy the flow values (the primal solution) into the
+    /// given map.
     ///
     /// This function copies the flow value on each arc into the given
@@ -635,5 +639,6 @@
     }
 
-    /// \brief Return the potential map (the dual solution).
+    /// \brief Copy the potential values (the dual solution) into the
+    /// given map.
     ///
     /// This function copies the potential (dual value) of each node
@@ -665,4 +670,8 @@
       if (_sum_supply > 0) return INFEASIBLE;
 
+      // Check lower and upper bounds
+      LEMON_DEBUG(checkBoundMaps(),
+          "Upper bounds must be greater or equal to the lower bounds");
+
 
       // Initialize vectors
@@ -675,5 +684,5 @@
       const Value MAX = std::numeric_limits<Value>::max();
       int last_out;
-      if (_have_lower) {
+      if (_has_lower) {
         for (int i = 0; i != _root; ++i) {
           last_out = _first_out[i+1];
@@ -718,5 +727,5 @@
         sup[n] = _supply[_node_id[n]];
       }
-      if (_have_lower) {
+      if (_has_lower) {
         for (ArcIt a(_graph); a != INVALID; ++a) {
           int j = _arc_idf[a];
@@ -773,4 +782,13 @@
 
       return OPTIMAL;
+    }
+
+    // Check if the upper bound is greater than or equal to the lower bound
+    // on each forward arc.
+    bool checkBoundMaps() {
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_forward[j] && _upper[j] < _lower[j]) return false;
+      }
+      return true;
     }
 
@@ -817,8 +835,8 @@
 
       // Handle non-zero lower bounds
-      if (_have_lower) {
+      if (_has_lower) {
         int limit = _first_out[_root];
         for (int j = 0; j != limit; ++j) {
-          if (!_forward[j]) _res_cap[j] += _lower[j];
+          if (_forward[j]) _res_cap[_reverse[j]] += _lower[j];
         }
       }
@@ -923,16 +941,39 @@
     // Execute the "Minimum Mean Cycle Canceling" method
     void startMinMeanCycleCanceling() {
-      typedef SimplePath<StaticDigraph> SPath;
+      typedef Path<StaticDigraph> SPath;
       typedef typename SPath::ArcIt SPathArcIt;
       typedef typename HowardMmc<StaticDigraph, CostArcMap>
-        ::template SetPath<SPath>::Create MMC;
+        ::template SetPath<SPath>::Create HwMmc;
+      typedef typename HartmannOrlinMmc<StaticDigraph, CostArcMap>
+        ::template SetPath<SPath>::Create HoMmc;
+
+      const double HW_ITER_LIMIT_FACTOR = 1.0;
+      const int HW_ITER_LIMIT_MIN_VALUE = 5;
+
+      const int hw_iter_limit =
+          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
+                   HW_ITER_LIMIT_MIN_VALUE);
 
       SPath cycle;
-      MMC mmc(_sgr, _cost_map);
-      mmc.cycle(cycle);
+      HwMmc hw_mmc(_sgr, _cost_map);
+      hw_mmc.cycle(cycle);
       buildResidualNetwork();
-      while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
-        // Find the cycle
-        mmc.findCycle();
+      while (true) {
+
+        typename HwMmc::TerminationCause hw_tc =
+            hw_mmc.findCycleMean(hw_iter_limit);
+        if (hw_tc == HwMmc::ITERATION_LIMIT) {
+          // Howard's algorithm reached the iteration limit, start a
+          // strongly polynomial algorithm instead
+          HoMmc ho_mmc(_sgr, _cost_map);
+          ho_mmc.cycle(cycle);
+          // Find a minimum mean cycle (Hartmann-Orlin algorithm)
+          if (!(ho_mmc.findCycleMean() && ho_mmc.cycleCost() < 0)) break;
+          ho_mmc.findCycle();
+        } else {
+          // Find a minimum mean cycle (Howard algorithm)
+          if (!(hw_tc == HwMmc::OPTIMAL && hw_mmc.cycleCost() < 0)) break;
+          hw_mmc.findCycle();
+        }
 
         // Compute delta value
@@ -955,9 +996,15 @@
     }
 
-    // Execute the "Cancel And Tighten" method
+    // Execute the "Cancel-and-Tighten" method
     void startCancelAndTighten() {
       // Constants for the min mean cycle computations
       const double LIMIT_FACTOR = 1.0;
       const int MIN_LIMIT = 5;
+      const double HW_ITER_LIMIT_FACTOR = 1.0;
+      const int HW_ITER_LIMIT_MIN_VALUE = 5;
+
+      const int hw_iter_limit =
+          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
+                   HW_ITER_LIMIT_MIN_VALUE);
 
       // Contruct auxiliary data vectors
@@ -1133,15 +1180,28 @@
           }
         } else {
-          typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
+          typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc;
+          typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc;
           typedef typename BellmanFord<StaticDigraph, CostArcMap>
             ::template SetDistMap<CostNodeMap>::Create BF;
 
           // Set epsilon to the minimum cycle mean
+          Cost cycle_cost = 0;
+          int cycle_size = 1;
           buildResidualNetwork();
-          MMC mmc(_sgr, _cost_map);
-          mmc.findCycleMean();
-          epsilon = -mmc.cycleMean();
-          Cost cycle_cost = mmc.cycleCost();
-          int cycle_size = mmc.cycleSize();
+          HwMmc hw_mmc(_sgr, _cost_map);
+          if (hw_mmc.findCycleMean(hw_iter_limit) == HwMmc::ITERATION_LIMIT) {
+            // Howard's algorithm reached the iteration limit, start a
+            // strongly polynomial algorithm instead
+            HoMmc ho_mmc(_sgr, _cost_map);
+            ho_mmc.findCycleMean();
+            epsilon = -ho_mmc.cycleMean();
+            cycle_cost = ho_mmc.cycleCost();
+            cycle_size = ho_mmc.cycleSize();
+          } else {
+            // Set epsilon
+            epsilon = -hw_mmc.cycleMean();
+            cycle_cost = hw_mmc.cycleCost();
+            cycle_size = hw_mmc.cycleSize();
+          }
 
           // Compute feasible potentials for the current epsilon
Index: lemon/dfs.h
===================================================================
--- lemon/dfs.h	(revision 1161)
+++ lemon/dfs.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -153,5 +153,5 @@
     typedef PredMapPath<Digraph, PredMap> Path;
 
-    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
+    ///The \ref lemon::DfsDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
 
Index: lemon/dijkstra.h
===================================================================
--- lemon/dijkstra.h	(revision 956)
+++ lemon/dijkstra.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -228,9 +228,9 @@
     ///The heap type used by the algorithm.
     typedef typename TR::Heap Heap;
-    ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
-    ///of the algorithm.
+    /// \brief The \ref lemon::DijkstraDefaultOperationTraits
+    /// "operation traits class" of the algorithm.
     typedef typename TR::OperationTraits OperationTraits;
 
-    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
+    ///The \ref lemon::DijkstraDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
 
Index: lemon/dim2.h
===================================================================
--- lemon/dim2.h	(revision 761)
+++ lemon/dim2.h	(revision 1311)
@@ -21,4 +21,5 @@
 
 #include <iostream>
+#include <algorithm>
 
 ///\ingroup geomdat
Index: lemon/dimacs.h
===================================================================
--- lemon/dimacs.h	(revision 956)
+++ lemon/dimacs.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/edge_set.h
===================================================================
--- lemon/edge_set.h	(revision 956)
+++ lemon/edge_set.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/edmonds_karp.h
===================================================================
--- lemon/edmonds_karp.h	(revision 1270)
+++ lemon/edmonds_karp.h	(revision 1270)
@@ -0,0 +1,556 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_EDMONDS_KARP_H
+#define LEMON_EDMONDS_KARP_H
+
+/// \file
+/// \ingroup max_flow
+/// \brief Implementation of the Edmonds-Karp algorithm.
+
+#include <lemon/tolerance.h>
+#include <vector>
+
+namespace lemon {
+
+  /// \brief Default traits class of EdmondsKarp class.
+  ///
+  /// Default traits class of EdmondsKarp class.
+  /// \param GR Digraph type.
+  /// \param CAP Type of capacity map.
+  template <typename GR, typename CAP>
+  struct EdmondsKarpDefaultTraits {
+
+    /// \brief The digraph type the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc capacities.
+    ///
+    /// The type of the map that stores the arc capacities.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef CAP CapacityMap;
+
+    /// \brief The type of the flow values.
+    typedef typename CapacityMap::Value Value;
+
+    /// \brief The type of the map that stores the flow values.
+    ///
+    /// The type of the map that stores the flow values.
+    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+#ifdef DOXYGEN
+    typedef GR::ArcMap<Value> FlowMap;
+#else
+    typedef typename Digraph::template ArcMap<Value> FlowMap;
+#endif
+
+    /// \brief Instantiates a FlowMap.
+    ///
+    /// This function instantiates a \ref FlowMap.
+    /// \param digraph The digraph for which we would like to define
+    /// the flow map.
+    static FlowMap* createFlowMap(const Digraph& digraph) {
+      return new FlowMap(digraph);
+    }
+
+    /// \brief The tolerance used by the algorithm
+    ///
+    /// The tolerance used by the algorithm to handle inexact computation.
+    typedef lemon::Tolerance<Value> Tolerance;
+
+  };
+
+  /// \ingroup max_flow
+  ///
+  /// \brief Edmonds-Karp algorithms class.
+  ///
+  /// This class provides an implementation of the \e Edmonds-Karp \e
+  /// algorithm producing a \ref max_flow "flow of maximum value" in a
+  /// digraph \cite clrs01algorithms, \cite amo93networkflows,
+  /// \cite edmondskarp72theoretical.
+  /// The Edmonds-Karp algorithm is slower than the Preflow
+  /// algorithm, but it has an advantage of the step-by-step execution
+  /// control with feasible flow solutions. The \e source node, the \e
+  /// target node, the \e capacity of the arcs and the \e starting \e
+  /// flow value of the arcs should be passed to the algorithm
+  /// through the constructor.
+  ///
+  /// The time complexity of the algorithm is \f$ O(nm^2) \f$ in
+  /// worst case. Always try the Preflow algorithm instead of this if
+  /// you just want to compute the optimal flow.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CAP The type of the capacity map. The default map
+  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref EdmondsKarpDefaultTraits
+  /// "EdmondsKarpDefaultTraits<GR, CAP>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+
+#ifdef DOXYGEN
+  template <typename GR, typename CAP, typename TR>
+#else
+  template <typename GR,
+            typename CAP = typename GR::template ArcMap<int>,
+            typename TR = EdmondsKarpDefaultTraits<GR, CAP> >
+#endif
+  class EdmondsKarp {
+  public:
+
+    /// \brief The \ref lemon::EdmondsKarpDefaultTraits "traits class"
+    /// of the algorithm.
+    typedef TR Traits;
+    /// The type of the digraph the algorithm runs on.
+    typedef typename Traits::Digraph Digraph;
+    /// The type of the capacity map.
+    typedef typename Traits::CapacityMap CapacityMap;
+    /// The type of the flow values.
+    typedef typename Traits::Value Value;
+
+    /// The type of the flow map.
+    typedef typename Traits::FlowMap FlowMap;
+    /// The type of the tolerance.
+    typedef typename Traits::Tolerance Tolerance;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+    typedef typename Digraph::template NodeMap<Arc> PredMap;
+
+    const Digraph& _graph;
+    const CapacityMap* _capacity;
+
+    Node _source, _target;
+
+    FlowMap* _flow;
+    bool _local_flow;
+
+    PredMap* _pred;
+    std::vector<Node> _queue;
+
+    Tolerance _tolerance;
+    Value _flow_value;
+
+    void createStructures() {
+      if (!_flow) {
+        _flow = Traits::createFlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_pred) {
+        _pred = new PredMap(_graph);
+      }
+      _queue.resize(countNodes(_graph));
+    }
+
+    void destroyStructures() {
+      if (_local_flow) {
+        delete _flow;
+      }
+      if (_pred) {
+        delete _pred;
+      }
+    }
+
+  public:
+
+    typedef EdmondsKarp Create;
+
+    ///\name Named template parameters
+
+    ///@{
+
+    template <typename T>
+    struct SetFlowMapTraits : public Traits {
+      typedef T FlowMap;
+      static FlowMap *createFlowMap(const Digraph&) {
+        LEMON_ASSERT(false, "FlowMap is not initialized");
+        return 0;
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// FlowMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting FlowMap
+    /// type
+    template <typename T>
+    struct SetFlowMap
+      : public EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > {
+      typedef EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    EdmondsKarp() {}
+
+  public:
+
+    /// \brief The constructor of the class.
+    ///
+    /// The constructor of the class.
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param capacity The capacity of the arcs.
+    /// \param source The source node.
+    /// \param target The target node.
+    EdmondsKarp(const Digraph& digraph, const CapacityMap& capacity,
+                Node source, Node target)
+      : _graph(digraph), _capacity(&capacity), _source(source), _target(target),
+        _flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value()
+    {
+      LEMON_ASSERT(_source != _target,
+                   "Flow source and target are the same nodes.");
+    }
+
+    /// \brief Destructor.
+    ///
+    /// Destructor.
+    ~EdmondsKarp() {
+      destroyStructures();
+    }
+
+    /// \brief Sets the capacity map.
+    ///
+    /// Sets the capacity map.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& capacityMap(const CapacityMap& map) {
+      _capacity = &map;
+      return *this;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& flowMap(FlowMap& map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = &map;
+      return *this;
+    }
+
+    /// \brief Sets the source node.
+    ///
+    /// Sets the source node.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& source(const Node& node) {
+      _source = node;
+      return *this;
+    }
+
+    /// \brief Sets the target node.
+    ///
+    /// Sets the target node.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& target(const Node& node) {
+      _target = node;
+      return *this;
+    }
+
+    /// \brief Sets the tolerance used by algorithm.
+    ///
+    /// Sets the tolerance used by algorithm.
+    /// \return <tt>(*this)</tt>
+    EdmondsKarp& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// Returns a const reference to the tolerance object used by
+    /// the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use \ref run().\n
+    /// If you need better control on the initial solution or the execution,
+    /// you have to call one of the \ref init() functions first, then
+    /// \ref start() or multiple times the \ref augment() function.
+
+    ///@{
+
+    /// \brief Initializes the algorithm.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to zero on each arc.
+    void init() {
+      createStructures();
+      for (ArcIt it(_graph); it != INVALID; ++it) {
+        _flow->set(it, 0);
+      }
+      _flow_value = 0;
+    }
+
+    /// \brief Initializes the algorithm using the given flow map.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to the given \c flowMap. The \c flowMap should
+    /// contain a feasible flow, i.e. at each node excluding the source
+    /// and the target, the incoming flow should be equal to the
+    /// outgoing flow.
+    template <typename FlowMap>
+    void init(const FlowMap& flowMap) {
+      createStructures();
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _flow->set(e, flowMap[e]);
+      }
+      _flow_value = 0;
+      for (OutArcIt jt(_graph, _source); jt != INVALID; ++jt) {
+        _flow_value += (*_flow)[jt];
+      }
+      for (InArcIt jt(_graph, _source); jt != INVALID; ++jt) {
+        _flow_value -= (*_flow)[jt];
+      }
+    }
+
+    /// \brief Initializes the algorithm using the given flow map.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to the given \c flowMap. The \c flowMap should
+    /// contain a feasible flow, i.e. at each node excluding the source
+    /// and the target, the incoming flow should be equal to the
+    /// outgoing flow.
+    /// \return \c false when the given \c flowMap does not contain a
+    /// feasible flow.
+    template <typename FlowMap>
+    bool checkedInit(const FlowMap& flowMap) {
+      createStructures();
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _flow->set(e, flowMap[e]);
+      }
+      for (NodeIt it(_graph); it != INVALID; ++it) {
+        if (it == _source || it == _target) continue;
+        Value outFlow = 0;
+        for (OutArcIt jt(_graph, it); jt != INVALID; ++jt) {
+          outFlow += (*_flow)[jt];
+        }
+        Value inFlow = 0;
+        for (InArcIt jt(_graph, it); jt != INVALID; ++jt) {
+          inFlow += (*_flow)[jt];
+        }
+        if (_tolerance.different(outFlow, inFlow)) {
+          return false;
+        }
+      }
+      for (ArcIt it(_graph); it != INVALID; ++it) {
+        if (_tolerance.less((*_flow)[it], 0)) return false;
+        if (_tolerance.less((*_capacity)[it], (*_flow)[it])) return false;
+      }
+      _flow_value = 0;
+      for (OutArcIt jt(_graph, _source); jt != INVALID; ++jt) {
+        _flow_value += (*_flow)[jt];
+      }
+      for (InArcIt jt(_graph, _source); jt != INVALID; ++jt) {
+        _flow_value -= (*_flow)[jt];
+      }
+      return true;
+    }
+
+    /// \brief Augments the solution along a shortest path.
+    ///
+    /// Augments the solution along a shortest path. This function searches a
+    /// shortest path between the source and the target
+    /// in the residual digraph by the Bfs algoritm.
+    /// Then it increases the flow on this path with the minimal residual
+    /// capacity on the path. If there is no such path, it gives back
+    /// false.
+    /// \return \c false when the augmenting did not success, i.e. the
+    /// current flow is a feasible and optimal solution.
+    bool augment() {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _pred->set(n, INVALID);
+      }
+
+      int first = 0, last = 1;
+
+      _queue[0] = _source;
+      _pred->set(_source, OutArcIt(_graph, _source));
+
+      while (first != last && (*_pred)[_target] == INVALID) {
+        Node n = _queue[first++];
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Value rem = (*_capacity)[e] - (*_flow)[e];
+          Node t = _graph.target(e);
+          if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
+            _pred->set(t, e);
+            _queue[last++] = t;
+          }
+        }
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Value rem = (*_flow)[e];
+          Node t = _graph.source(e);
+          if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
+            _pred->set(t, e);
+            _queue[last++] = t;
+          }
+        }
+      }
+
+      if ((*_pred)[_target] != INVALID) {
+        Node n = _target;
+        Arc e = (*_pred)[n];
+
+        Value prem = (*_capacity)[e] - (*_flow)[e];
+        n = _graph.source(e);
+        while (n != _source) {
+          e = (*_pred)[n];
+          if (_graph.target(e) == n) {
+            Value rem = (*_capacity)[e] - (*_flow)[e];
+            if (rem < prem) prem = rem;
+            n = _graph.source(e);
+          } else {
+            Value rem = (*_flow)[e];
+            if (rem < prem) prem = rem;
+            n = _graph.target(e);
+          }
+        }
+
+        n = _target;
+        e = (*_pred)[n];
+
+        _flow->set(e, (*_flow)[e] + prem);
+        n = _graph.source(e);
+        while (n != _source) {
+          e = (*_pred)[n];
+          if (_graph.target(e) == n) {
+            _flow->set(e, (*_flow)[e] + prem);
+            n = _graph.source(e);
+          } else {
+            _flow->set(e, (*_flow)[e] - prem);
+            n = _graph.target(e);
+          }
+        }
+
+        _flow_value += prem;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    /// \brief Executes the algorithm
+    ///
+    /// Executes the algorithm by performing augmenting phases until the
+    /// optimal solution is reached.
+    /// \pre One of the \ref init() functions must be called before
+    /// using this function.
+    void start() {
+      while (augment()) {}
+    }
+
+    /// \brief Runs the algorithm.
+    ///
+    /// Runs the Edmonds-Karp algorithm.
+    /// \note ek.run() is just a shortcut of the following code.
+    ///\code
+    /// ek.init();
+    /// ek.start();
+    ///\endcode
+    void run() {
+      init();
+      start();
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The result of the Edmonds-Karp algorithm can be obtained using these
+    /// functions.\n
+    /// Either \ref run() or \ref start() should be called before using them.
+
+    ///@{
+
+    /// \brief Returns the value of the maximum flow.
+    ///
+    /// Returns the value of the maximum flow found by the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flowValue() const {
+      return _flow_value;
+    }
+
+    /// \brief Returns the flow value on the given arc.
+    ///
+    /// Returns the flow value on the given arc.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flow(const Arc& arc) const {
+      return (*_flow)[arc];
+    }
+
+    /// \brief Returns a const reference to the flow map.
+    ///
+    /// Returns a const reference to the arc map storing the found flow.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const FlowMap& flowMap() const {
+      return *_flow;
+    }
+
+    /// \brief Returns \c true when the node is on the source side of the
+    /// minimum cut.
+    ///
+    /// Returns true when the node is on the source side of the found
+    /// minimum cut.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    bool minCut(const Node& node) const {
+      return ((*_pred)[node] != INVALID) || node == _source;
+    }
+
+    /// \brief Gives back a minimum value cut.
+    ///
+    /// Sets \c cutMap to the characteristic vector of a minimum value
+    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
+    /// node map with \c bool (or convertible) value type.
+    ///
+    /// \note This function calls \ref minCut() for each node, so it runs in
+    /// O(n) time.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    template <typename CutMap>
+    void minCutMap(CutMap& cutMap) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        cutMap.set(n, (*_pred)[n] != INVALID);
+      }
+      cutMap.set(_source, true);
+    }
+
+    /// @}
+
+  };
+
+}
+
+#endif
Index: lemon/euler.h
===================================================================
--- lemon/euler.h	(revision 956)
+++ lemon/euler.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -37,5 +37,5 @@
   ///Euler tour iterator for digraphs.
 
-  /// \ingroup graph_prop
+  /// \ingroup graph_properties
   ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
   ///graph (if there exists) and it converts to the \c Arc type of the digraph.
Index: lemon/fractional_matching.h
===================================================================
--- lemon/fractional_matching.h	(revision 956)
+++ lemon/fractional_matching.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -124,6 +124,6 @@
   public:
 
-    /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
-    /// class" of the algorithm.
+    /// \brief The \ref lemon::MaxFractionalMatchingDefaultTraits
+    /// "traits class" of the algorithm.
     typedef TR Traits;
     /// The type of the graph the algorithm runs on.
Index: lemon/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 956)
+++ lemon/full_graph.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -622,4 +622,458 @@
   };
 
+  class FullBpGraphBase {
+
+  protected:
+
+    int _red_num, _blue_num;
+    int _node_num, _edge_num;
+
+  public:
+
+    typedef FullBpGraphBase Graph;
+
+    class Node;
+    class Arc;
+    class Edge;
+
+    class Node {
+      friend class FullBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Node(int id) { _id = id;}
+
+    public:
+      Node() {}
+      Node (Invalid) { _id = -1; }
+      bool operator==(const Node& node) const {return _id == node._id;}
+      bool operator!=(const Node& node) const {return _id != node._id;}
+      bool operator<(const Node& node) const {return _id < node._id;}
+    };
+
+    class RedNode : public Node {
+      friend class FullBpGraphBase;
+    protected:
+
+      explicit RedNode(int pid) : Node(pid) {}
+
+    public:
+      RedNode() {}
+      RedNode(const RedNode& node) : Node(node) {}
+      RedNode(Invalid) : Node(INVALID){}
+    };
+
+    class BlueNode : public Node {
+      friend class FullBpGraphBase;
+    protected:
+
+      explicit BlueNode(int pid) : Node(pid) {}
+
+    public:
+      BlueNode() {}
+      BlueNode(const BlueNode& node) : Node(node) {}
+      BlueNode(Invalid) : Node(INVALID){}
+    };
+
+    class Edge {
+      friend class FullBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Edge(int id) { _id = id;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { _id = -1; }
+      bool operator==(const Edge& arc) const {return _id == arc._id;}
+      bool operator!=(const Edge& arc) const {return _id != arc._id;}
+      bool operator<(const Edge& arc) const {return _id < arc._id;}
+    };
+
+    class Arc {
+      friend class FullBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Arc(int id) { _id = id;}
+
+    public:
+      operator Edge() const {
+        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
+      }
+
+      Arc() {}
+      Arc (Invalid) { _id = -1; }
+      bool operator==(const Arc& arc) const {return _id == arc._id;}
+      bool operator!=(const Arc& arc) const {return _id != arc._id;}
+      bool operator<(const Arc& arc) const {return _id < arc._id;}
+    };
+
+
+  protected:
+
+    FullBpGraphBase()
+      : _red_num(0), _blue_num(0), _node_num(0), _edge_num(0) {}
+
+    void construct(int redNum, int blueNum) {
+      _red_num = redNum; _blue_num = blueNum;
+      _node_num = redNum + blueNum; _edge_num = redNum * blueNum;
+    }
+
+  public:
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return _node_num; }
+    int redNum() const { return _red_num; }
+    int blueNum() const { return _blue_num; }
+    int edgeNum() const { return _edge_num; }
+    int arcNum() const { return 2 * _edge_num; }
+
+    int maxNodeId() const { return _node_num - 1; }
+    int maxRedId() const { return _red_num - 1; }
+    int maxBlueId() const { return _blue_num - 1; }
+    int maxEdgeId() const { return _edge_num - 1; }
+    int maxArcId() const { return 2 * _edge_num - 1; }
+
+    bool red(Node n) const { return n._id < _red_num; }
+    bool blue(Node n) const { return n._id >= _red_num; }
+
+    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
+    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
+
+    Node source(Arc a) const {
+      if (a._id & 1) {
+        return Node((a._id >> 1) % _red_num);
+      } else {
+        return Node((a._id >> 1) / _red_num + _red_num);
+      }
+    }
+    Node target(Arc a) const {
+      if (a._id & 1) {
+        return Node((a._id >> 1) / _red_num + _red_num);
+      } else {
+        return Node((a._id >> 1) % _red_num);
+      }
+    }
+
+    RedNode redNode(Edge e) const {
+      return RedNode(e._id % _red_num);
+    }
+    BlueNode blueNode(Edge e) const {
+      return BlueNode(e._id / _red_num + _red_num);
+    }
+
+    static bool direction(Arc a) {
+      return (a._id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e._id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(RedNode& node) const {
+      node._id = _red_num - 1;
+    }
+
+    static void next(RedNode& node) {
+      --node._id;
+    }
+
+    void first(BlueNode& node) const {
+      if (_red_num == _node_num) node._id = -1;
+      else node._id = _node_num - 1;
+    }
+
+    void next(BlueNode& node) const {
+      if (node._id == _red_num) node._id = -1;
+      else --node._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = 2 * _edge_num - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void first(Edge& arc) const {
+      arc._id = _edge_num - 1;
+    }
+
+    static void next(Edge& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc &a, const Node& v) const {
+      if (v._id < _red_num) {
+        a._id = 2 * (v._id + _red_num * (_blue_num - 1)) + 1;
+      } else {
+        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num));
+      }
+    }
+    void nextOut(Arc &a) const {
+      if (a._id & 1) {
+        a._id -= 2 * _red_num;
+        if (a._id < 0) a._id = -1;
+      } else {
+        if (a._id % (2 * _red_num) == 0) a._id = -1;
+        else a._id -= 2;
+      }
+    }
+
+    void firstIn(Arc &a, const Node& v) const {
+      if (v._id < _red_num) {
+        a._id = 2 * (v._id + _red_num * (_blue_num - 1));
+      } else {
+        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)) + 1;
+      }
+    }
+    void nextIn(Arc &a) const {
+      if (a._id & 1) {
+        if (a._id % (2 * _red_num) == 1) a._id = -1;
+        else a._id -= 2;
+      } else {
+        a._id -= 2 * _red_num;
+        if (a._id < 0) a._id = -1;
+      }
+    }
+
+    void firstInc(Edge &e, bool& d, const Node& v) const {
+      if (v._id < _red_num) {
+        d = true;
+        e._id = v._id + _red_num * (_blue_num - 1);
+      } else {
+        d = false;
+        e._id = _red_num - 1 + _red_num * (v._id - _red_num);
+      }
+    }
+    void nextInc(Edge &e, bool& d) const {
+      if (d) {
+        e._id -= _red_num;
+        if (e._id < 0) e._id = -1;
+      } else {
+        if (e._id % _red_num == 0) e._id = -1;
+        else --e._id;
+      }
+    }
+
+    static int id(const Node& v) { return v._id; }
+    int id(const RedNode& v) const { return v._id; }
+    int id(const BlueNode& v) const { return v._id - _red_num; }
+    static int id(Arc e) { return e._id; }
+    static int id(Edge e) { return e._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n._id >= 0 && n._id < _node_num;
+    }
+    bool valid(Arc a) const {
+      return a._id >= 0 && a._id < 2 * _edge_num;
+    }
+    bool valid(Edge e) const {
+      return e._id >= 0 && e._id < _edge_num;
+    }
+
+    RedNode redNode(int index) const {
+      return RedNode(index);
+    }
+
+    int index(RedNode n) const {
+      return n._id;
+    }
+
+    BlueNode blueNode(int index) const {
+      return BlueNode(index + _red_num);
+    }
+
+    int index(BlueNode n) const {
+      return n._id - _red_num;
+    }
+
+    void clear() {
+      _red_num = 0; _blue_num = 0;
+      _node_num = 0; _edge_num = 0;
+    }
+
+    Edge edge(const Node& u, const Node& v) const {
+      if (u._id < _red_num) {
+        if (v._id < _red_num) {
+          return Edge(-1);
+        } else {
+          return Edge(u._id + _red_num * (v._id - _red_num));
+        }
+      } else {
+        if (v._id < _red_num) {
+          return Edge(v._id + _red_num * (u._id - _red_num));
+        } else {
+          return Edge(-1);
+        }
+      }
+    }
+
+    Arc arc(const Node& u, const Node& v) const {
+      if (u._id < _red_num) {
+        if (v._id < _red_num) {
+          return Arc(-1);
+        } else {
+          return Arc(2 * (u._id + _red_num * (v._id - _red_num)) + 1);
+        }
+      } else {
+        if (v._id < _red_num) {
+          return Arc(2 * (v._id + _red_num * (u._id - _red_num)));
+        } else {
+          return Arc(-1);
+        }
+      }
+    }
+
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      return prev != INVALID ? INVALID : edge(u, v);
+    }
+
+    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
+      return prev != INVALID ? INVALID : arc(s, t);
+    }
+
+  };
+
+  typedef BpGraphExtender<FullBpGraphBase> ExtendedFullBpGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief An undirected full bipartite graph class.
+  ///
+  /// FullBpGraph is a simple and fast implmenetation of undirected
+  /// full bipartite graphs. It contains an edge between every
+  /// red-blue pairs of nodes, therefore the number of edges is
+  /// <tt>nr*nb</tt>.  This class is completely static and it needs
+  /// constant memory space.  Thus you can neither add nor delete
+  /// nodes or edges, however the structure can be resized using
+  /// resize().
+  ///
+  /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes, edges and arcs.
+  ///
+  /// \sa FullGraph
+  class FullBpGraph : public ExtendedFullBpGraphBase {
+  public:
+
+    typedef ExtendedFullBpGraphBase Parent;
+
+    /// \brief Default constructor.
+    ///
+    /// Default constructor. The number of nodes and edges will be zero.
+    FullBpGraph() { construct(0, 0); }
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param redNum The number of the red nodes.
+    /// \param blueNum The number of the blue nodes.
+    FullBpGraph(int redNum, int blueNum) { construct(redNum, blueNum); }
+
+    /// \brief Resizes the graph
+    ///
+    /// This function resizes the graph. It fully destroys and
+    /// rebuilds the structure, therefore the maps of the graph will be
+    /// reallocated automatically and the previous values will be lost.
+    void resize(int redNum, int blueNum) {
+      Parent::notifier(Arc()).clear();
+      Parent::notifier(Edge()).clear();
+      Parent::notifier(Node()).clear();
+      Parent::notifier(BlueNode()).clear();
+      Parent::notifier(RedNode()).clear();
+      construct(redNum, blueNum);
+      Parent::notifier(RedNode()).build();
+      Parent::notifier(BlueNode()).build();
+      Parent::notifier(Node()).build();
+      Parent::notifier(Edge()).build();
+      Parent::notifier(Arc()).build();
+    }
+
+    using Parent::redNode;
+    using Parent::blueNode;
+
+    /// \brief Returns the red node with the given index.
+    ///
+    /// Returns the red node with the given index. Since this
+    /// structure is completely static, the red nodes can be indexed
+    /// with integers from the range <tt>[0..redNum()-1]</tt>.
+    /// \sa redIndex()
+    RedNode redNode(int index) const { return Parent::redNode(index); }
+
+    /// \brief Returns the index of the given red node.
+    ///
+    /// Returns the index of the given red node. Since this structure
+    /// is completely static, the red nodes can be indexed with
+    /// integers from the range <tt>[0..redNum()-1]</tt>.
+    ///
+    /// \sa operator()()
+    int index(RedNode node) const { return Parent::index(node); }
+
+    /// \brief Returns the blue node with the given index.
+    ///
+    /// Returns the blue node with the given index. Since this
+    /// structure is completely static, the blue nodes can be indexed
+    /// with integers from the range <tt>[0..blueNum()-1]</tt>.
+    /// \sa blueIndex()
+    BlueNode blueNode(int index) const { return Parent::blueNode(index); }
+
+    /// \brief Returns the index of the given blue node.
+    ///
+    /// Returns the index of the given blue node. Since this structure
+    /// is completely static, the blue nodes can be indexed with
+    /// integers from the range <tt>[0..blueNum()-1]</tt>.
+    ///
+    /// \sa operator()()
+    int index(BlueNode node) const { return Parent::index(node); }
+
+    /// \brief Returns the edge which connects the given nodes.
+    ///
+    /// Returns the edge which connects the given nodes.
+    Edge edge(const Node& u, const Node& v) const {
+      return Parent::edge(u, v);
+    }
+
+    /// \brief Returns the arc which connects the given nodes.
+    ///
+    /// Returns the arc which connects the given nodes.
+    Arc arc(const Node& u, const Node& v) const {
+      return Parent::arc(u, v);
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of red nodes.
+    int redNum() const { return Parent::redNum(); }
+    /// \brief Number of blue nodes.
+    int blueNum() const { return Parent::blueNum(); }
+    /// \brief Number of arcs.
+    int arcNum() const { return Parent::arcNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
+  };
+
 
 } //namespace lemon
Index: lemon/glpk.cc
===================================================================
--- lemon/glpk.cc	(revision 1142)
+++ lemon/glpk.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -581,4 +581,13 @@
       break;
     }
+  }
+
+  void GlpkBase::_write(std::string file, std::string format) const
+  {
+    if(format == "MPS")
+      glp_write_mps(lp, GLP_MPS_FILE, 0, file.c_str());
+    else if(format == "LP")
+      glp_write_lp(lp, 0, file.c_str());
+    else throw UnsupportedFormatError(format);
   }
 
@@ -999,3 +1008,5 @@
   const char* GlpkMip::_solverName() const { return "GlpkMip"; }
 
+
+
 } //END OF NAMESPACE LEMON
Index: lemon/glpk.h
===================================================================
--- lemon/glpk.h	(revision 956)
+++ lemon/glpk.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -116,4 +116,6 @@
     virtual void _messageLevel(MessageLevel level);
 
+    virtual void _write(std::string file, std::string format) const;
+
   private:
 
@@ -145,4 +147,17 @@
     int lpxCol(Col c) const { return cols(id(c)); }
 
+#ifdef DOXYGEN
+    /// Write the problem or the solution to a file in the given format
+
+    /// This function writes the problem or the solution
+    /// to a file in the given format.
+    /// Trying to write in an unsupported format will trigger
+    /// \ref LpBase::UnsupportedFormatError.
+    /// \param file The file path
+    /// \param format The output file format.
+    /// Supportted formats are "MPS" and "LP".
+    void write(std::string file, std::string format = "MPS") const {}
+#endif
+
   };
 
Index: lemon/gomory_hu.h
===================================================================
--- lemon/gomory_hu.h	(revision 956)
+++ lemon/gomory_hu.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -47,5 +47,5 @@
   ///
   /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
-  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
+  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{m})\f$ overall
   /// time complexity. It calculates a rooted Gomory-Hu tree.
   /// The structure of the tree and the edge weights can be
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 1288)
+++ lemon/graph_to_eps.h	(revision 1291)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/greedy_tsp.h
===================================================================
--- lemon/greedy_tsp.h	(revision 1270)
+++ lemon/greedy_tsp.h	(revision 1270)
@@ -0,0 +1,251 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_GREEDY_TSP_H
+#define LEMON_GREEDY_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief Greedy algorithm for symmetric TSP
+
+#include <vector>
+#include <algorithm>
+#include <lemon/full_graph.h>
+#include <lemon/unionfind.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief Greedy algorithm for symmetric TSP.
+  ///
+  /// GreedyTsp implements the greedy heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This algorithm is quite similar to the \ref NearestNeighborTsp
+  /// "nearest neighbor" heuristic, but it maintains a set of disjoint paths.
+  /// At each step, the shortest possible edge is added to these paths
+  /// as long as it does not create a cycle of less than n edges and it does
+  /// not increase the degree of any node above two.
+  ///
+  /// This method runs in O(n<sup>2</sup>) time.
+  /// It quickly finds a relatively short tour for most TSP instances,
+  /// but it could also yield a really bad (or even the worst) solution
+  /// in special cases.
+  ///
+  /// \tparam CM Type of the cost map.
+  template <typename CM>
+  class GreedyTsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      Cost _sum;
+      std::vector<Node> _path;
+
+    private:
+
+      // Functor class to compare edges by their costs
+      class EdgeComp {
+      private:
+        const CostMap &_cost;
+
+      public:
+        EdgeComp(const CostMap &cost) : _cost(cost) {}
+
+        bool operator()(const Edge &a, const Edge &b) const {
+          return _cost[a] < _cost[b];
+        }
+      };
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      GreedyTsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm.
+      ///
+      /// This function runs the algorithm.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run() {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+
+        std::vector<int> plist;
+        plist.resize(_gr.nodeNum()*2, -1);
+
+        std::vector<Edge> sorted_edges;
+        sorted_edges.reserve(_gr.edgeNum());
+        for (EdgeIt e(_gr); e != INVALID; ++e)
+          sorted_edges.push_back(e);
+        std::sort(sorted_edges.begin(), sorted_edges.end(), EdgeComp(_cost));
+
+        FullGraph::NodeMap<int> item_int_map(_gr);
+        UnionFind<FullGraph::NodeMap<int> > union_find(item_int_map);
+        for (NodeIt n(_gr); n != INVALID; ++n)
+          union_find.insert(n);
+
+        FullGraph::NodeMap<int> degree(_gr, 0);
+
+        int nodesNum = 0, i = 0;
+        while (nodesNum != _gr.nodeNum()-1) {
+          Edge e = sorted_edges[i++];
+          Node u = _gr.u(e),
+               v = _gr.v(e);
+
+          if (degree[u] <= 1 && degree[v] <= 1) {
+            if (union_find.join(u, v)) {
+              const int uid = _gr.id(u),
+                        vid = _gr.id(v);
+
+              plist[uid*2 + degree[u]] = vid;
+              plist[vid*2 + degree[v]] = uid;
+
+              ++degree[u];
+              ++degree[v];
+              ++nodesNum;
+            }
+          }
+        }
+
+        for (int i=0, n=-1; i<_gr.nodeNum()*2; ++i) {
+          if (plist[i] == -1) {
+            if (n==-1) {
+              n = i;
+            } else {
+              plist[n] = i/2;
+              plist[i] = n/2;
+              break;
+            }
+          }
+        }
+
+        for (int i=0, next=0, last=-1; i!=_gr.nodeNum(); ++i) {
+          _path.push_back(_gr.nodeFromId(next));
+          if (plist[2*next] != last) {
+            last = next;
+            next = plist[2*next];
+          } else {
+            last = next;
+            next = plist[2*next+1];
+          }
+        }
+
+        _sum = _cost[_gr.edge(_path.back(), _path.front())];
+        for (int i = 0; i < int(_path.size())-1; ++i) {
+          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
+        }
+
+        return _sum;
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _path;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_path.begin(), _path.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_path.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_path[i], _path[i+1]));
+        }
+        if (int(_path.size()) >= 2) {
+          path.addBack(_gr.arc(_path.back(), _path.front()));
+        }
+      }
+
+      /// @}
+
+  };
+
+}; // namespace lemon
+
+#endif
Index: lemon/grosso_locatelli_pullan_mc.h
===================================================================
--- lemon/grosso_locatelli_pullan_mc.h	(revision 1270)
+++ lemon/grosso_locatelli_pullan_mc.h	(revision 1270)
@@ -0,0 +1,840 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
+#define LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
+
+/// \ingroup approx_algs
+///
+/// \file
+/// \brief The iterated local search algorithm of Grosso, Locatelli, and Pullan
+/// for the maximum clique problem
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/random.h>
+
+namespace lemon {
+
+  /// \addtogroup approx_algs
+  /// @{
+
+  /// \brief Implementation of the iterated local search algorithm of Grosso,
+  /// Locatelli, and Pullan for the maximum clique problem
+  ///
+  /// \ref GrossoLocatelliPullanMc implements the iterated local search
+  /// algorithm of Grosso, Locatelli, and Pullan for solving the \e maximum
+  /// \e clique \e problem \cite grosso08maxclique.
+  /// It is to find the largest complete subgraph (\e clique) in an
+  /// undirected graph, i.e., the largest set of nodes where each
+  /// pair of nodes is connected.
+  ///
+  /// This class provides a simple but highly efficient and robust heuristic
+  /// method that quickly finds a quite large clique, but not necessarily the
+  /// largest one.
+  /// The algorithm performs a certain number of iterations to find several
+  /// cliques and selects the largest one among them. Various limits can be
+  /// specified to control the running time and the effectiveness of the
+  /// search process.
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  ///
+  /// \note %GrossoLocatelliPullanMc provides three different node selection
+  /// rules, from which the most powerful one is used by default.
+  /// For more information, see \ref SelectionRule.
+  template <typename GR>
+  class GrossoLocatelliPullanMc
+  {
+  public:
+
+    /// \brief Constants for specifying the node selection rule.
+    ///
+    /// Enum type containing constants for specifying the node selection rule
+    /// for the \ref run() function.
+    ///
+    /// During the algorithm, nodes are selected for addition to the current
+    /// clique according to the applied rule.
+    /// In general, the PENALTY_BASED rule turned out to be the most powerful
+    /// and the most robust, thus it is the default option.
+    /// However, another selection rule can be specified using the \ref run()
+    /// function with the proper parameter.
+    enum SelectionRule {
+
+      /// A node is selected randomly without any evaluation at each step.
+      RANDOM,
+
+      /// A node of maximum degree is selected randomly at each step.
+      DEGREE_BASED,
+
+      /// A node of minimum penalty is selected randomly at each step.
+      /// The node penalties are updated adaptively after each stage of the
+      /// search process.
+      PENALTY_BASED
+    };
+
+    /// \brief Constants for the causes of search termination.
+    ///
+    /// Enum type containing constants for the different causes of search
+    /// termination. The \ref run() function returns one of these values.
+    enum TerminationCause {
+
+      /// The iteration count limit is reached.
+      ITERATION_LIMIT,
+
+      /// The step count limit is reached.
+      STEP_LIMIT,
+
+      /// The clique size limit is reached.
+      SIZE_LIMIT
+    };
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(GR);
+
+    typedef std::vector<int> IntVector;
+    typedef std::vector<char> BoolVector;
+    typedef std::vector<BoolVector> BoolMatrix;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
+
+    // The underlying graph
+    const GR &_graph;
+    IntNodeMap _id;
+
+    // Internal matrix representation of the graph
+    BoolMatrix _gr;
+    int _n;
+
+    // Search options
+    bool _delta_based_restart;
+    int _restart_delta_limit;
+
+    // Search limits
+    int _iteration_limit;
+    int _step_limit;
+    int _size_limit;
+
+    // The current clique
+    BoolVector _clique;
+    int _size;
+
+    // The best clique found so far
+    BoolVector _best_clique;
+    int _best_size;
+
+    // The "distances" of the nodes from the current clique.
+    // _delta[u] is the number of nodes in the clique that are
+    // not connected with u.
+    IntVector _delta;
+
+    // The current tabu set
+    BoolVector _tabu;
+
+    // Random number generator
+    Random _rnd;
+
+  private:
+
+    // Implementation of the RANDOM node selection rule.
+    class RandomSelectionRule
+    {
+    private:
+
+      // References to the algorithm instance
+      const BoolVector &_clique;
+      const IntVector  &_delta;
+      const BoolVector &_tabu;
+      Random &_rnd;
+
+      // Pivot rule data
+      int _n;
+
+    public:
+
+      // Constructor
+      RandomSelectionRule(GrossoLocatelliPullanMc &mc) :
+        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
+        _rnd(mc._rnd), _n(mc._n)
+      {}
+
+      // Return a node index for a feasible add move or -1 if no one exists
+      int nextFeasibleAddNode() const {
+        int start_node = _rnd[_n];
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && !_tabu[i]) return i;
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && !_tabu[i]) return i;
+        }
+        return -1;
+      }
+
+      // Return a node index for a feasible swap move or -1 if no one exists
+      int nextFeasibleSwapNode() const {
+        int start_node = _rnd[_n];
+        for (int i = start_node; i != _n; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i]) return i;
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i]) return i;
+        }
+        return -1;
+      }
+
+      // Return a node index for an add move or -1 if no one exists
+      int nextAddNode() const {
+        int start_node = _rnd[_n];
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0) return i;
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0) return i;
+        }
+        return -1;
+      }
+
+      // Update internal data structures between stages (if necessary)
+      void update() {}
+
+    }; //class RandomSelectionRule
+
+
+    // Implementation of the DEGREE_BASED node selection rule.
+    class DegreeBasedSelectionRule
+    {
+    private:
+
+      // References to the algorithm instance
+      const BoolVector &_clique;
+      const IntVector  &_delta;
+      const BoolVector &_tabu;
+      Random &_rnd;
+
+      // Pivot rule data
+      int _n;
+      IntVector _deg;
+
+    public:
+
+      // Constructor
+      DegreeBasedSelectionRule(GrossoLocatelliPullanMc &mc) :
+        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
+        _rnd(mc._rnd), _n(mc._n), _deg(_n)
+      {
+        for (int i = 0; i != _n; i++) {
+          int d = 0;
+          BoolVector &row = mc._gr[i];
+          for (int j = 0; j != _n; j++) {
+            if (row[j]) d++;
+          }
+          _deg[i] = d;
+        }
+      }
+
+      // Return a node index for a feasible add move or -1 if no one exists
+      int nextFeasibleAddNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, max_deg = -1;
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && !_tabu[i] && _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && !_tabu[i] && _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        return node;
+      }
+
+      // Return a node index for a feasible swap move or -1 if no one exists
+      int nextFeasibleSwapNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, max_deg = -1;
+        for (int i = start_node; i != _n; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
+              _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
+              _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        return node;
+      }
+
+      // Return a node index for an add move or -1 if no one exists
+      int nextAddNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, max_deg = -1;
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && _deg[i] > max_deg) {
+            node = i;
+            max_deg = _deg[i];
+          }
+        }
+        return node;
+      }
+
+      // Update internal data structures between stages (if necessary)
+      void update() {}
+
+    }; //class DegreeBasedSelectionRule
+
+
+    // Implementation of the PENALTY_BASED node selection rule.
+    class PenaltyBasedSelectionRule
+    {
+    private:
+
+      // References to the algorithm instance
+      const BoolVector &_clique;
+      const IntVector  &_delta;
+      const BoolVector &_tabu;
+      Random &_rnd;
+
+      // Pivot rule data
+      int _n;
+      IntVector _penalty;
+
+    public:
+
+      // Constructor
+      PenaltyBasedSelectionRule(GrossoLocatelliPullanMc &mc) :
+        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
+        _rnd(mc._rnd), _n(mc._n), _penalty(_n, 0)
+      {}
+
+      // Return a node index for a feasible add move or -1 if no one exists
+      int nextFeasibleAddNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, min_p = std::numeric_limits<int>::max();
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && !_tabu[i] && _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && !_tabu[i] && _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        return node;
+      }
+
+      // Return a node index for a feasible swap move or -1 if no one exists
+      int nextFeasibleSwapNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, min_p = std::numeric_limits<int>::max();
+        for (int i = start_node; i != _n; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
+              _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
+              _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        return node;
+      }
+
+      // Return a node index for an add move or -1 if no one exists
+      int nextAddNode() const {
+        int start_node = _rnd[_n];
+        int node = -1, min_p = std::numeric_limits<int>::max();
+        for (int i = start_node; i != _n; i++) {
+          if (_delta[i] == 0 && _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        for (int i = 0; i != start_node; i++) {
+          if (_delta[i] == 0 && _penalty[i] < min_p) {
+            node = i;
+            min_p = _penalty[i];
+          }
+        }
+        return node;
+      }
+
+      // Update internal data structures between stages (if necessary)
+      void update() {}
+
+    }; //class PenaltyBasedSelectionRule
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// The global \ref rnd "random number generator instance" is used
+    /// during the algorithm.
+    ///
+    /// \param graph The undirected graph the algorithm runs on.
+    GrossoLocatelliPullanMc(const GR& graph) :
+      _graph(graph), _id(_graph), _rnd(rnd)
+    {
+      initOptions();
+    }
+
+    /// \brief Constructor with random seed.
+    ///
+    /// Constructor with random seed.
+    ///
+    /// \param graph The undirected graph the algorithm runs on.
+    /// \param seed Seed value for the internal random number generator
+    /// that is used during the algorithm.
+    GrossoLocatelliPullanMc(const GR& graph, int seed) :
+      _graph(graph), _id(_graph), _rnd(seed)
+    {
+      initOptions();
+    }
+
+    /// \brief Constructor with random number generator.
+    ///
+    /// Constructor with random number generator.
+    ///
+    /// \param graph The undirected graph the algorithm runs on.
+    /// \param random A random number generator that is used during the
+    /// algorithm.
+    GrossoLocatelliPullanMc(const GR& graph, const Random& random) :
+      _graph(graph), _id(_graph), _rnd(random)
+    {
+      initOptions();
+    }
+
+    /// \name Execution Control
+    /// The \ref run() function can be used to execute the algorithm.\n
+    /// The functions \ref iterationLimit(int), \ref stepLimit(int), and
+    /// \ref sizeLimit(int) can be used to specify various limits for the
+    /// search process.
+
+    /// @{
+
+    /// \brief Sets the maximum number of iterations.
+    ///
+    /// This function sets the maximum number of iterations.
+    /// Each iteration of the algorithm finds a maximal clique (but not
+    /// necessarily the largest one) by performing several search steps
+    /// (node selections).
+    ///
+    /// This limit controls the running time and the success of the
+    /// algorithm. For larger values, the algorithm runs slower, but it more
+    /// likely finds larger cliques. For smaller values, the algorithm is
+    /// faster but probably gives worse results.
+    ///
+    /// The default value is \c 1000.
+    /// \c -1 means that number of iterations is not limited.
+    ///
+    /// \warning You should specify a reasonable limit for the number of
+    /// iterations and/or the number of search steps.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \sa stepLimit(int)
+    /// \sa sizeLimit(int)
+    GrossoLocatelliPullanMc& iterationLimit(int limit) {
+      _iteration_limit = limit;
+      return *this;
+    }
+
+    /// \brief Sets the maximum number of search steps.
+    ///
+    /// This function sets the maximum number of elementary search steps.
+    /// Each iteration of the algorithm finds a maximal clique (but not
+    /// necessarily the largest one) by performing several search steps
+    /// (node selections).
+    ///
+    /// This limit controls the running time and the success of the
+    /// algorithm. For larger values, the algorithm runs slower, but it more
+    /// likely finds larger cliques. For smaller values, the algorithm is
+    /// faster but probably gives worse results.
+    ///
+    /// The default value is \c -1, which means that number of steps
+    /// is not limited explicitly. However, the number of iterations is
+    /// limited and each iteration performs a finite number of search steps.
+    ///
+    /// \warning You should specify a reasonable limit for the number of
+    /// iterations and/or the number of search steps.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \sa iterationLimit(int)
+    /// \sa sizeLimit(int)
+    GrossoLocatelliPullanMc& stepLimit(int limit) {
+      _step_limit = limit;
+      return *this;
+    }
+
+    /// \brief Sets the desired clique size.
+    ///
+    /// This function sets the desired clique size that serves as a search
+    /// limit. If a clique of this size (or a larger one) is found, then the
+    /// algorithm terminates.
+    ///
+    /// This function is especially useful if you know an exact upper bound
+    /// for the size of the cliques in the graph or if any clique above
+    /// a certain size limit is sufficient for your application.
+    ///
+    /// The default value is \c -1, which means that the size limit is set to
+    /// the number of nodes in the graph.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \sa iterationLimit(int)
+    /// \sa stepLimit(int)
+    GrossoLocatelliPullanMc& sizeLimit(int limit) {
+      _size_limit = limit;
+      return *this;
+    }
+
+    /// \brief The maximum number of iterations.
+    ///
+    /// This function gives back the maximum number of iterations.
+    /// \c -1 means that no limit is specified.
+    ///
+    /// \sa iterationLimit(int)
+    int iterationLimit() const {
+      return _iteration_limit;
+    }
+
+    /// \brief The maximum number of search steps.
+    ///
+    /// This function gives back the maximum number of search steps.
+    /// \c -1 means that no limit is specified.
+    ///
+    /// \sa stepLimit(int)
+    int stepLimit() const {
+      return _step_limit;
+    }
+
+    /// \brief The desired clique size.
+    ///
+    /// This function gives back the desired clique size that serves as a
+    /// search limit. \c -1 means that this limit is set to the number of
+    /// nodes in the graph.
+    ///
+    /// \sa sizeLimit(int)
+    int sizeLimit() const {
+      return _size_limit;
+    }
+
+    /// \brief Runs the algorithm.
+    ///
+    /// This function runs the algorithm. If one of the specified limits
+    /// is reached, the search process terminates.
+    ///
+    /// \param rule The node selection rule. For more information, see
+    /// \ref SelectionRule.
+    ///
+    /// \return The termination cause of the search. For more information,
+    /// see \ref TerminationCause.
+    TerminationCause run(SelectionRule rule = PENALTY_BASED)
+    {
+      init();
+      switch (rule) {
+        case RANDOM:
+          return start<RandomSelectionRule>();
+        case DEGREE_BASED:
+          return start<DegreeBasedSelectionRule>();
+        default:
+          return start<PenaltyBasedSelectionRule>();
+      }
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these functions.\n
+    /// The run() function must be called before using them.
+
+    /// @{
+
+    /// \brief The size of the found clique
+    ///
+    /// This function returns the size of the found clique.
+    ///
+    /// \pre run() must be called before using this function.
+    int cliqueSize() const {
+      return _best_size;
+    }
+
+    /// \brief Gives back the found clique in a \c bool node map
+    ///
+    /// This function gives back the characteristic vector of the found
+    /// clique in the given node map.
+    /// It must be a \ref concepts::WriteMap "writable" node map with
+    /// \c bool (or convertible) value type.
+    ///
+    /// \pre run() must be called before using this function.
+    template <typename CliqueMap>
+    void cliqueMap(CliqueMap &map) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        map[n] = static_cast<bool>(_best_clique[_id[n]]);
+      }
+    }
+
+    /// \brief Iterator to list the nodes of the found clique
+    ///
+    /// This iterator class lists the nodes of the found clique.
+    /// Before using it, you must allocate a GrossoLocatelliPullanMc instance
+    /// and call its \ref GrossoLocatelliPullanMc::run() "run()" method.
+    ///
+    /// The following example prints out the IDs of the nodes in the found
+    /// clique.
+    /// \code
+    ///   GrossoLocatelliPullanMc<Graph> mc(g);
+    ///   mc.run();
+    ///   for (GrossoLocatelliPullanMc<Graph>::CliqueNodeIt n(mc);
+    ///        n != INVALID; ++n)
+    ///   {
+    ///     std::cout << g.id(n) << std::endl;
+    ///   }
+    /// \endcode
+    class CliqueNodeIt
+    {
+    private:
+      NodeIt _it;
+      BoolNodeMap _map;
+
+    public:
+
+      /// Constructor
+
+      /// Constructor.
+      /// \param mc The algorithm instance.
+      CliqueNodeIt(const GrossoLocatelliPullanMc &mc)
+       : _map(mc._graph)
+      {
+        mc.cliqueMap(_map);
+        for (_it = NodeIt(mc._graph); _it != INVALID && !_map[_it]; ++_it) ;
+      }
+
+      /// Conversion to \c Node
+      operator Node() const { return _it; }
+
+      bool operator==(Invalid) const { return _it == INVALID; }
+      bool operator!=(Invalid) const { return _it != INVALID; }
+
+      /// Next node
+      CliqueNodeIt &operator++() {
+        for (++_it; _it != INVALID && !_map[_it]; ++_it) ;
+        return *this;
+      }
+
+      /// Postfix incrementation
+
+      /// Postfix incrementation.
+      ///
+      /// \warning This incrementation returns a \c Node, not a
+      /// \c CliqueNodeIt as one may expect.
+      typename GR::Node operator++(int) {
+        Node n=*this;
+        ++(*this);
+        return n;
+      }
+
+    };
+
+    /// @}
+
+  private:
+
+    // Initialize search options and limits
+    void initOptions() {
+      // Search options
+      _delta_based_restart = true;
+      _restart_delta_limit = 4;
+
+      // Search limits
+      _iteration_limit = 1000;
+      _step_limit = -1;             // this is disabled by default
+      _size_limit = -1;             // this is disabled by default
+    }
+
+    // Adds a node to the current clique
+    void addCliqueNode(int u) {
+      if (_clique[u]) return;
+      _clique[u] = true;
+      _size++;
+      BoolVector &row = _gr[u];
+      for (int i = 0; i != _n; i++) {
+        if (!row[i]) _delta[i]++;
+      }
+    }
+
+    // Removes a node from the current clique
+    void delCliqueNode(int u) {
+      if (!_clique[u]) return;
+      _clique[u] = false;
+      _size--;
+      BoolVector &row = _gr[u];
+      for (int i = 0; i != _n; i++) {
+        if (!row[i]) _delta[i]--;
+      }
+    }
+
+    // Initialize data structures
+    void init() {
+      _n = countNodes(_graph);
+      int ui = 0;
+      for (NodeIt u(_graph); u != INVALID; ++u) {
+        _id[u] = ui++;
+      }
+      _gr.clear();
+      _gr.resize(_n, BoolVector(_n, false));
+      ui = 0;
+      for (NodeIt u(_graph); u != INVALID; ++u) {
+        for (IncEdgeIt e(_graph, u); e != INVALID; ++e) {
+          int vi = _id[_graph.runningNode(e)];
+          _gr[ui][vi] = true;
+          _gr[vi][ui] = true;
+        }
+        ++ui;
+      }
+
+      _clique.clear();
+      _clique.resize(_n, false);
+      _size = 0;
+      _best_clique.clear();
+      _best_clique.resize(_n, false);
+      _best_size = 0;
+      _delta.clear();
+      _delta.resize(_n, 0);
+      _tabu.clear();
+      _tabu.resize(_n, false);
+    }
+
+    // Executes the algorithm
+    template <typename SelectionRuleImpl>
+    TerminationCause start() {
+      if (_n == 0) return SIZE_LIMIT;
+      if (_n == 1) {
+        _best_clique[0] = true;
+        _best_size = 1;
+        return SIZE_LIMIT;
+      }
+
+      // Iterated local search algorithm
+      const int max_size = _size_limit >= 0 ? _size_limit : _n;
+      const int max_restart = _iteration_limit >= 0 ?
+        _iteration_limit : std::numeric_limits<int>::max();
+      const int max_select = _step_limit >= 0 ?
+        _step_limit : std::numeric_limits<int>::max();
+
+      SelectionRuleImpl sel_method(*this);
+      int select = 0, restart = 0;
+      IntVector restart_nodes;
+      while (select < max_select && restart < max_restart) {
+
+        // Perturbation/restart
+        restart++;
+        if (_delta_based_restart) {
+          restart_nodes.clear();
+          for (int i = 0; i != _n; i++) {
+            if (_delta[i] >= _restart_delta_limit)
+              restart_nodes.push_back(i);
+          }
+        }
+        int rs_node = -1;
+        if (restart_nodes.size() > 0) {
+          rs_node = restart_nodes[_rnd[restart_nodes.size()]];
+        } else {
+          rs_node = _rnd[_n];
+        }
+        BoolVector &row = _gr[rs_node];
+        for (int i = 0; i != _n; i++) {
+          if (_clique[i] && !row[i]) delCliqueNode(i);
+        }
+        addCliqueNode(rs_node);
+
+        // Local search
+        _tabu.clear();
+        _tabu.resize(_n, false);
+        bool tabu_empty = true;
+        int max_swap = _size;
+        while (select < max_select) {
+          select++;
+          int u;
+          if ((u = sel_method.nextFeasibleAddNode()) != -1) {
+            // Feasible add move
+            addCliqueNode(u);
+            if (tabu_empty) max_swap = _size;
+          }
+          else if ((u = sel_method.nextFeasibleSwapNode()) != -1) {
+            // Feasible swap move
+            int v = -1;
+            BoolVector &row = _gr[u];
+            for (int i = 0; i != _n; i++) {
+              if (_clique[i] && !row[i]) {
+                v = i;
+                break;
+              }
+            }
+            addCliqueNode(u);
+            delCliqueNode(v);
+            _tabu[v] = true;
+            tabu_empty = false;
+            if (--max_swap <= 0) break;
+          }
+          else if ((u = sel_method.nextAddNode()) != -1) {
+            // Non-feasible add move
+            addCliqueNode(u);
+          }
+          else break;
+        }
+        if (_size > _best_size) {
+          _best_clique = _clique;
+          _best_size = _size;
+          if (_best_size >= max_size) return SIZE_LIMIT;
+        }
+        sel_method.update();
+      }
+
+      return (restart >= max_restart ? ITERATION_LIMIT : STEP_LIMIT);
+    }
+
+  }; //class GrossoLocatelliPullanMc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
Index: lemon/hao_orlin.h
===================================================================
--- lemon/hao_orlin.h	(revision 956)
+++ lemon/hao_orlin.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -54,6 +54,6 @@
   /// preflow push-relabel algorithm. Our implementation calculates
   /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
-  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
-  /// purpose of such algorithm is e.g. testing network reliability.
+  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. A notable
+  /// use of this algorithm is testing network reliability.
   ///
   /// For an undirected graph you can run just the first phase of the
@@ -913,4 +913,6 @@
     /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
     /// \f$ source \in X \f$ and minimal outgoing capacity).
+    /// It updates the stored cut if (and only if) the newly found one
+    /// is better.
     ///
     /// \pre \ref init() must be called before using this function.
@@ -925,4 +927,6 @@
     /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
     /// \f$ source \notin X \f$ and minimal outgoing capacity).
+    /// It updates the stored cut if (and only if) the newly found one
+    /// is better.
     ///
     /// \pre \ref init() must be called before using this function.
@@ -934,6 +938,6 @@
     /// \brief Run the algorithm.
     ///
-    /// This function runs the algorithm. It finds nodes \c source and
-    /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
+    /// This function runs the algorithm. It chooses source node,
+    /// then calls \ref init(), \ref calculateOut()
     /// and \ref calculateIn().
     void run() {
@@ -945,7 +949,7 @@
     /// \brief Run the algorithm.
     ///
-    /// This function runs the algorithm. It uses the given \c source node,
-    /// finds a proper \c target node and then calls the \ref init(),
-    /// \ref calculateOut() and \ref calculateIn().
+    /// This function runs the algorithm. It calls \ref init(),
+    /// \ref calculateOut() and \ref calculateIn() with the given
+    /// source node.
     void run(const Node& s) {
       init(s);
@@ -966,5 +970,7 @@
     /// \brief Return the value of the minimum cut.
     ///
-    /// This function returns the value of the minimum cut.
+    /// This function returns the value of the best cut found by the
+    /// previously called \ref run(), \ref calculateOut() or \ref
+    /// calculateIn().
     ///
     /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
@@ -977,7 +983,11 @@
     /// \brief Return a minimum cut.
     ///
-    /// This function sets \c cutMap to the characteristic vector of a
-    /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
-    /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
+    /// This function gives the best cut found by the
+    /// previously called \ref run(), \ref calculateOut() or \ref
+    /// calculateIn().
+    ///
+    /// It sets \c cutMap to the characteristic vector of the found
+    /// minimum value cut - a non-empty set \f$ X\subsetneq V \f$
+    /// of minimum outgoing capacity (i.e. \c cutMap will be \c true exactly
     /// for the nodes of \f$ X \f$).
     ///
Index: lemon/hartmann_orlin_mmc.h
===================================================================
--- lemon/hartmann_orlin_mmc.h	(revision 959)
+++ lemon/hartmann_orlin_mmc.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -99,8 +99,9 @@
   /// This class implements the Hartmann-Orlin algorithm for finding
   /// a directed cycle of minimum mean cost in a digraph
-  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
-  /// It is an improved version of \ref KarpMmc "Karp"'s original algorithm,
-  /// it applies an efficient early termination scheme.
-  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
+  /// \cite hartmann93finding, \cite dasdan98minmeancycle.
+  /// This method is based on \ref KarpMmc "Karp"'s original algorithm, but
+  /// applies an early termination scheme. It makes the algorithm
+  /// significantly faster for some problem instances, but slower for others.
+  /// The algorithm runs in time O(nm) and uses space O(n<sup>2</sup>+m).
   ///
   /// \tparam GR The type of the digraph the algorithm runs on.
@@ -143,9 +144,12 @@
     ///
     /// The path type of the found cycles.
-    /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class",
+    /// Using the \ref lemon::HartmannOrlinMmcDefaultTraits
+    /// "default traits class",
     /// it is \ref lemon::Path "Path<Digraph>".
     typedef typename TR::Path Path;
 
-    /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm
+    /// \brief The
+    /// \ref lemon::HartmannOrlinMmcDefaultTraits "traits class"
+    /// of the algorithm
     typedef TR Traits;
 
@@ -275,6 +279,6 @@
     ///
     /// If you don't call this function before calling \ref run() or
-    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
-    /// structure. The destuctor deallocates this automatically
+    /// \ref findCycleMean(), a local \ref Path "path" structure
+    /// will be allocated. The destuctor deallocates this automatically
     /// allocated object, of course.
     ///
Index: lemon/howard_mmc.h
===================================================================
--- lemon/howard_mmc.h	(revision 956)
+++ lemon/howard_mmc.h	(revision 1271)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -99,5 +99,5 @@
   /// This class implements Howard's policy iteration algorithm for finding
   /// a directed cycle of minimum mean cost in a digraph
-  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// \cite dasdan98minmeancycle, \cite dasdan04experimental.
   /// This class provides the most efficient algorithm for the
   /// minimum mean cycle problem, though the best known theoretical
@@ -143,10 +143,27 @@
     ///
     /// The path type of the found cycles.
-    /// Using the \ref HowardMmcDefaultTraits "default traits class",
+    /// Using the \ref lemon::HowardMmcDefaultTraits "default traits class",
     /// it is \ref lemon::Path "Path<Digraph>".
     typedef typename TR::Path Path;
 
-    /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
+    /// The \ref lemon::HowardMmcDefaultTraits "traits class" of the algorithm
     typedef TR Traits;
+
+    /// \brief Constants for the causes of search termination.
+    ///
+    /// Enum type containing constants for the different causes of search
+    /// termination. The \ref findCycleMean() function returns one of
+    /// these values.
+    enum TerminationCause {
+
+      /// No directed cycle can be found in the digraph.
+      NO_CYCLE = 0,
+
+      /// Optimal solution (minimum cycle mean) is found.
+      OPTIMAL = 1,
+
+      /// The iteration count limit is reached.
+      ITERATION_LIMIT
+    };
 
   private:
@@ -266,6 +283,6 @@
     ///
     /// If you don't call this function before calling \ref run() or
-    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
-    /// structure. The destuctor deallocates this automatically
+    /// \ref findCycleMean(), a local \ref Path "path" structure
+    /// will be allocated. The destuctor deallocates this automatically
     /// allocated object, of course.
     ///
@@ -325,11 +342,26 @@
     }
 
-    /// \brief Find the minimum cycle mean.
+    /// \brief Find the minimum cycle mean (or an upper bound).
     ///
     /// This function finds the minimum mean cost of the directed
-    /// cycles in the digraph.
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    bool findCycleMean() {
+    /// cycles in the digraph (or an upper bound for it).
+    ///
+    /// By default, the function finds the exact minimum cycle mean,
+    /// but an optional limit can also be specified for the number of
+    /// iterations performed during the search process.
+    /// The return value indicates if the optimal solution is found
+    /// or the iteration limit is reached. In the latter case, an
+    /// approximate solution is provided, which corresponds to a directed
+    /// cycle whose mean cost is relatively small, but not necessarily
+    /// minimal.
+    ///
+    /// \param limit  The maximum allowed number of iterations during
+    /// the search process. Its default value implies that the algorithm
+    /// runs until it finds the exact optimal solution.
+    ///
+    /// \return The termination cause of the search process.
+    /// For more information, see \ref TerminationCause.
+    TerminationCause findCycleMean(int limit =
+                                   std::numeric_limits<int>::max()) {
       // Initialize and find strongly connected components
       init();
@@ -337,11 +369,18 @@
 
       // Find the minimum cycle mean in the components
+      int iter_count = 0;
+      bool iter_limit_reached = false;
       for (int comp = 0; comp < _comp_num; ++comp) {
         // Find the minimum mean cycle in the current component
         if (!buildPolicyGraph(comp)) continue;
         while (true) {
+          if (++iter_count > limit) {
+            iter_limit_reached = true;
+            break;
+          }
           findPolicyCycle();
           if (!computeNodeDistances()) break;
         }
+
         // Update the best cycle (global minimum mean cycle)
         if ( _curr_found && (!_best_found ||
@@ -352,6 +391,13 @@
           _best_node = _curr_node;
         }
-      }
-      return _best_found;
+
+        if (iter_limit_reached) break;
+      }
+
+      if (iter_limit_reached) {
+        return ITERATION_LIMIT;
+      } else {
+        return _best_found ? OPTIMAL : NO_CYCLE;
+      }
     }
 
Index: lemon/insertion_tsp.h
===================================================================
--- lemon/insertion_tsp.h	(revision 1270)
+++ lemon/insertion_tsp.h	(revision 1270)
@@ -0,0 +1,533 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_INSERTION_TSP_H
+#define LEMON_INSERTION_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief Insertion algorithm for symmetric TSP
+
+#include <vector>
+#include <functional>
+#include <lemon/full_graph.h>
+#include <lemon/maps.h>
+#include <lemon/random.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief Insertion algorithm for symmetric TSP.
+  ///
+  /// InsertionTsp implements the insertion heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This is a fast and effective tour construction method that has
+  /// many variants.
+  /// It starts with a subtour containing a few nodes of the graph and it
+  /// iteratively inserts the other nodes into this subtour according to a
+  /// certain node selection rule.
+  ///
+  /// This method is among the fastest TSP algorithms, and it typically
+  /// provides quite good solutions (usually much better than
+  /// \ref NearestNeighborTsp and \ref GreedyTsp).
+  ///
+  /// InsertionTsp implements four different node selection rules,
+  /// from which the most effective one (\e farthest \e node \e selection)
+  /// is used by default.
+  /// With this choice, the algorithm runs in O(n<sup>2</sup>) time.
+  /// For more information, see \ref SelectionRule.
+  ///
+  /// \tparam CM Type of the cost map.
+  template <typename CM>
+  class InsertionTsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      std::vector<Node> _notused;
+      std::vector<Node> _tour;
+      Cost _sum;
+
+    public:
+
+      /// \brief Constants for specifying the node selection rule.
+      ///
+      /// Enum type containing constants for specifying the node selection
+      /// rule for the \ref run() function.
+      ///
+      /// During the algorithm, nodes are selected for addition to the current
+      /// subtour according to the applied rule.
+      /// The FARTHEST method is one of the fastest selection rules, and
+      /// it is typically the most effective, thus it is the default
+      /// option. The RANDOM rule usually gives slightly worse results,
+      /// but it is more robust.
+      ///
+      /// The desired selection rule can be specified as a parameter of the
+      /// \ref run() function.
+      enum SelectionRule {
+
+        /// An unvisited node having minimum distance from the current
+        /// subtour is selected at each step.
+        /// The algorithm runs in O(n<sup>2</sup>) time using this
+        /// selection rule.
+        NEAREST,
+
+        /// An unvisited node having maximum distance from the current
+        /// subtour is selected at each step.
+        /// The algorithm runs in O(n<sup>2</sup>) time using this
+        /// selection rule.
+        FARTHEST,
+
+        /// An unvisited node whose insertion results in the least
+        /// increase of the subtour's total cost is selected at each step.
+        /// The algorithm runs in O(n<sup>3</sup>) time using this
+        /// selection rule, but in most cases, it is almost as fast as
+        /// with other rules.
+        CHEAPEST,
+
+        /// An unvisited node is selected randomly without any evaluation
+        /// at each step.
+        /// The global \ref rnd "random number generator instance" is used.
+        /// You can seed it before executing the algorithm, if you
+        /// would like to.
+        /// The algorithm runs in O(n<sup>2</sup>) time using this
+        /// selection rule.
+        RANDOM
+      };
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      InsertionTsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm.
+      ///
+      /// This function runs the algorithm.
+      ///
+      /// \param rule The node selection rule. For more information, see
+      /// \ref SelectionRule.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run(SelectionRule rule = FARTHEST) {
+        _tour.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _tour.push_back(_gr(0));
+          return _sum = 0;
+        }
+
+        switch (rule) {
+          case NEAREST:
+            init(true);
+            start<ComparingSelection<std::less<Cost> >,
+                  DefaultInsertion>();
+            break;
+          case FARTHEST:
+            init(false);
+            start<ComparingSelection<std::greater<Cost> >,
+                  DefaultInsertion>();
+            break;
+          case CHEAPEST:
+            init(true);
+            start<CheapestSelection, CheapestInsertion>();
+            break;
+          case RANDOM:
+            init(true);
+            start<RandomSelection, DefaultInsertion>();
+            break;
+        }
+        return _sum;
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _tour;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_tour.begin(), _tour.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_tour.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_tour[i], _tour[i+1]));
+        }
+        if (int(_tour.size()) >= 2) {
+          path.addBack(_gr.arc(_tour.back(), _tour.front()));
+        }
+      }
+
+      /// @}
+
+    private:
+
+      // Initializes the algorithm
+      void init(bool min) {
+        Edge min_edge = min ? mapMin(_gr, _cost) : mapMax(_gr, _cost);
+
+        _tour.clear();
+        _tour.push_back(_gr.u(min_edge));
+        _tour.push_back(_gr.v(min_edge));
+
+        _notused.clear();
+        for (NodeIt n(_gr); n!=INVALID; ++n) {
+          if (n != _gr.u(min_edge) && n != _gr.v(min_edge)) {
+            _notused.push_back(n);
+          }
+        }
+
+        _sum = _cost[min_edge] * 2;
+      }
+
+      // Executes the algorithm
+      template <class SelectionFunctor, class InsertionFunctor>
+      void start() {
+        SelectionFunctor selectNode(_gr, _cost, _tour, _notused);
+        InsertionFunctor insertNode(_gr, _cost, _tour, _sum);
+
+        for (int i=0; i<_gr.nodeNum()-2; ++i) {
+          insertNode.insert(selectNode.select());
+        }
+
+        _sum = _cost[_gr.edge(_tour.back(), _tour.front())];
+        for (int i = 0; i < int(_tour.size())-1; ++i) {
+          _sum += _cost[_gr.edge(_tour[i], _tour[i+1])];
+        }
+      }
+
+
+      // Implementation of the nearest and farthest selection rule
+      template <typename Comparator>
+      class ComparingSelection {
+        public:
+          ComparingSelection(const FullGraph &gr, const CostMap &cost,
+                  std::vector<Node> &tour, std::vector<Node> &notused)
+            : _gr(gr), _cost(cost), _tour(tour), _notused(notused),
+              _dist(gr, 0), _compare()
+          {
+            // Compute initial distances for the unused nodes
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Node u = _notused[i];
+              Cost min_dist = _cost[_gr.edge(u, _tour[0])];
+              for (unsigned int j=1; j<_tour.size(); ++j) {
+                Cost curr = _cost[_gr.edge(u, _tour[j])];
+                if (curr < min_dist) {
+                  min_dist = curr;
+                }
+              }
+              _dist[u] = min_dist;
+            }
+          }
+
+          Node select() {
+
+            // Select an used node with minimum distance
+            Cost ins_dist = 0;
+            int ins_node = -1;
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Cost curr = _dist[_notused[i]];
+              if (_compare(curr, ins_dist) || ins_node == -1) {
+                ins_dist = curr;
+                ins_node = i;
+              }
+            }
+
+            // Remove the selected node from the unused vector
+            Node sn = _notused[ins_node];
+            _notused[ins_node] = _notused.back();
+            _notused.pop_back();
+
+            // Update the distances of the remaining nodes
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Node u = _notused[i];
+              Cost nc = _cost[_gr.edge(sn, u)];
+              if (nc < _dist[u]) {
+                _dist[u] = nc;
+              }
+            }
+
+            return sn;
+          }
+
+        private:
+          const FullGraph &_gr;
+          const CostMap &_cost;
+          std::vector<Node> &_tour;
+          std::vector<Node> &_notused;
+          FullGraph::NodeMap<Cost> _dist;
+          Comparator _compare;
+      };
+
+      // Implementation of the cheapest selection rule
+      class CheapestSelection {
+        private:
+          Cost costDiff(Node u, Node v, Node w) const {
+            return
+              _cost[_gr.edge(u, w)] +
+              _cost[_gr.edge(v, w)] -
+              _cost[_gr.edge(u, v)];
+          }
+
+        public:
+          CheapestSelection(const FullGraph &gr, const CostMap &cost,
+                            std::vector<Node> &tour, std::vector<Node> &notused)
+            : _gr(gr), _cost(cost), _tour(tour), _notused(notused),
+              _ins_cost(gr, 0), _ins_pos(gr, -1)
+          {
+            // Compute insertion cost and position for the unused nodes
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Node u = _notused[i];
+              Cost min_cost = costDiff(_tour.back(), _tour.front(), u);
+              int min_pos = 0;
+              for (unsigned int j=1; j<_tour.size(); ++j) {
+                Cost curr_cost = costDiff(_tour[j-1], _tour[j], u);
+                if (curr_cost < min_cost) {
+                  min_cost = curr_cost;
+                  min_pos = j;
+                }
+              }
+              _ins_cost[u] = min_cost;
+              _ins_pos[u] = min_pos;
+            }
+          }
+
+          Cost select() {
+
+            // Select an used node with minimum insertion cost
+            Cost min_cost = 0;
+            int min_node = -1;
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Cost curr_cost = _ins_cost[_notused[i]];
+              if (curr_cost < min_cost || min_node == -1) {
+                min_cost = curr_cost;
+                min_node = i;
+              }
+            }
+
+            // Remove the selected node from the unused vector
+            Node sn = _notused[min_node];
+            _notused[min_node] = _notused.back();
+            _notused.pop_back();
+
+            // Insert the selected node into the tour
+            const int ipos = _ins_pos[sn];
+            _tour.insert(_tour.begin() + ipos, sn);
+
+            // Update the insertion cost and position of the remaining nodes
+            for (unsigned int i=0; i<_notused.size(); ++i) {
+              Node u = _notused[i];
+              Cost curr_cost = _ins_cost[u];
+              int curr_pos = _ins_pos[u];
+
+              int ipos_prev = ipos == 0 ? _tour.size()-1 : ipos-1;
+              int ipos_next = ipos == int(_tour.size())-1 ? 0 : ipos+1;
+              Cost nc1 = costDiff(_tour[ipos_prev], _tour[ipos], u);
+              Cost nc2 = costDiff(_tour[ipos], _tour[ipos_next], u);
+
+              if (nc1 <= curr_cost || nc2 <= curr_cost) {
+                // A new position is better than the old one
+                if (nc1 <= nc2) {
+                  curr_cost = nc1;
+                  curr_pos = ipos;
+                } else {
+                  curr_cost = nc2;
+                  curr_pos = ipos_next;
+                }
+              }
+              else {
+                if (curr_pos == ipos) {
+                  // The minimum should be found again
+                  curr_cost = costDiff(_tour.back(), _tour.front(), u);
+                  curr_pos = 0;
+                  for (unsigned int j=1; j<_tour.size(); ++j) {
+                    Cost tmp_cost = costDiff(_tour[j-1], _tour[j], u);
+                    if (tmp_cost < curr_cost) {
+                      curr_cost = tmp_cost;
+                      curr_pos = j;
+                    }
+                  }
+                }
+                else if (curr_pos > ipos) {
+                  ++curr_pos;
+                }
+              }
+
+              _ins_cost[u] = curr_cost;
+              _ins_pos[u] = curr_pos;
+            }
+
+            return min_cost;
+          }
+
+        private:
+          const FullGraph &_gr;
+          const CostMap &_cost;
+          std::vector<Node> &_tour;
+          std::vector<Node> &_notused;
+          FullGraph::NodeMap<Cost> _ins_cost;
+          FullGraph::NodeMap<int> _ins_pos;
+      };
+
+      // Implementation of the random selection rule
+      class RandomSelection {
+        public:
+          RandomSelection(const FullGraph &, const CostMap &,
+                          std::vector<Node> &, std::vector<Node> &notused)
+            : _notused(notused) {}
+
+          Node select() const {
+            const int index = rnd[_notused.size()];
+            Node n = _notused[index];
+            _notused[index] = _notused.back();
+            _notused.pop_back();
+            return n;
+          }
+
+        private:
+          std::vector<Node> &_notused;
+      };
+
+
+      // Implementation of the default insertion method
+      class DefaultInsertion {
+        private:
+          Cost costDiff(Node u, Node v, Node w) const {
+            return
+              _cost[_gr.edge(u, w)] +
+              _cost[_gr.edge(v, w)] -
+              _cost[_gr.edge(u, v)];
+          }
+
+        public:
+          DefaultInsertion(const FullGraph &gr, const CostMap &cost,
+                           std::vector<Node> &tour, Cost &total_cost) :
+            _gr(gr), _cost(cost), _tour(tour), _total(total_cost) {}
+
+          void insert(Node n) const {
+            int min = 0;
+            Cost min_val =
+              costDiff(_tour.front(), _tour.back(), n);
+
+            for (unsigned int i=1; i<_tour.size(); ++i) {
+              Cost tmp = costDiff(_tour[i-1], _tour[i], n);
+              if (tmp < min_val) {
+                min = i;
+                min_val = tmp;
+              }
+            }
+
+            _tour.insert(_tour.begin()+min, n);
+            _total += min_val;
+          }
+
+        private:
+          const FullGraph &_gr;
+          const CostMap &_cost;
+          std::vector<Node> &_tour;
+          Cost &_total;
+      };
+
+      // Implementation of a special insertion method for the cheapest
+      // selection rule
+      class CheapestInsertion {
+        TEMPLATE_GRAPH_TYPEDEFS(FullGraph);
+        public:
+          CheapestInsertion(const FullGraph &, const CostMap &,
+                            std::vector<Node> &, Cost &total_cost) :
+            _total(total_cost) {}
+
+          void insert(Cost diff) const {
+            _total += diff;
+          }
+
+        private:
+          Cost &_total;
+      };
+
+  };
+
+}; // namespace lemon
+
+#endif
Index: lemon/karp_mmc.h
===================================================================
--- lemon/karp_mmc.h	(revision 956)
+++ lemon/karp_mmc.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -99,6 +99,6 @@
   /// This class implements Karp's algorithm for finding a directed
   /// cycle of minimum mean cost in a digraph
-  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
-  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
+  /// \cite karp78characterization, \cite dasdan98minmeancycle.
+  /// It runs in time O(nm) and uses space O(n<sup>2</sup>+m).
   ///
   /// \tparam GR The type of the digraph the algorithm runs on.
@@ -141,9 +141,9 @@
     ///
     /// The path type of the found cycles.
-    /// Using the \ref KarpMmcDefaultTraits "default traits class",
+    /// Using the \ref lemon::KarpMmcDefaultTraits "default traits class",
     /// it is \ref lemon::Path "Path<Digraph>".
     typedef typename TR::Path Path;
 
-    /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm
+    /// The \ref lemon::KarpMmcDefaultTraits "traits class" of the algorithm
     typedef TR Traits;
 
@@ -271,6 +271,6 @@
     ///
     /// If you don't call this function before calling \ref run() or
-    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
-    /// structure. The destuctor deallocates this automatically
+    /// \ref findCycleMean(), a local \ref Path "path" structure
+    /// will be allocated. The destuctor deallocates this automatically
     /// allocated object, of course.
     ///
Index: lemon/kruskal.h
===================================================================
--- lemon/kruskal.h	(revision 631)
+++ lemon/kruskal.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -31,7 +31,4 @@
 ///\file
 ///\brief Kruskal's algorithm to compute a minimum cost spanning tree
-///
-///Kruskal's algorithm to compute a minimum cost spanning tree.
-///
 
 namespace lemon {
Index: mon/lemon.pc.cmake
===================================================================
--- lemon/lemon.pc.cmake	(revision 1012)
+++ 	(revision )
@@ -1,10 +1,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
-libdir=@CMAKE_INSTALL_PREFIX@/lib
-includedir=@CMAKE_INSTALL_PREFIX@/include
-
-Name: @PROJECT_NAME@
-Description: Library for Efficient Modeling and Optimization in Networks
-Version: @PROJECT_VERSION@
-Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
-Cflags: -I${includedir}
Index: lemon/lemon.pc.in
===================================================================
--- lemon/lemon.pc.in	(revision 705)
+++ lemon/lemon.pc.in	(revision 1133)
@@ -1,10 +1,10 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
+libdir=@CMAKE_INSTALL_PREFIX@/lib
+includedir=@CMAKE_INSTALL_PREFIX@/include
 
-Name: @PACKAGE_NAME@
+Name: @PROJECT_NAME@
 Description: Library for Efficient Modeling and Optimization in Networks
-Version: @PACKAGE_VERSION@
+Version: @PROJECT_VERSION@
 Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
 Cflags: -I${includedir}
Index: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 1110)
+++ lemon/lgf_reader.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -155,14 +155,14 @@
     };
 
-    template <typename Value>
+    template <typename Value,
+              typename Map = std::map<std::string, Value> >
     struct MapLookUpConverter {
-      const std::map<std::string, Value>& _map;
-
-      MapLookUpConverter(const std::map<std::string, Value>& map)
+      const Map& _map;
+
+      MapLookUpConverter(const Map& map)
         : _map(map) {}
 
       Value operator()(const std::string& str) {
-        typename std::map<std::string, Value>::const_iterator it =
-          _map.find(str);
+        typename Map::const_iterator it = _map.find(str);
         if (it == _map.end()) {
           std::ostringstream msg;
@@ -171,4 +171,37 @@
         }
         return it->second;
+      }
+    };
+
+    template <typename Value,
+              typename Map1 = std::map<std::string, Value>,
+              typename Map2 = std::map<std::string, Value> >
+    struct DoubleMapLookUpConverter {
+      const Map1& _map1;
+      const Map2& _map2;
+
+      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
+        : _map1(map1), _map2(map2) {}
+
+      Value operator()(const std::string& str) {
+        typename Map1::const_iterator it1 = _map1.find(str);
+        typename Map2::const_iterator it2 = _map2.find(str);
+        if (it1 == _map1.end()) {
+          if (it2 == _map2.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << str;
+            throw FormatError(msg.str());
+          } else {
+            return it2->second;
+          }
+        } else {
+          if (it2 == _map2.end()) {
+            return it1->second;
+          } else {
+            std::ostringstream msg;
+            msg << "Item is ambigous: " << str;
+            throw FormatError(msg.str());
+          }
+        }
       }
     };
@@ -1198,7 +1231,8 @@
   /// \ingroup lemon_io
   ///
-  /// \brief Return a \ref DigraphReader class
-  ///
-  /// This function just returns a \ref DigraphReader class.
+  /// \brief Return a \ref lemon::DigraphReader "DigraphReader" class
+  ///
+  /// This function just returns a \ref lemon::DigraphReader
+  /// "DigraphReader" class.
   ///
   /// With this function a digraph can be read from an
@@ -1220,7 +1254,8 @@
   ///\endcode
   ///
-  /// For a complete documentation, please see the \ref DigraphReader
+  /// For a complete documentation, please see the
+  /// \ref lemon::DigraphReader "DigraphReader"
   /// class documentation.
-  /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
+  /// \warning Don't forget to put the \ref lemon::DigraphReader::run() "run()"
   /// to the end of the parameter list.
   /// \relates DigraphReader
@@ -2076,7 +2111,7 @@
   /// \ingroup lemon_io
   ///
-  /// \brief Return a \ref GraphReader class
-  ///
-  /// This function just returns a \ref GraphReader class.
+  /// \brief Return a \ref lemon::GraphReader "GraphReader" class
+  ///
+  /// This function just returns a \ref lemon::GraphReader "GraphReader" class.
   ///
   /// With this function a graph can be read from an
@@ -2094,7 +2129,8 @@
   ///\endcode
   ///
-  /// For a complete documentation, please see the \ref GraphReader
+  /// For a complete documentation, please see the
+  /// \ref lemon::GraphReader "GraphReader"
   /// class documentation.
-  /// \warning Don't forget to put the \ref GraphReader::run() "run()"
+  /// \warning Don't forget to put the \ref lemon::GraphReader::run() "run()"
   /// to the end of the parameter list.
   /// \relates GraphReader
@@ -2126,4 +2162,1072 @@
   GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
     GraphReader<TGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  template <typename BGR>
+  class BpGraphReader;
+
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin);
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn);
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" reader for bipartite graphs
+  ///
+  /// This utility reads an \ref lgf-format "LGF" file.
+  ///
+  /// It can be used almost the same way as \c GraphReader, but it
+  /// reads the red and blue nodes from separate sections, and these
+  /// sections can contain different set of maps.
+  ///
+  /// The red and blue node maps are read from the corresponding
+  /// sections. If a map is defined with the same name in both of
+  /// these sections, then it can be read as a node map.
+  template <typename BGR>
+  class BpGraphReader {
+  public:
+
+    typedef BGR Graph;
+
+  private:
+
+    TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
+
+    std::istream* _is;
+    bool local_is;
+    std::string _filename;
+
+    BGR& _graph;
+
+    std::string _nodes_caption;
+    std::string _edges_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<std::string, RedNode> RedNodeIndex;
+    RedNodeIndex _red_node_index;
+    typedef std::map<std::string, BlueNode> BlueNodeIndex;
+    BlueNodeIndex _blue_node_index;
+    typedef std::map<std::string, Edge> EdgeIndex;
+    EdgeIndex _edge_index;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<RedNode>*> > RedNodeMaps;
+    RedNodeMaps _red_node_maps;
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<BlueNode>*> > BlueNodeMaps;
+    BlueNodeMaps _blue_node_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
+    EdgeMaps _edge_maps;
+
+    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
+      Attributes;
+    Attributes _attributes;
+
+    bool _use_nodes;
+    bool _use_edges;
+
+    bool _skip_nodes;
+    bool _skip_edges;
+
+    int line_num;
+    std::istringstream line;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// input stream.
+    BpGraphReader(BGR& graph, std::istream& is = std::cin)
+      : _is(&is), local_is(false), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// file.
+    BpGraphReader(BGR& graph, const std::string& fn)
+      : _is(new std::ifstream(fn.c_str())), local_is(true),
+        _filename(fn), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// file.
+    BpGraphReader(BGR& graph, const char* fn)
+      : _is(new std::ifstream(fn)), local_is(true),
+        _filename(fn), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~BpGraphReader() {
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_is) {
+        delete _is;
+      }
+
+    }
+
+  private:
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is);
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph,
+                                             const std::string& fn);
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
+
+    BpGraphReader(BpGraphReader& other)
+      : _is(other._is), local_is(other.local_is), _graph(other._graph),
+        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
+        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
+
+      other._is = 0;
+      other.local_is = false;
+
+      _red_node_index.swap(other._red_node_index);
+      _blue_node_index.swap(other._blue_node_index);
+      _edge_index.swap(other._edge_index);
+
+      _red_node_maps.swap(other._red_node_maps);
+      _blue_node_maps.swap(other._blue_node_maps);
+      _edge_maps.swap(other._edge_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _edges_caption = other._edges_caption;
+      _attributes_caption = other._attributes_caption;
+
+    }
+
+    BpGraphReader& operator=(const BpGraphReader&);
+
+  public:
+
+    /// \name Reading Rules
+    /// @{
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& nodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* red_storage =
+        new _reader_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _reader_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _reader_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& nodeMap(const std::string& caption, Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* red_storage =
+        new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _reader_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// Add a red node map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& redNodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* storage =
+        new _reader_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node map reading rule
+    ///
+    /// Add a red node map node reading rule with specialized converter to
+    /// the reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& redNodeMap(const std::string& caption, Map& map,
+                              const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* storage =
+        new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// Add a blue node map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& blueNodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<BlueNode>* storage =
+        new _reader_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node map reading rule
+    ///
+    /// Add a blue node map reading rule with specialized converter to
+    /// the reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& blueNodeMap(const std::string& caption, Map& map,
+                               const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<BlueNode>* storage =
+        new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map reading rule
+    ///
+    /// Add an edge map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& edgeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* storage =
+        new _reader_bits::MapStorage<Edge, Map>(map);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map reading rule
+    ///
+    /// Add an edge map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& edgeMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* storage =
+        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& arcMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* forward_storage =
+        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _reader_bits::MapStorageBase<Edge>* backward_storage =
+        new _reader_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& arcMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* forward_storage =
+        new _reader_bits::GraphArcMapStorage<BGR, true, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _reader_bits::MapStorageBase<Edge>* backward_storage =
+        new _reader_bits::GraphArcMapStorage<BGR, false, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Attribute reading rule
+    ///
+    /// Add an attribute reading rule to the reader.
+    template <typename Value>
+    BpGraphReader& attribute(const std::string& caption, Value& value) {
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Value>(value);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute reading rule
+    ///
+    /// Add an attribute reading rule with specialized converter to the
+    /// reader.
+    template <typename Value, typename Converter>
+    BpGraphReader& attribute(const std::string& caption, Value& value,
+                             const Converter& converter = Converter()) {
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node reading rule
+    ///
+    /// Add a node reading rule to reader.
+    BpGraphReader& node(const std::string& caption, Node& node) {
+      typedef _reader_bits::DoubleMapLookUpConverter<
+        Node, RedNodeIndex, BlueNodeIndex> Converter;
+      Converter converter(_red_node_index, _blue_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node reading rule
+    ///
+    /// Add a red node reading rule to reader.
+    BpGraphReader& redNode(const std::string& caption, RedNode& node) {
+      typedef _reader_bits::MapLookUpConverter<RedNode> Converter;
+      Converter converter(_red_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<RedNode, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node reading rule
+    ///
+    /// Add a blue node reading rule to reader.
+    BpGraphReader& blueNode(const std::string& caption, BlueNode& node) {
+      typedef _reader_bits::MapLookUpConverter<BlueNode> Converter;
+      Converter converter(_blue_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<BlueNode, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge reading rule
+    ///
+    /// Add an edge reading rule to reader.
+    BpGraphReader& edge(const std::string& caption, Edge& edge) {
+      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
+      Converter converter(_edge_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc reading rule
+    ///
+    /// Add an arc reading rule to reader.
+    BpGraphReader& arc(const std::string& caption, Arc& arc) {
+      typedef _reader_bits::GraphArcLookUpConverter<BGR> Converter;
+      Converter converter(_graph, _edge_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Select Section by Name
+    /// @{
+
+    /// \brief Set \c \@nodes section to be read
+    ///
+    /// Set \c \@nodes section to be read.
+    BpGraphReader& nodes(const std::string& caption) {
+      _nodes_caption = caption;
+      return *this;
+    }
+
+    /// \brief Set \c \@edges section to be read
+    ///
+    /// Set \c \@edges section to be read.
+    BpGraphReader& edges(const std::string& caption) {
+      _edges_caption = caption;
+      return *this;
+    }
+
+    /// \brief Set \c \@attributes section to be read
+    ///
+    /// Set \c \@attributes section to be read.
+    BpGraphReader& attributes(const std::string& caption) {
+      _attributes_caption = caption;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Using Previously Constructed Node or Edge Set
+    /// @{
+
+    /// \brief Use previously constructed node set
+    ///
+    /// Use previously constructed node set, and specify the node
+    /// label map.
+    template <typename Map>
+    BpGraphReader& useNodes(const Map& map) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
+      _use_nodes = true;
+      _writer_bits::DefaultConverter<typename Map::Value> converter;
+      for (RedNodeIt n(_graph); n != INVALID; ++n) {
+        _red_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+        _blue_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed node set
+    ///
+    /// Use previously constructed node set, and specify the node
+    /// label map and a functor which converts the label map values to
+    /// \c std::string.
+    template <typename Map, typename Converter>
+    BpGraphReader& useNodes(const Map& map,
+                            const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
+      _use_nodes = true;
+      for (RedNodeIt n(_graph); n != INVALID; ++n) {
+        _red_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+        _blue_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed edge set
+    ///
+    /// Use previously constructed edge set, and specify the edge
+    /// label map.
+    template <typename Map>
+    BpGraphReader& useEdges(const Map& map) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
+      _use_edges = true;
+      _writer_bits::DefaultConverter<typename Map::Value> converter;
+      for (EdgeIt a(_graph); a != INVALID; ++a) {
+        _edge_index.insert(std::make_pair(converter(map[a]), a));
+      }
+      return *this;
+    }
+
+    /// \brief Use previously constructed edge set
+    ///
+    /// Use previously constructed edge set, and specify the edge
+    /// label map and a functor which converts the label map values to
+    /// \c std::string.
+    template <typename Map, typename Converter>
+    BpGraphReader& useEdges(const Map& map,
+                            const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
+      _use_edges = true;
+      for (EdgeIt a(_graph); a != INVALID; ++a) {
+        _edge_index.insert(std::make_pair(converter(map[a]), a));
+      }
+      return *this;
+    }
+
+    /// \brief Skip the reading of node section
+    ///
+    /// Omit the reading of the node section. This implies that each node
+    /// map reading rule will be abandoned, and the nodes of the graph
+    /// will not be constructed, which usually cause that the edge set
+    /// could not be read due to lack of node name
+    /// could not be read due to lack of node name resolving.
+    /// Therefore \c skipEdges() function should also be used, or
+    /// \c useNodes() should be used to specify the label of the nodes.
+    BpGraphReader& skipNodes() {
+      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
+      _skip_nodes = true;
+      return *this;
+    }
+
+    /// \brief Skip the reading of edge section
+    ///
+    /// Omit the reading of the edge section. This implies that each edge
+    /// map reading rule will be abandoned, and the edges of the graph
+    /// will not be constructed.
+    BpGraphReader& skipEdges() {
+      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
+      _skip_edges = true;
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    bool readLine() {
+      std::string str;
+      while(++line_num, std::getline(*_is, str)) {
+        line.clear(); line.str(str);
+        char c;
+        if (line >> std::ws >> c && c != '#') {
+          line.putback(c);
+          return true;
+        }
+      }
+      return false;
+    }
+
+    bool readSuccess() {
+      return static_cast<bool>(*_is);
+    }
+
+    void skipSection() {
+      char c;
+      while (readSuccess() && line >> c && c != '@') {
+        readLine();
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readRedNodes() {
+
+      std::vector<int> map_index(_red_node_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_red_node_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of red node map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_red_node_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _red_node_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        RedNode n;
+        if (!_use_nodes) {
+          n = _graph.addRedNode();
+          if (label_index != -1)
+            _red_node_index.insert(std::make_pair(tokens[label_index], n));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, RedNode>::iterator it =
+            _red_node_index.find(tokens[label_index]);
+          if (it == _red_node_index.end()) {
+            std::ostringstream msg;
+            msg << "Node with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          n = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
+          _red_node_maps[i].second->set(n, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readBlueNodes() {
+
+      std::vector<int> map_index(_blue_node_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_blue_node_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of blue node map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_blue_node_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _blue_node_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        BlueNode n;
+        if (!_use_nodes) {
+          n = _graph.addBlueNode();
+          if (label_index != -1)
+            _blue_node_index.insert(std::make_pair(tokens[label_index], n));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, BlueNode>::iterator it =
+            _blue_node_index.find(tokens[label_index]);
+          if (it == _blue_node_index.end()) {
+            std::ostringstream msg;
+            msg << "Node with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          n = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
+          _blue_node_maps[i].second->set(n, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readEdges() {
+
+      std::vector<int> map_index(_edge_maps.size());
+      int map_num, label_index;
+
+      char c;
+      if (!readLine() || !(line >> c) || c == '@') {
+        if (readSuccess() && line) line.putback(c);
+        if (!_edge_maps.empty())
+          throw FormatError("Cannot find map names");
+        return;
+      }
+      line.putback(c);
+
+      {
+        std::map<std::string, int> maps;
+
+        std::string map;
+        int index = 0;
+        while (_reader_bits::readToken(line, map)) {
+          if (maps.find(map) != maps.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of edge map: " << map;
+            throw FormatError(msg.str());
+          }
+          maps.insert(std::make_pair(map, index));
+          ++index;
+        }
+
+        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
+          std::map<std::string, int>::iterator jt =
+            maps.find(_edge_maps[i].first);
+          if (jt == maps.end()) {
+            std::ostringstream msg;
+            msg << "Map not found: " << _edge_maps[i].first;
+            throw FormatError(msg.str());
+          }
+          map_index[i] = jt->second;
+        }
+
+        {
+          std::map<std::string, int>::iterator jt = maps.find("label");
+          if (jt != maps.end()) {
+            label_index = jt->second;
+          } else {
+            label_index = -1;
+          }
+        }
+        map_num = maps.size();
+      }
+
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::string source_token;
+        std::string target_token;
+
+        if (!_reader_bits::readToken(line, source_token))
+          throw FormatError("Red node not found");
+
+        if (!_reader_bits::readToken(line, target_token))
+          throw FormatError("Blue node not found");
+
+        std::vector<std::string> tokens(map_num);
+        for (int i = 0; i < map_num; ++i) {
+          if (!_reader_bits::readToken(line, tokens[i])) {
+            std::ostringstream msg;
+            msg << "Column not found (" << i + 1 << ")";
+            throw FormatError(msg.str());
+          }
+        }
+        if (line >> std::ws >> c)
+          throw FormatError("Extra character at the end of line");
+
+        Edge e;
+        if (!_use_edges) {
+          typename RedNodeIndex::iterator rit =
+            _red_node_index.find(source_token);
+          if (rit == _red_node_index.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << source_token;
+            throw FormatError(msg.str());
+          }
+          RedNode source = rit->second;
+          typename BlueNodeIndex::iterator it =
+            _blue_node_index.find(target_token);
+          if (it == _blue_node_index.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << target_token;
+            throw FormatError(msg.str());
+          }
+          BlueNode target = it->second;
+
+          // It is checked that source is red and
+          // target is blue, so this should be safe:
+          e = _graph.addEdge(source, target);
+          if (label_index != -1)
+            _edge_index.insert(std::make_pair(tokens[label_index], e));
+        } else {
+          if (label_index == -1)
+            throw FormatError("Label map not found");
+          typename std::map<std::string, Edge>::iterator it =
+            _edge_index.find(tokens[label_index]);
+          if (it == _edge_index.end()) {
+            std::ostringstream msg;
+            msg << "Edge with label not found: " << tokens[label_index];
+            throw FormatError(msg.str());
+          }
+          e = it->second;
+        }
+
+        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
+          _edge_maps[i].second->set(e, tokens[map_index[i]]);
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+    }
+
+    void readAttributes() {
+
+      std::set<std::string> read_attr;
+
+      char c;
+      while (readLine() && line >> c && c != '@') {
+        line.putback(c);
+
+        std::string attr, token;
+        if (!_reader_bits::readToken(line, attr))
+          throw FormatError("Attribute name not found");
+        if (!_reader_bits::readToken(line, token))
+          throw FormatError("Attribute value not found");
+        if (line >> c)
+          throw FormatError("Extra character at the end of line");
+
+        {
+          std::set<std::string>::iterator it = read_attr.find(attr);
+          if (it != read_attr.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of attribute: " << attr;
+            throw FormatError(msg.str());
+          }
+          read_attr.insert(attr);
+        }
+
+        {
+          typename Attributes::iterator it = _attributes.lower_bound(attr);
+          while (it != _attributes.end() && it->first == attr) {
+            it->second->set(token);
+            ++it;
+          }
+        }
+
+      }
+      if (readSuccess()) {
+        line.putback(c);
+      }
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        if (read_attr.find(it->first) == read_attr.end()) {
+          std::ostringstream msg;
+          msg << "Attribute not found: " << it->first;
+          throw FormatError(msg.str());
+        }
+      }
+    }
+
+  public:
+
+    /// \name Execution of the Reader
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing
+    void run() {
+
+      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
+
+      bool red_nodes_done = _skip_nodes;
+      bool blue_nodes_done = _skip_nodes;
+      bool edges_done = _skip_edges;
+      bool attributes_done = false;
+
+      line_num = 0;
+      readLine();
+      skipSection();
+
+      while (readSuccess()) {
+        try {
+          char c;
+          std::string section, caption;
+          line >> c;
+          _reader_bits::readToken(line, section);
+          _reader_bits::readToken(line, caption);
+
+          if (line >> c)
+            throw FormatError("Extra character at the end of line");
+
+          if (section == "red_nodes" && !red_nodes_done) {
+            if (_nodes_caption.empty() || _nodes_caption == caption) {
+              readRedNodes();
+              red_nodes_done = true;
+            }
+          } else if (section == "blue_nodes" && !blue_nodes_done) {
+            if (_nodes_caption.empty() || _nodes_caption == caption) {
+              readBlueNodes();
+              blue_nodes_done = true;
+            }
+          } else if ((section == "edges" || section == "arcs") &&
+                     !edges_done) {
+            if (_edges_caption.empty() || _edges_caption == caption) {
+              readEdges();
+              edges_done = true;
+            }
+          } else if (section == "attributes" && !attributes_done) {
+            if (_attributes_caption.empty() || _attributes_caption == caption) {
+              readAttributes();
+              attributes_done = true;
+            }
+          } else {
+            readLine();
+            skipSection();
+          }
+        } catch (FormatError& error) {
+          error.line(line_num);
+          error.file(_filename);
+          throw;
+        }
+      }
+
+      if (!red_nodes_done) {
+        throw FormatError("Section @red_nodes not found");
+      }
+
+      if (!blue_nodes_done) {
+        throw FormatError("Section @blue_nodes not found");
+      }
+
+      if (!edges_done) {
+        throw FormatError("Section @edges not found");
+      }
+
+      if (!attributes_done && !_attributes.empty()) {
+        throw FormatError("Section @attributes not found");
+      }
+
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref lemon::BpGraphReader "BpGraphReader" class
+  ///
+  /// This function just returns a \ref lemon::BpGraphReader
+  /// "BpGraphReader" class.
+  ///
+  /// With this function a graph can be read from an
+  /// \ref lgf-format "LGF" file or input stream with several maps and
+  /// attributes. For example, there is bipartite weighted matching problem
+  /// on a graph, i.e. a graph with a \e weight map on the edges. This
+  /// graph can be read with the following code:
+  ///
+  ///\code
+  ///ListBpGraph graph;
+  ///ListBpGraph::EdgeMap<int> weight(graph);
+  ///bpGraphReader(graph, std::cin).
+  ///  edgeMap("weight", weight).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the
+  /// \ref lemon::BpGraphReader "BpGraphReader"
+  /// class documentation.
+  /// \warning Don't forget to put the \ref lemon::BpGraphReader::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, const std::string& fn)
+  /// \sa bpGraphReader(TBGR& graph, const char* fn)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) {
+    BpGraphReader<TBGR> tmp(graph, is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphReader class
+  ///
+  /// This function just returns a \ref BpGraphReader class.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, std::istream& is)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) {
+    BpGraphReader<TBGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphReader class
+  ///
+  /// This function just returns a \ref BpGraphReader class.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, std::istream& is)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) {
+    BpGraphReader<TBGR> tmp(graph, fn);
     return tmp;
   }
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 956)
+++ lemon/lgf_writer.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -192,18 +192,47 @@
     };
 
-    template <typename Value>
+    template <typename Value,
+              typename Map = std::map<Value, std::string> >
     struct MapLookUpConverter {
-      const std::map<Value, std::string>& _map;
-
-      MapLookUpConverter(const std::map<Value, std::string>& map)
+      const Map& _map;
+
+      MapLookUpConverter(const Map& map)
         : _map(map) {}
 
-      std::string operator()(const Value& str) {
-        typename std::map<Value, std::string>::const_iterator it =
-          _map.find(str);
+      std::string operator()(const Value& value) {
+        typename Map::const_iterator it = _map.find(value);
         if (it == _map.end()) {
           throw FormatError("Item not found");
         }
         return it->second;
+      }
+    };
+
+    template <typename Value,
+              typename Map1 = std::map<Value, std::string>,
+              typename Map2 = std::map<Value, std::string> >
+    struct DoubleMapLookUpConverter {
+      const Map1& _map1;
+      const Map2& _map2;
+
+      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
+        : _map1(map1), _map2(map2) {}
+
+      std::string operator()(const Value& value) {
+        typename Map1::const_iterator it1 = _map1.find(value);
+        typename Map1::const_iterator it2 = _map2.find(value);
+        if (it1 == _map1.end()) {
+          if (it2 == _map2.end()) {
+            throw FormatError("Item not found");
+          } else {
+            return it2->second;
+          }
+        } else {
+          if (it2 == _map2.end()) {
+            return it1->second;
+          } else {
+            throw FormatError("Item is ambigous");
+          }
+        }
       }
     };
@@ -916,7 +945,8 @@
   /// \ingroup lemon_io
   ///
-  /// \brief Return a \ref DigraphWriter class
-  ///
-  /// This function just returns a \ref DigraphWriter class.
+  /// \brief Return a \ref lemon::DigraphWriter "DigraphWriter" class
+  ///
+  /// This function just returns a \ref lemon::DigraphWriter
+  /// "DigraphWriter" class.
   ///
   /// With this function a digraph can be write to a file or output
@@ -939,7 +969,8 @@
   ///\endcode
   ///
-  /// For a complete documentation, please see the \ref DigraphWriter
+  /// For a complete documentation, please see the
+  /// \ref lemon::DigraphWriter "DigraphWriter"
   /// class documentation.
-  /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
+  /// \warning Don't forget to put the \ref lemon::DigraphWriter::run() "run()"
   /// to the end of the parameter list.
   /// \relates DigraphWriter
@@ -987,5 +1018,5 @@
   /// \ingroup lemon_io
   ///
-  /// \brief \ref lgf-format "LGF" writer for directed graphs
+  /// \brief \ref lgf-format "LGF" writer for undirected graphs
   ///
   /// This utility writes an \ref lgf-format "LGF" file.
@@ -1043,6 +1074,6 @@
     /// \brief Constructor
     ///
-    /// Construct a directed graph writer, which writes to the given
-    /// output stream.
+    /// Construct an undirected graph writer, which writes to the
+    /// given output stream.
     GraphWriter(const GR& graph, std::ostream& os = std::cout)
       : _os(&os), local_os(false), _graph(graph),
@@ -1051,5 +1082,5 @@
     /// \brief Constructor
     ///
-    /// Construct a directed graph writer, which writes to the given
+    /// Construct a undirected graph writer, which writes to the given
     /// output file.
     GraphWriter(const GR& graph, const std::string& fn)
@@ -1064,5 +1095,5 @@
     /// \brief Constructor
     ///
-    /// Construct a directed graph writer, which writes to the given
+    /// Construct a undirected graph writer, which writes to the given
     /// output file.
     GraphWriter(const GR& graph, const char* fn)
@@ -1290,7 +1321,7 @@
     }
 
-    /// \brief Add an additional caption to the \c \@arcs section
-    ///
-    /// Add an additional caption to the \c \@arcs section.
+    /// \brief Add an additional caption to the \c \@edges section
+    ///
+    /// Add an additional caption to the \c \@edges section.
     GraphWriter& edges(const std::string& caption) {
       _edges_caption = caption;
@@ -1555,7 +1586,7 @@
   /// \ingroup lemon_io
   ///
-  /// \brief Return a \ref GraphWriter class
-  ///
-  /// This function just returns a \ref GraphWriter class.
+  /// \brief Return a \ref lemon::GraphWriter "GraphWriter" class
+  ///
+  /// This function just returns a \ref lemon::GraphWriter "GraphWriter" class.
   ///
   /// With this function a graph can be write to a file or output
@@ -1574,7 +1605,8 @@
   ///\endcode
   ///
-  /// For a complete documentation, please see the \ref GraphWriter
+  /// For a complete documentation, please see the
+  /// \ref lemon::GraphWriter "GraphWriter"
   /// class documentation.
-  /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
+  /// \warning Don't forget to put the \ref lemon::GraphWriter::run() "run()"
   /// to the end of the parameter list.
   /// \relates GraphWriter
@@ -1606,4 +1638,824 @@
   GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
     GraphWriter<TGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  template <typename BGR>
+  class BpGraphWriter;
+
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
+                                    std::ostream& os = std::cout);
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn);
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" writer for undirected bipartite graphs
+  ///
+  /// This utility writes an \ref lgf-format "LGF" file.
+  ///
+  /// It can be used almost the same way as \c GraphWriter, but it
+  /// reads the red and blue nodes from separate sections, and these
+  /// sections can contain different set of maps.
+  ///
+  /// The red and blue node maps are written to the corresponding
+  /// sections. The node maps are written to both of these sections
+  /// with the same map name.
+  template <typename BGR>
+  class BpGraphWriter {
+  public:
+
+    typedef BGR BpGraph;
+    TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
+
+  private:
+
+
+    std::ostream* _os;
+    bool local_os;
+
+    const BGR& _graph;
+
+    std::string _nodes_caption;
+    std::string _edges_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<Node, std::string> RedNodeIndex;
+    RedNodeIndex _red_node_index;
+    typedef std::map<Node, std::string> BlueNodeIndex;
+    BlueNodeIndex _blue_node_index;
+    typedef std::map<Edge, std::string> EdgeIndex;
+    EdgeIndex _edge_index;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<RedNode>* > > RedNodeMaps;
+    RedNodeMaps _red_node_maps;
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<BlueNode>* > > BlueNodeMaps;
+    BlueNodeMaps _blue_node_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
+    EdgeMaps _edge_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::ValueStorageBase*> > Attributes;
+    Attributes _attributes;
+
+    bool _skip_nodes;
+    bool _skip_edges;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct a bipartite graph writer, which writes to the given
+    /// output stream.
+    BpGraphWriter(const BGR& graph, std::ostream& os = std::cout)
+      : _os(&os), local_os(false), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a bipartite graph writer, which writes to the given
+    /// output file.
+    BpGraphWriter(const BGR& graph, const std::string& fn)
+      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct a bipartite graph writer, which writes to the given
+    /// output file.
+    BpGraphWriter(const BGR& graph, const char* fn)
+      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_os)) {
+        delete _os;
+        throw IoError("Cannot write file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~BpGraphWriter() {
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_os) {
+        delete _os;
+      }
+    }
+
+  private:
+
+    template <typename TBGR>
+    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
+                                             std::ostream& os);
+    template <typename TBGR>
+    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
+                                             const std::string& fn);
+    template <typename TBGR>
+    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char *fn);
+
+    BpGraphWriter(BpGraphWriter& other)
+      : _os(other._os), local_os(other.local_os), _graph(other._graph),
+        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
+
+      other._os = 0;
+      other.local_os = false;
+
+      _red_node_index.swap(other._red_node_index);
+      _blue_node_index.swap(other._blue_node_index);
+      _edge_index.swap(other._edge_index);
+
+      _red_node_maps.swap(other._red_node_maps);
+      _blue_node_maps.swap(other._blue_node_maps);
+      _edge_maps.swap(other._edge_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _edges_caption = other._edges_caption;
+      _attributes_caption = other._attributes_caption;
+    }
+
+    BpGraphWriter& operator=(const BpGraphWriter&);
+
+  public:
+
+    /// \name Writing Rules
+    /// @{
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& nodeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* red_storage =
+        new _writer_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _writer_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& nodeMap(const std::string& caption, const Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* red_storage =
+        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// \brief Red node map writing rule
+    ///
+    /// Add a red node map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* storage =
+        new _writer_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node map writing rule
+    ///
+    /// Add a red node map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& redNodeMap(const std::string& caption, const Map& map,
+                              const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* storage =
+        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node map writing rule
+    ///
+    /// Add a blue node map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<BlueNode>* storage =
+        new _writer_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node map writing rule
+    ///
+    /// Add a blue node map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map,
+                               const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<BlueNode>* storage =
+        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map writing rule
+    ///
+    /// Add an edge map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& edgeMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* storage =
+        new _writer_bits::MapStorage<Edge, Map>(map);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map writing rule
+    ///
+    /// Add an edge map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& edgeMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* storage =
+        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule to the writer.
+    template <typename Map>
+    BpGraphWriter& arcMap(const std::string& caption, const Map& map) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* forward_storage =
+        new _writer_bits::GraphArcMapStorage<BGR, true, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _writer_bits::MapStorageBase<Edge>* backward_storage =
+        new _writer_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule with specialized converter to the
+    /// writer.
+    template <typename Map, typename Converter>
+    BpGraphWriter& arcMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* forward_storage =
+        new _writer_bits::GraphArcMapStorage<BGR, true, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _writer_bits::MapStorageBase<Edge>* backward_storage =
+        new _writer_bits::GraphArcMapStorage<BGR, false, Map, Converter>
+        (_graph, map, converter);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Attribute writing rule
+    ///
+    /// Add an attribute writing rule to the writer.
+    template <typename Value>
+    BpGraphWriter& attribute(const std::string& caption, const Value& value) {
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Value>(value);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Attribute writing rule
+    ///
+    /// Add an attribute writing rule with specialized converter to the
+    /// writer.
+    template <typename Value, typename Converter>
+    BpGraphWriter& attribute(const std::string& caption, const Value& value,
+                             const Converter& converter = Converter()) {
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node writing rule
+    ///
+    /// Add a node writing rule to the writer.
+    BpGraphWriter& node(const std::string& caption, const Node& node) {
+      typedef _writer_bits::DoubleMapLookUpConverter<
+        Node, RedNodeIndex, BlueNodeIndex> Converter;
+      Converter converter(_red_node_index, _blue_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node writing rule
+    ///
+    /// Add a red node writing rule to the writer.
+    BpGraphWriter& redNode(const std::string& caption, const RedNode& node) {
+      typedef _writer_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_red_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node writing rule
+    ///
+    /// Add a blue node writing rule to the writer.
+    BpGraphWriter& blueNode(const std::string& caption, const BlueNode& node) {
+      typedef _writer_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_blue_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge writing rule
+    ///
+    /// Add an edge writing rule to writer.
+    BpGraphWriter& edge(const std::string& caption, const Edge& edge) {
+      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
+      Converter converter(_edge_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc writing rule
+    ///
+    /// Add an arc writing rule to writer.
+    BpGraphWriter& arc(const std::string& caption, const Arc& arc) {
+      typedef _writer_bits::GraphArcLookUpConverter<BGR> Converter;
+      Converter converter(_graph, _edge_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \name Section Captions
+    /// @{
+
+    /// \brief Add an additional caption to the \c \@red_nodes and
+    /// \c \@blue_nodes section
+    ///
+    /// Add an additional caption to the \c \@red_nodes and \c
+    /// \@blue_nodes section.
+    BpGraphWriter& nodes(const std::string& caption) {
+      _nodes_caption = caption;
+      return *this;
+    }
+
+    /// \brief Add an additional caption to the \c \@edges section
+    ///
+    /// Add an additional caption to the \c \@edges section.
+    BpGraphWriter& edges(const std::string& caption) {
+      _edges_caption = caption;
+      return *this;
+    }
+
+    /// \brief Add an additional caption to the \c \@attributes section
+    ///
+    /// Add an additional caption to the \c \@attributes section.
+    BpGraphWriter& attributes(const std::string& caption) {
+      _attributes_caption = caption;
+      return *this;
+    }
+
+    /// \name Skipping Section
+    /// @{
+
+    /// \brief Skip writing the node set
+    ///
+    /// The \c \@red_nodes and \c \@blue_nodes section will not be
+    /// written to the stream.
+    BpGraphWriter& skipNodes() {
+      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
+      _skip_nodes = true;
+      return *this;
+    }
+
+    /// \brief Skip writing edge set
+    ///
+    /// The \c \@edges section will not be written to the stream.
+    BpGraphWriter& skipEdges() {
+      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
+      _skip_edges = true;
+      return *this;
+    }
+
+    /// @}
+
+  private:
+
+    void writeRedNodes() {
+      _writer_bits::MapStorageBase<RedNode>* label = 0;
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@red_nodes";
+      if (!_nodes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
+      }
+      *_os << std::endl;
+
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<RedNode> nodes;
+      for (RedNodeIt n(_graph); n != INVALID; ++n) {
+        nodes.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<BGR, Node> id_map(_graph);
+        _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map);
+        std::sort(nodes.begin(), nodes.end(), id_less);
+      } else {
+        label->sort(nodes);
+      }
+
+      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
+        RedNode n = nodes[i];
+        if (label == 0) {
+          std::ostringstream os;
+          os << _graph.id(static_cast<Node>(n));
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _red_node_index.insert(std::make_pair(n, os.str()));
+        }
+        for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+             it != _red_node_maps.end(); ++it) {
+          std::string value = it->second->get(n);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _red_node_index.insert(std::make_pair(n, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void writeBlueNodes() {
+      _writer_bits::MapStorageBase<BlueNode>* label = 0;
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@blue_nodes";
+      if (!_nodes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
+      }
+      *_os << std::endl;
+
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<BlueNode> nodes;
+      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+        nodes.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<BGR, Node> id_map(_graph);
+        _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map);
+        std::sort(nodes.begin(), nodes.end(), id_less);
+      } else {
+        label->sort(nodes);
+      }
+
+      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
+        BlueNode n = nodes[i];
+        if (label == 0) {
+          std::ostringstream os;
+          os << _graph.id(static_cast<Node>(n));
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _blue_node_index.insert(std::make_pair(n, os.str()));
+        }
+        for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+             it != _blue_node_maps.end(); ++it) {
+          std::string value = it->second->get(n);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _blue_node_index.insert(std::make_pair(n, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void createRedNodeIndex() {
+      _writer_bits::MapStorageBase<RedNode>* label = 0;
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (RedNodeIt n(_graph); n != INVALID; ++n) {
+          std::ostringstream os;
+          os << _graph.id(n);
+          _red_node_index.insert(std::make_pair(n, os.str()));
+        }
+      } else {
+        for (RedNodeIt n(_graph); n != INVALID; ++n) {
+          std::string value = label->get(n);
+          _red_node_index.insert(std::make_pair(n, value));
+        }
+      }
+    }
+
+    void createBlueNodeIndex() {
+      _writer_bits::MapStorageBase<BlueNode>* label = 0;
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+          std::ostringstream os;
+          os << _graph.id(n);
+          _blue_node_index.insert(std::make_pair(n, os.str()));
+        }
+      } else {
+        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+          std::string value = label->get(n);
+          _blue_node_index.insert(std::make_pair(n, value));
+        }
+      }
+    }
+
+    void writeEdges() {
+      _writer_bits::MapStorageBase<Edge>* label = 0;
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      *_os << "@edges";
+      if (!_edges_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _edges_caption);
+      }
+      *_os << std::endl;
+
+      *_os << '\t' << '\t';
+      if (label == 0) {
+        *_os << "label" << '\t';
+      }
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << '\t';
+      }
+      *_os << std::endl;
+
+      std::vector<Edge> edges;
+      for (EdgeIt n(_graph); n != INVALID; ++n) {
+        edges.push_back(n);
+      }
+
+      if (label == 0) {
+        IdMap<BGR, Edge> id_map(_graph);
+        _writer_bits::MapLess<IdMap<BGR, Edge> > id_less(id_map);
+        std::sort(edges.begin(), edges.end(), id_less);
+      } else {
+        label->sort(edges);
+      }
+
+      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
+        Edge e = edges[i];
+        _writer_bits::writeToken(*_os, _red_node_index.
+                                 find(_graph.redNode(e))->second);
+        *_os << '\t';
+        _writer_bits::writeToken(*_os, _blue_node_index.
+                                 find(_graph.blueNode(e))->second);
+        *_os << '\t';
+        if (label == 0) {
+          std::ostringstream os;
+          os << _graph.id(e);
+          _writer_bits::writeToken(*_os, os.str());
+          *_os << '\t';
+          _edge_index.insert(std::make_pair(e, os.str()));
+        }
+        for (typename EdgeMaps::iterator it = _edge_maps.begin();
+             it != _edge_maps.end(); ++it) {
+          std::string value = it->second->get(e);
+          _writer_bits::writeToken(*_os, value);
+          if (it->first == "label") {
+            _edge_index.insert(std::make_pair(e, value));
+          }
+          *_os << '\t';
+        }
+        *_os << std::endl;
+      }
+    }
+
+    void createEdgeIndex() {
+      _writer_bits::MapStorageBase<Edge>* label = 0;
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      if (label == 0) {
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          std::ostringstream os;
+          os << _graph.id(e);
+          _edge_index.insert(std::make_pair(e, os.str()));
+        }
+      } else {
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          std::string value = label->get(e);
+          _edge_index.insert(std::make_pair(e, value));
+        }
+      }
+    }
+
+    void writeAttributes() {
+      if (_attributes.empty()) return;
+      *_os << "@attributes";
+      if (!_attributes_caption.empty()) {
+        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
+      }
+      *_os << std::endl;
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        _writer_bits::writeToken(*_os, it->first) << ' ';
+        _writer_bits::writeToken(*_os, it->second->get());
+        *_os << std::endl;
+      }
+    }
+
+  public:
+
+    /// \name Execution of the Writer
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing.
+    void run() {
+      if (!_skip_nodes) {
+        writeRedNodes();
+        writeBlueNodes();
+      } else {
+        createRedNodeIndex();
+        createBlueNodeIndex();
+      }
+      if (!_skip_edges) {
+        writeEdges();
+      } else {
+        createEdgeIndex();
+      }
+      writeAttributes();
+    }
+
+    /// \brief Give back the stream of the writer
+    ///
+    /// Give back the stream of the writer
+    std::ostream& ostream() {
+      return *_os;
+    }
+
+    /// @}
+  };
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref lemon::BpGraphWriter "BpGraphWriter" class
+  ///
+  /// This function just returns a \ref lemon::BpGraphWriter
+  /// "BpGraphWriter" class.
+  ///
+  /// With this function a bipartite graph can be write to a file or output
+  /// stream in \ref lgf-format "LGF" format with several maps and
+  /// attributes. For example, with the following code a bipartite
+  /// weighted matching problem can be written to the standard output,
+  /// i.e. a graph with a \e weight map on the edges:
+  ///
+  ///\code
+  ///ListBpGraph graph;
+  ///ListBpGraph::EdgeMap<int> weight(graph);
+  ///  // Setting the weight map
+  ///bpGraphWriter(graph, std::cout).
+  ///  edgeMap("weight", weight).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the
+  /// \ref lemon::BpGraphWriter "BpGraphWriter"
+  /// class documentation.
+  /// \warning Don't forget to put the \ref lemon::BpGraphWriter::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates BpGraphWriter
+  /// \sa bpGraphWriter(const TBGR& graph, const std::string& fn)
+  /// \sa bpGraphWriter(const TBGR& graph, const char* fn)
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, std::ostream& os) {
+    BpGraphWriter<TBGR> tmp(graph, os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphWriter class
+  ///
+  /// This function just returns a \ref BpGraphWriter class.
+  /// \relates BpGraphWriter
+  /// \sa graphWriter(const TBGR& graph, std::ostream& os)
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn) {
+    BpGraphWriter<TBGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphWriter class
+  ///
+  /// This function just returns a \ref BpGraphWriter class.
+  /// \relates BpGraphWriter
+  /// \sa graphWriter(const TBGR& graph, std::ostream& os)
+  template <typename TBGR>
+  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn) {
+    BpGraphWriter<TBGR> tmp(graph, fn);
     return tmp;
   }
Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 956)
+++ lemon/list_graph.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -446,5 +446,5 @@
     ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
     ///invalidated for the outgoing arcs of node \c v and \c InArcIt
-    ///iterators are invalidated for the incomming arcs of \c v.
+    ///iterators are invalidated for the incoming arcs of \c v.
     ///Moreover all iterators referencing node \c v or the removed
     ///loops are also invalidated. Other iterators remain valid.
@@ -1600,4 +1600,909 @@
 
   /// @}
+
+  class ListBpGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      int prev, next;
+      int partition_prev, partition_next;
+      int partition_index;
+      bool red;
+    };
+
+    struct ArcT {
+      int target;
+      int prev_out, next_out;
+    };
+
+    std::vector<NodeT> nodes;
+
+    int first_node, first_red, first_blue;
+    int max_red, max_blue;
+
+    int first_free_red, first_free_blue;
+
+    std::vector<ArcT> arcs;
+
+    int first_free_arc;
+
+  public:
+
+    typedef ListBpGraphBase BpGraph;
+
+    class Node {
+      friend class ListBpGraphBase;
+    protected:
+
+      int id;
+      explicit Node(int pid) { id = pid;}
+
+    public:
+      Node() {}
+      Node (Invalid) { id = -1; }
+      bool operator==(const Node& node) const {return id == node.id;}
+      bool operator!=(const Node& node) const {return id != node.id;}
+      bool operator<(const Node& node) const {return id < node.id;}
+    };
+
+    class RedNode : public Node {
+      friend class ListBpGraphBase;
+    protected:
+
+      explicit RedNode(int pid) : Node(pid) {}
+
+    public:
+      RedNode() {}
+      RedNode(const RedNode& node) : Node(node) {}
+      RedNode(Invalid) : Node(INVALID){}
+    };
+
+    class BlueNode : public Node {
+      friend class ListBpGraphBase;
+    protected:
+
+      explicit BlueNode(int pid) : Node(pid) {}
+
+    public:
+      BlueNode() {}
+      BlueNode(const BlueNode& node) : Node(node) {}
+      BlueNode(Invalid) : Node(INVALID){}
+    };
+
+    class Edge {
+      friend class ListBpGraphBase;
+    protected:
+
+      int id;
+      explicit Edge(int pid) { id = pid;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { id = -1; }
+      bool operator==(const Edge& edge) const {return id == edge.id;}
+      bool operator!=(const Edge& edge) const {return id != edge.id;}
+      bool operator<(const Edge& edge) const {return id < edge.id;}
+    };
+
+    class Arc {
+      friend class ListBpGraphBase;
+    protected:
+
+      int id;
+      explicit Arc(int pid) { id = pid;}
+
+    public:
+      operator Edge() const {
+        return id != -1 ? edgeFromId(id / 2) : INVALID;
+      }
+
+      Arc() {}
+      Arc (Invalid) { id = -1; }
+      bool operator==(const Arc& arc) const {return id == arc.id;}
+      bool operator!=(const Arc& arc) const {return id != arc.id;}
+      bool operator<(const Arc& arc) const {return id < arc.id;}
+    };
+
+    ListBpGraphBase()
+      : nodes(), first_node(-1),
+        first_red(-1), first_blue(-1),
+        max_red(-1), max_blue(-1),
+        first_free_red(-1), first_free_blue(-1),
+        arcs(), first_free_arc(-1) {}
+
+
+    bool red(Node n) const { return nodes[n.id].red; }
+    bool blue(Node n) const { return !nodes[n.id].red; }
+
+    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n.id); }
+    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n.id); }
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxRedId() const { return max_red; }
+    int maxBlueId() const { return max_blue; }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
+    Node target(Arc e) const { return Node(arcs[e.id].target); }
+
+    RedNode redNode(Edge e) const {
+      return RedNode(arcs[2 * e.id].target);
+    }
+    BlueNode blueNode(Edge e) const {
+      return BlueNode(arcs[2 * e.id + 1].target);
+    }
+
+    static bool direction(Arc e) {
+      return (e.id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e.id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node.id = first_node;
+    }
+
+    void next(Node& node) const {
+      node.id = nodes[node.id].next;
+    }
+
+    void first(RedNode& node) const {
+      node.id = first_red;
+    }
+
+    void next(RedNode& node) const {
+      node.id = nodes[node.id].partition_next;
+    }
+
+    void first(BlueNode& node) const {
+      node.id = first_blue;
+    }
+
+    void next(BlueNode& node) const {
+      node.id = nodes[node.id].partition_next;
+    }
+
+    void first(Arc& e) const {
+      int n = first_node;
+      while (n != -1 && nodes[n].first_out == -1) {
+        n = nodes[n].next;
+      }
+      e.id = (n == -1) ? -1 : nodes[n].first_out;
+    }
+
+    void next(Arc& e) const {
+      if (arcs[e.id].next_out != -1) {
+        e.id = arcs[e.id].next_out;
+      } else {
+        int n = nodes[arcs[e.id ^ 1].target].next;
+        while(n != -1 && nodes[n].first_out == -1) {
+          n = nodes[n].next;
+        }
+        e.id = (n == -1) ? -1 : nodes[n].first_out;
+      }
+    }
+
+    void first(Edge& e) const {
+      int n = first_node;
+      while (n != -1) {
+        e.id = nodes[n].first_out;
+        while ((e.id & 1) != 1) {
+          e.id = arcs[e.id].next_out;
+        }
+        if (e.id != -1) {
+          e.id /= 2;
+          return;
+        }
+        n = nodes[n].next;
+      }
+      e.id = -1;
+    }
+
+    void next(Edge& e) const {
+      int n = arcs[e.id * 2].target;
+      e.id = arcs[(e.id * 2) | 1].next_out;
+      while ((e.id & 1) != 1) {
+        e.id = arcs[e.id].next_out;
+      }
+      if (e.id != -1) {
+        e.id /= 2;
+        return;
+      }
+      n = nodes[n].next;
+      while (n != -1) {
+        e.id = nodes[n].first_out;
+        while ((e.id & 1) != 1) {
+          e.id = arcs[e.id].next_out;
+        }
+        if (e.id != -1) {
+          e.id /= 2;
+          return;
+        }
+        n = nodes[n].next;
+      }
+      e.id = -1;
+    }
+
+    void firstOut(Arc &e, const Node& v) const {
+      e.id = nodes[v.id].first_out;
+    }
+    void nextOut(Arc &e) const {
+      e.id = arcs[e.id].next_out;
+    }
+
+    void firstIn(Arc &e, const Node& v) const {
+      e.id = ((nodes[v.id].first_out) ^ 1);
+      if (e.id == -2) e.id = -1;
+    }
+    void nextIn(Arc &e) const {
+      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
+      if (e.id == -2) e.id = -1;
+    }
+
+    void firstInc(Edge &e, bool& d, const Node& v) const {
+      int a = nodes[v.id].first_out;
+      if (a != -1 ) {
+        e.id = a / 2;
+        d = ((a & 1) == 1);
+      } else {
+        e.id = -1;
+        d = true;
+      }
+    }
+    void nextInc(Edge &e, bool& d) const {
+      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
+      if (a != -1 ) {
+        e.id = a / 2;
+        d = ((a & 1) == 1);
+      } else {
+        e.id = -1;
+        d = true;
+      }
+    }
+
+    static int id(Node v) { return v.id; }
+    int id(RedNode v) const { return nodes[v.id].partition_index; }
+    int id(BlueNode v) const { return nodes[v.id].partition_index; }
+    static int id(Arc e) { return e.id; }
+    static int id(Edge e) { return e.id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
+        nodes[n.id].prev != -2;
+    }
+
+    bool valid(Arc a) const {
+      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
+        arcs[a.id].prev_out != -2;
+    }
+
+    bool valid(Edge e) const {
+      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
+        arcs[2 * e.id].prev_out != -2;
+    }
+
+    RedNode addRedNode() {
+      int n;
+
+      if(first_free_red==-1) {
+        n = nodes.size();
+        nodes.push_back(NodeT());
+        nodes[n].partition_index = ++max_red;
+        nodes[n].red = true;
+      } else {
+        n = first_free_red;
+        first_free_red = nodes[n].next;
+      }
+
+      nodes[n].next = first_node;
+      if (first_node != -1) nodes[first_node].prev = n;
+      first_node = n;
+      nodes[n].prev = -1;
+
+      nodes[n].partition_next = first_red;
+      if (first_red != -1) nodes[first_red].partition_prev = n;
+      first_red = n;
+      nodes[n].partition_prev = -1;
+
+      nodes[n].first_out = -1;
+
+      return RedNode(n);
+    }
+
+    BlueNode addBlueNode() {
+      int n;
+
+      if(first_free_blue==-1) {
+        n = nodes.size();
+        nodes.push_back(NodeT());
+        nodes[n].partition_index = ++max_blue;
+        nodes[n].red = false;
+      } else {
+        n = first_free_blue;
+        first_free_blue = nodes[n].next;
+      }
+
+      nodes[n].next = first_node;
+      if (first_node != -1) nodes[first_node].prev = n;
+      first_node = n;
+      nodes[n].prev = -1;
+
+      nodes[n].partition_next = first_blue;
+      if (first_blue != -1) nodes[first_blue].partition_prev = n;
+      first_blue = n;
+      nodes[n].partition_prev = -1;
+
+      nodes[n].first_out = -1;
+
+      return BlueNode(n);
+    }
+
+    Edge addEdge(Node u, Node v) {
+      int n;
+
+      if (first_free_arc == -1) {
+        n = arcs.size();
+        arcs.push_back(ArcT());
+        arcs.push_back(ArcT());
+      } else {
+        n = first_free_arc;
+        first_free_arc = arcs[n].next_out;
+      }
+
+      arcs[n].target = u.id;
+      arcs[n | 1].target = v.id;
+
+      arcs[n].next_out = nodes[v.id].first_out;
+      if (nodes[v.id].first_out != -1) {
+        arcs[nodes[v.id].first_out].prev_out = n;
+      }
+      arcs[n].prev_out = -1;
+      nodes[v.id].first_out = n;
+
+      arcs[n | 1].next_out = nodes[u.id].first_out;
+      if (nodes[u.id].first_out != -1) {
+        arcs[nodes[u.id].first_out].prev_out = (n | 1);
+      }
+      arcs[n | 1].prev_out = -1;
+      nodes[u.id].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+
+    void erase(const Node& node) {
+      int n = node.id;
+
+      if(nodes[n].next != -1) {
+        nodes[nodes[n].next].prev = nodes[n].prev;
+      }
+
+      if(nodes[n].prev != -1) {
+        nodes[nodes[n].prev].next = nodes[n].next;
+      } else {
+        first_node = nodes[n].next;
+      }
+
+      if (nodes[n].partition_next != -1) {
+        nodes[nodes[n].partition_next].partition_prev = nodes[n].partition_prev;
+      }
+
+      if (nodes[n].partition_prev != -1) {
+        nodes[nodes[n].partition_prev].partition_next = nodes[n].partition_next;
+      } else {
+        if (nodes[n].red) {
+          first_red = nodes[n].partition_next;
+        } else {
+          first_blue = nodes[n].partition_next;
+        }
+      }
+
+      if (nodes[n].red) {
+        nodes[n].next = first_free_red;
+        first_free_red = n;
+      } else {
+        nodes[n].next = first_free_blue;
+        first_free_blue = n;
+      }
+      nodes[n].prev = -2;
+    }
+
+    void erase(const Edge& edge) {
+      int n = edge.id * 2;
+
+      if (arcs[n].next_out != -1) {
+        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
+      }
+
+      if (arcs[n].prev_out != -1) {
+        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
+      } else {
+        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
+      }
+
+      if (arcs[n | 1].next_out != -1) {
+        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
+      }
+
+      if (arcs[n | 1].prev_out != -1) {
+        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
+      } else {
+        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
+      }
+
+      arcs[n].next_out = first_free_arc;
+      first_free_arc = n;
+      arcs[n].prev_out = -2;
+      arcs[n | 1].prev_out = -2;
+
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_node = first_free_arc = first_red = first_blue =
+        max_red = max_blue = first_free_red = first_free_blue = -1;
+    }
+
+  protected:
+
+    void changeRed(Edge e, RedNode n) {
+      if(arcs[(2 * e.id) | 1].next_out != -1) {
+        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
+          arcs[(2 * e.id) | 1].prev_out;
+      }
+      if(arcs[(2 * e.id) | 1].prev_out != -1) {
+        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
+          arcs[(2 * e.id) | 1].next_out;
+      } else {
+        nodes[arcs[2 * e.id].target].first_out =
+          arcs[(2 * e.id) | 1].next_out;
+      }
+
+      if (nodes[n.id].first_out != -1) {
+        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
+      }
+      arcs[2 * e.id].target = n.id;
+      arcs[(2 * e.id) | 1].prev_out = -1;
+      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = ((2 * e.id) | 1);
+    }
+
+    void changeBlue(Edge e, BlueNode n) {
+       if(arcs[2 * e.id].next_out != -1) {
+        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
+      }
+      if(arcs[2 * e.id].prev_out != -1) {
+        arcs[arcs[2 * e.id].prev_out].next_out =
+          arcs[2 * e.id].next_out;
+      } else {
+        nodes[arcs[(2 * e.id) | 1].target].first_out =
+          arcs[2 * e.id].next_out;
+      }
+
+      if (nodes[n.id].first_out != -1) {
+        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
+      }
+      arcs[(2 * e.id) | 1].target = n.id;
+      arcs[2 * e.id].prev_out = -1;
+      arcs[2 * e.id].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = 2 * e.id;
+    }
+
+  };
+
+  typedef BpGraphExtender<ListBpGraphBase> ExtendedListBpGraphBase;
+
+
+  /// \addtogroup graphs
+  /// @{
+
+  ///A general undirected graph structure.
+
+  ///\ref ListBpGraph is a versatile and fast undirected graph
+  ///implementation based on linked lists that are stored in
+  ///\c std::vector structures.
+  ///
+  ///This type fully conforms to the \ref concepts::BpGraph "BpGraph concept"
+  ///and it also provides several useful additional functionalities.
+  ///Most of its member functions and nested classes are documented
+  ///only in the concept class.
+  ///
+  ///This class provides only linear time counting for nodes, edges and arcs.
+  ///
+  ///\sa concepts::BpGraph
+  ///\sa ListDigraph
+  class ListBpGraph : public ExtendedListBpGraphBase {
+    typedef ExtendedListBpGraphBase Parent;
+
+  private:
+    /// BpGraphs are \e not copy constructible. Use BpGraphCopy instead.
+    ListBpGraph(const ListBpGraph &) :ExtendedListBpGraphBase()  {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use BpGraphCopy instead.
+    void operator=(const ListBpGraph &) {}
+  public:
+    /// Constructor
+
+    /// Constructor.
+    ///
+    ListBpGraph() {}
+
+    typedef Parent::OutArcIt IncEdgeIt;
+
+    /// \brief Add a new red node to the graph.
+    ///
+    /// This function adds a red new node to the graph.
+    /// \return The new node.
+    RedNode addRedNode() { return Parent::addRedNode(); }
+
+    /// \brief Add a new blue node to the graph.
+    ///
+    /// This function adds a blue new node to the graph.
+    /// \return The new node.
+    BlueNode addBlueNode() { return Parent::addBlueNode(); }
+
+    /// \brief Add a new edge to the graph.
+    ///
+    /// This function adds a new edge to the graph between nodes
+    /// \c u and \c v with inherent orientation from node \c u to
+    /// node \c v.
+    /// \return The new edge.
+    Edge addEdge(RedNode u, BlueNode v) {
+      return Parent::addEdge(u, v);
+    }
+    Edge addEdge(BlueNode v, RedNode u) {
+      return Parent::addEdge(u, v);
+    }
+
+    ///\brief Erase a node from the graph.
+    ///
+    /// This function erases the given node along with its incident arcs
+    /// from the graph.
+    ///
+    /// \note All iterators referencing the removed node or the incident
+    /// edges are invalidated, of course.
+    void erase(Node n) { Parent::erase(n); }
+
+    ///\brief Erase an edge from the graph.
+    ///
+    /// This function erases the given edge from the graph.
+    ///
+    /// \note All iterators referencing the removed edge are invalidated,
+    /// of course.
+    void erase(Edge e) { Parent::erase(e); }
+    /// Node validity check
+
+    /// This function gives back \c true if the given node is valid,
+    /// i.e. it is a real node of the graph.
+    ///
+    /// \warning A removed node could become valid again if new nodes are
+    /// added to the graph.
+    bool valid(Node n) const { return Parent::valid(n); }
+    /// Edge validity check
+
+    /// This function gives back \c true if the given edge is valid,
+    /// i.e. it is a real edge of the graph.
+    ///
+    /// \warning A removed edge could become valid again if new edges are
+    /// added to the graph.
+    bool valid(Edge e) const { return Parent::valid(e); }
+    /// Arc validity check
+
+    /// This function gives back \c true if the given arc is valid,
+    /// i.e. it is a real arc of the graph.
+    ///
+    /// \warning A removed arc could become valid again if new edges are
+    /// added to the graph.
+    bool valid(Arc a) const { return Parent::valid(a); }
+
+    /// \brief Change the red node of an edge.
+    ///
+    /// This function changes the red node of the given edge \c e to \c n.
+    ///
+    ///\note \c EdgeIt and \c ArcIt iterators referencing the
+    ///changed edge are invalidated and all other iterators whose
+    ///base node is the changed node are also invalidated.
+    ///
+    ///\warning This functionality cannot be used together with the
+    ///Snapshot feature.
+    void changeRed(Edge e, RedNode n) {
+      Parent::changeRed(e, n);
+    }
+    /// \brief Change the blue node of an edge.
+    ///
+    /// This function changes the blue node of the given edge \c e to \c n.
+    ///
+    ///\note \c EdgeIt iterators referencing the changed edge remain
+    ///valid, but \c ArcIt iterators referencing the changed edge and
+    ///all other iterators whose base node is the changed node are also
+    ///invalidated.
+    ///
+    ///\warning This functionality cannot be used together with the
+    ///Snapshot feature.
+    void changeBlue(Edge e, BlueNode n) {
+      Parent::changeBlue(e, n);
+    }
+
+    ///Clear the graph.
+
+    ///This function erases all nodes and arcs from the graph.
+    ///
+    ///\note All iterators of the graph are invalidated, of course.
+    void clear() {
+      Parent::clear();
+    }
+
+    /// Reserve memory for nodes.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveEdge()
+    void reserveNode(int n) { nodes.reserve(n); };
+
+    /// Reserve memory for edges.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveNode()
+    void reserveEdge(int m) { arcs.reserve(2 * m); };
+
+    /// \brief Class to make a snapshot of the graph and restore
+    /// it later.
+    ///
+    /// Class to make a snapshot of the graph and restore it later.
+    ///
+    /// The newly added nodes and edges can be removed
+    /// using the restore() function.
+    ///
+    /// \note After a state is restored, you cannot restore a later state,
+    /// i.e. you cannot add the removed nodes and edges again using
+    /// another Snapshot instance.
+    ///
+    /// \warning Node and edge deletions and other modifications
+    /// (e.g. changing the end-nodes of edges or contracting nodes)
+    /// cannot be restored. These events invalidate the snapshot.
+    /// However, the edges and nodes that were added to the graph after
+    /// making the current snapshot can be removed without invalidating it.
+    class Snapshot {
+    protected:
+
+      typedef Parent::NodeNotifier NodeNotifier;
+
+      class NodeObserverProxy : public NodeNotifier::ObserverBase {
+      public:
+
+        NodeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using NodeNotifier::ObserverBase::attach;
+        using NodeNotifier::ObserverBase::detach;
+        using NodeNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Node& node) {
+          snapshot.addNode(node);
+        }
+        virtual void add(const std::vector<Node>& nodes) {
+          for (int i = nodes.size() - 1; i >= 0; ++i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void erase(const Node& node) {
+          snapshot.eraseNode(node);
+        }
+        virtual void erase(const std::vector<Node>& nodes) {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            snapshot.eraseNode(nodes[i]);
+          }
+        }
+        virtual void build() {
+          Node node;
+          std::vector<Node> nodes;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            nodes.push_back(node);
+          }
+          for (int i = nodes.size() - 1; i >= 0; --i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void clear() {
+          Node node;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            snapshot.eraseNode(node);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
+      public:
+
+        EdgeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using EdgeNotifier::ObserverBase::attach;
+        using EdgeNotifier::ObserverBase::detach;
+        using EdgeNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Edge& edge) {
+          snapshot.addEdge(edge);
+        }
+        virtual void add(const std::vector<Edge>& edges) {
+          for (int i = edges.size() - 1; i >= 0; ++i) {
+            snapshot.addEdge(edges[i]);
+          }
+        }
+        virtual void erase(const Edge& edge) {
+          snapshot.eraseEdge(edge);
+        }
+        virtual void erase(const std::vector<Edge>& edges) {
+          for (int i = 0; i < int(edges.size()); ++i) {
+            snapshot.eraseEdge(edges[i]);
+          }
+        }
+        virtual void build() {
+          Edge edge;
+          std::vector<Edge> edges;
+          for (notifier()->first(edge); edge != INVALID;
+               notifier()->next(edge)) {
+            edges.push_back(edge);
+          }
+          for (int i = edges.size() - 1; i >= 0; --i) {
+            snapshot.addEdge(edges[i]);
+          }
+        }
+        virtual void clear() {
+          Edge edge;
+          for (notifier()->first(edge); edge != INVALID;
+               notifier()->next(edge)) {
+            snapshot.eraseEdge(edge);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      ListBpGraph *graph;
+
+      NodeObserverProxy node_observer_proxy;
+      EdgeObserverProxy edge_observer_proxy;
+
+      std::list<Node> added_nodes;
+      std::list<Edge> added_edges;
+
+
+      void addNode(const Node& node) {
+        added_nodes.push_front(node);
+      }
+      void eraseNode(const Node& node) {
+        std::list<Node>::iterator it =
+          std::find(added_nodes.begin(), added_nodes.end(), node);
+        if (it == added_nodes.end()) {
+          clear();
+          edge_observer_proxy.detach();
+          throw NodeNotifier::ImmediateDetach();
+        } else {
+          added_nodes.erase(it);
+        }
+      }
+
+      void addEdge(const Edge& edge) {
+        added_edges.push_front(edge);
+      }
+      void eraseEdge(const Edge& edge) {
+        std::list<Edge>::iterator it =
+          std::find(added_edges.begin(), added_edges.end(), edge);
+        if (it == added_edges.end()) {
+          clear();
+          node_observer_proxy.detach();
+          throw EdgeNotifier::ImmediateDetach();
+        } else {
+          added_edges.erase(it);
+        }
+      }
+
+      void attach(ListBpGraph &_graph) {
+        graph = &_graph;
+        node_observer_proxy.attach(graph->notifier(Node()));
+        edge_observer_proxy.attach(graph->notifier(Edge()));
+      }
+
+      void detach() {
+        node_observer_proxy.detach();
+        edge_observer_proxy.detach();
+      }
+
+      bool attached() const {
+        return node_observer_proxy.attached();
+      }
+
+      void clear() {
+        added_nodes.clear();
+        added_edges.clear();
+      }
+
+    public:
+
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// You have to call save() to actually make a snapshot.
+      Snapshot()
+        : graph(0), node_observer_proxy(*this),
+          edge_observer_proxy(*this) {}
+
+      /// \brief Constructor that immediately makes a snapshot.
+      ///
+      /// This constructor immediately makes a snapshot of the given graph.
+      Snapshot(ListBpGraph &gr)
+        : node_observer_proxy(*this),
+          edge_observer_proxy(*this) {
+        attach(gr);
+      }
+
+      /// \brief Make a snapshot.
+      ///
+      /// This function makes a snapshot of the given graph.
+      /// It can be called more than once. In case of a repeated
+      /// call, the previous snapshot gets lost.
+      void save(ListBpGraph &gr) {
+        if (attached()) {
+          detach();
+          clear();
+        }
+        attach(gr);
+      }
+
+      /// \brief Undo the changes until the last snapshot.
+      ///
+      /// This function undos the changes until the last snapshot
+      /// created by save() or Snapshot(ListBpGraph&).
+      ///
+      /// \warning This method invalidates the snapshot, i.e. repeated
+      /// restoring is not supported unless you call save() again.
+      void restore() {
+        detach();
+        for(std::list<Edge>::iterator it = added_edges.begin();
+            it != added_edges.end(); ++it) {
+          graph->erase(*it);
+        }
+        for(std::list<Node>::iterator it = added_nodes.begin();
+            it != added_nodes.end(); ++it) {
+          graph->erase(*it);
+        }
+        clear();
+      }
+
+      /// \brief Returns \c true if the snapshot is valid.
+      ///
+      /// This function returns \c true if the snapshot is valid.
+      bool valid() const {
+        return attached();
+      }
+    };
+  };
+
+  /// @}
 } //namespace lemon
 
Index: lemon/lp.h
===================================================================
--- lemon/lp.h	(revision 956)
+++ lemon/lp.h	(revision 1323)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,12 +23,18 @@
 
 
-#ifdef LEMON_HAVE_GLPK
+#if LEMON_DEFAULT_LP == _LEMON_GLPK || LEMON_DEFAULT_MIP == _LEMON_GLPK
 #include <lemon/glpk.h>
-#elif LEMON_HAVE_CPLEX
+#endif
+#if LEMON_DEFAULT_LP == _LEMON_CPLEX || LEMON_DEFAULT_MIP == _LEMON_CPLEX 
 #include <lemon/cplex.h>
-#elif LEMON_HAVE_SOPLEX
+#endif
+#if LEMON_DEFAULT_LP == _LEMON_SOPLEX
 #include <lemon/soplex.h>
-#elif LEMON_HAVE_CLP
+#endif
+#if LEMON_DEFAULT_LP == _LEMON_CLP
 #include <lemon/clp.h>
+#endif
+#if LEMON_DEFAULT_MIP == _LEMON_CBC
+#include <lemon/cbc.h>
 #endif
 
@@ -44,6 +50,6 @@
   ///\ingroup lp_group
   ///
-  ///Currently, the possible values are \c GLPK, \c CPLEX,
-  ///\c SOPLEX or \c CLP
+  ///Currently, the possible values are \c _LEMON_GLPK, \c LEMON__CPLEX,
+  ///\c _LEMON_SOPLEX or \c LEMON__CLP
 #define LEMON_DEFAULT_LP SOLVER
   ///The default LP solver
@@ -60,5 +66,6 @@
   ///\ingroup lp_group
   ///
-  ///Currently, the possible values are \c GLPK or \c CPLEX
+  ///Currently, the possible values are \c _LEMON_GLPK, \c LEMON__CPLEX
+  ///or \c _LEMON_CBC
 #define LEMON_DEFAULT_MIP SOLVER
   ///The default MIP solver.
@@ -67,23 +74,22 @@
   ///\ingroup lp_group
   ///
-  ///Currently, it is either \c GlpkMip or \c CplexMip
+  ///Currently, it is either \c GlpkMip, \c CplexMip , \c CbcMip
   typedef GlpkMip Mip;
 #else
-#ifdef LEMON_HAVE_GLPK
-# define LEMON_DEFAULT_LP GLPK
+#if LEMON_DEFAULT_LP == _LEMON_GLPK
   typedef GlpkLp Lp;
-# define LEMON_DEFAULT_MIP GLPK
+#elif LEMON_DEFAULT_LP == _LEMON_CPLEX
+  typedef CplexLp Lp;
+#elif LEMON_DEFAULT_LP == _LEMON_SOPLEX
+  typedef SoplexLp Lp;
+#elif LEMON_DEFAULT_LP == _LEMON_CLP
+  typedef ClpLp Lp;
+#endif
+#if LEMON_DEFAULT_MIP == _LEMON_GLPK
   typedef GlpkMip Mip;
-#elif LEMON_HAVE_CPLEX
-# define LEMON_DEFAULT_LP CPLEX
-  typedef CplexLp Lp;
-# define LEMON_DEFAULT_MIP CPLEX
+#elif LEMON_DEFAULT_MIP == _LEMON_CPLEX
   typedef CplexMip Mip;
-#elif LEMON_HAVE_SOPLEX
-# define DEFAULT_LP SOPLEX
-  typedef SoplexLp Lp;
-#elif LEMON_HAVE_CLP
-# define DEFAULT_LP CLP
-  typedef ClpLp Lp;
+#elif LEMON_DEFAULT_MIP == _LEMON_CBC
+  typedef CbcMip Mip;
 #endif
 #endif
Index: lemon/lp_base.cc
===================================================================
--- lemon/lp_base.cc	(revision 956)
+++ lemon/lp_base.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/lp_base.h
===================================================================
--- lemon/lp_base.h	(revision 1161)
+++ lemon/lp_base.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -1008,4 +1008,34 @@
   public:
 
+    ///Unsupported file format exception
+    class UnsupportedFormatError : public Exception
+    {
+      std::string _format;
+      mutable std::string _what;
+    public:
+      explicit UnsupportedFormatError(std::string format) throw()
+        : _format(format) { }
+      virtual ~UnsupportedFormatError() throw() {}
+      virtual const char* what() const throw() {
+        try {
+          _what.clear();
+          std::ostringstream oss;
+          oss << "lemon::UnsupportedFormatError: " << _format;
+          _what = oss.str();
+        }
+        catch (...) {}
+        if (!_what.empty()) return _what.c_str();
+        else return "lemon::UnsupportedFormatError";
+      }
+    };
+
+  protected:
+    virtual void _write(std::string, std::string format) const
+    {
+      throw UnsupportedFormatError(format);
+    }
+
+  public:
+
     /// Virtual destructor
     virtual ~LpBase() {}
@@ -1556,9 +1586,24 @@
     void min() { _setSense(MIN); }
 
-    ///Clears the problem
+    ///Clear the problem
     void clear() { _clear(); rows.clear(); cols.clear(); }
 
-    /// Sets the message level of the solver
+    /// Set the message level of the solver
     void messageLevel(MessageLevel level) { _messageLevel(level); }
+
+    /// Write the problem to a file in the given format
+
+    /// This function writes the problem to a file in the given format.
+    /// Different solver backends may support different formats.
+    /// Trying to write in an unsupported format will trigger
+    /// \ref UnsupportedFormatError. For the supported formats,
+    /// visit the documentation of the base class of the related backends
+    /// (\ref CplexBase, \ref GlpkBase etc.)
+    /// \param file The file path
+    /// \param format The output file format.
+    void write(std::string file, std::string format = "MPS") const
+    {
+      _write(file.c_str(),format.c_str());
+    }
 
     ///@}
Index: lemon/lp_skeleton.cc
===================================================================
--- lemon/lp_skeleton.cc	(revision 956)
+++ lemon/lp_skeleton.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -92,4 +92,6 @@
   void SkeletonSolverBase::_messageLevel(MessageLevel) {}
 
+  void SkeletonSolverBase::_write(std::string, std::string) const {}
+
   LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
 
Index: lemon/lp_skeleton.h
===================================================================
--- lemon/lp_skeleton.h	(revision 956)
+++ lemon/lp_skeleton.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -145,4 +145,8 @@
     ///\e
     virtual void _messageLevel(MessageLevel);
+
+    ///\e
+    virtual void _write(std::string file, std::string format) const;
+
   };
 
@@ -223,4 +227,5 @@
     ///\e
     virtual const char* _solverName() const;
+
   };
 
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 1084)
+++ lemon/maps.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/matching.h
===================================================================
--- lemon/matching.h	(revision 956)
+++ lemon/matching.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/math.h
===================================================================
--- lemon/math.h	(revision 956)
+++ lemon/math.h	(revision 1311)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -66,7 +66,12 @@
     }
 
+  ///Round a value to its closest integer
+  inline double round(double r) {
+    return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5);
+  }
+
   /// @}
 
 } //namespace lemon
 
-#endif //LEMON_TOLERANCE_H
+#endif //LEMON_MATH_H
Index: lemon/max_cardinality_search.h
===================================================================
--- lemon/max_cardinality_search.h	(revision 1271)
+++ lemon/max_cardinality_search.h	(revision 1271)
@@ -0,0 +1,794 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_MAX_CARDINALITY_SEARCH_H
+#define LEMON_MAX_CARDINALITY_SEARCH_H
+
+
+/// \ingroup search
+/// \file
+/// \brief Maximum cardinality search in undirected digraphs.
+
+#include <lemon/bin_heap.h>
+#include <lemon/bucket_heap.h>
+
+#include <lemon/error.h>
+#include <lemon/maps.h>
+
+#include <functional>
+
+namespace lemon {
+
+  /// \brief Default traits class of MaxCardinalitySearch class.
+  ///
+  /// Default traits class of MaxCardinalitySearch class.
+  /// \param Digraph Digraph type.
+  /// \param CapacityMap Type of capacity map.
+  template <typename GR, typename CAP>
+  struct MaxCardinalitySearchDefaultTraits {
+    /// The digraph type the algorithm runs on.
+    typedef GR Digraph;
+
+    template <typename CM>
+    struct CapMapSelector {
+
+      typedef CM CapacityMap;
+
+      static CapacityMap *createCapacityMap(const Digraph& g) {
+        return new CapacityMap(g);
+      }
+    };
+
+    template <typename CM>
+    struct CapMapSelector<ConstMap<CM, Const<int, 1> > > {
+
+      typedef ConstMap<CM, Const<int, 1> > CapacityMap;
+
+      static CapacityMap *createCapacityMap(const Digraph&) {
+        return new CapacityMap;
+      }
+    };
+
+    /// \brief The type of the map that stores the arc capacities.
+    ///
+    /// The type of the map that stores the arc capacities.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef typename CapMapSelector<CAP>::CapacityMap CapacityMap;
+
+    /// \brief The type of the capacity of the arcs.
+    typedef typename CapacityMap::Value Value;
+
+    /// \brief Instantiates a CapacityMap.
+    ///
+    /// This function instantiates a \ref CapacityMap.
+    /// \param digraph is the digraph, to which we would like to define
+    /// the CapacityMap.
+    static CapacityMap *createCapacityMap(const Digraph& digraph) {
+      return CapMapSelector<CapacityMap>::createCapacityMap(digraph);
+    }
+
+    /// \brief The cross reference type used by heap.
+    ///
+    /// The cross reference type used by heap.
+    /// Usually it is \c Digraph::NodeMap<int>.
+    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
+
+    /// \brief Instantiates a HeapCrossRef.
+    ///
+    /// This function instantiates a \ref HeapCrossRef.
+    /// \param digraph is the digraph, to which we would like to define the
+    /// HeapCrossRef.
+    static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
+      return new HeapCrossRef(digraph);
+    }
+
+    template <typename CapacityMap>
+    struct HeapSelector {
+      template <typename Value, typename Ref>
+      struct Selector {
+        typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
+      };
+    };
+
+    template <typename CapacityKey>
+    struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
+      template <typename Value, typename Ref>
+      struct Selector {
+        typedef BucketHeap<Ref, false > Heap;
+      };
+    };
+
+    /// \brief The heap type used by MaxCardinalitySearch algorithm.
+    ///
+    /// The heap type used by MaxCardinalitySearch algorithm. It should
+    /// maximalize the priorities. The default heap type is
+    /// the \ref BinHeap, but it is specialized when the
+    /// CapacityMap is ConstMap<Digraph::Node, Const<int, 1> >
+    /// to BucketHeap.
+    ///
+    /// \sa MaxCardinalitySearch
+    typedef typename HeapSelector<CapacityMap>
+    ::template Selector<Value, HeapCrossRef>
+    ::Heap Heap;
+
+    /// \brief Instantiates a Heap.
+    ///
+    /// This function instantiates a \ref Heap.
+    /// \param crossref The cross reference of the heap.
+    static Heap *createHeap(HeapCrossRef& crossref) {
+      return new Heap(crossref);
+    }
+
+    /// \brief The type of the map that stores whether a node is processed.
+    ///
+    /// The type of the map that stores whether a node is processed.
+    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    /// By default it is a NullMap.
+    typedef NullMap<typename Digraph::Node, bool> ProcessedMap;
+
+    /// \brief Instantiates a ProcessedMap.
+    ///
+    /// This function instantiates a \ref ProcessedMap.
+    /// \param digraph is the digraph, to which
+    /// we would like to define the \ref ProcessedMap
+#ifdef DOXYGEN
+    static ProcessedMap *createProcessedMap(const Digraph &digraph)
+#else
+    static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+    {
+      return new ProcessedMap();
+    }
+
+    /// \brief The type of the map that stores the cardinalities of the nodes.
+    ///
+    /// The type of the map that stores the cardinalities of the nodes.
+    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename Digraph::template NodeMap<Value> CardinalityMap;
+
+    /// \brief Instantiates a CardinalityMap.
+    ///
+    /// This function instantiates a \ref CardinalityMap.
+    /// \param digraph is the digraph, to which we would like to
+    /// define the \ref CardinalityMap
+    static CardinalityMap *createCardinalityMap(const Digraph &digraph) {
+      return new CardinalityMap(digraph);
+    }
+
+
+  };
+
+  /// \ingroup search
+  ///
+  /// \brief Maximum Cardinality Search algorithm class.
+  ///
+  /// This class provides an efficient implementation of Maximum Cardinality
+  /// Search algorithm. The maximum cardinality search first chooses any
+  /// node of the digraph. Then every time it chooses one unprocessed node
+  /// with maximum cardinality, i.e the sum of capacities on out arcs
+  /// to the nodes
+  /// which were previusly processed.
+  /// If there is a cut in the digraph the algorithm should choose
+  /// again any unprocessed node of the digraph.
+
+  /// The arc capacities are passed to the algorithm using a
+  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
+  /// kind of capacity.
+  ///
+  /// The type of the capacity is determined by the \ref
+  /// concepts::ReadMap::Value "Value" of the capacity map.
+  ///
+  /// It is also possible to change the underlying priority heap.
+  ///
+  ///
+  /// \param GR The digraph type the algorithm runs on. The value of
+  /// Digraph is not used directly by the search algorithm, it
+  /// is only passed to \ref MaxCardinalitySearchDefaultTraits.
+  /// \param CAP This read-only ArcMap determines the capacities of
+  /// the arcs. It is read once for each arc, so the map may involve in
+  /// relatively time consuming process to compute the arc capacity if
+  /// it is necessary. The default map type is \ref
+  /// ConstMap "ConstMap<concepts::Digraph::Arc, Const<int,1> >". The value
+  /// of CapacityMap is not used directly by search algorithm, it is only
+  /// passed to \ref MaxCardinalitySearchDefaultTraits.
+  /// \param TR Traits class to set various data types used by the
+  /// algorithm.  The default traits class is
+  /// \ref MaxCardinalitySearchDefaultTraits
+  /// "MaxCardinalitySearchDefaultTraits<GR, CAP>".
+  /// See \ref MaxCardinalitySearchDefaultTraits
+  /// for the documentation of a MaxCardinalitySearch traits class.
+
+#ifdef DOXYGEN
+  template <typename GR, typename CAP, typename TR>
+#else
+  template <typename GR, typename CAP =
+            ConstMap<typename GR::Arc, Const<int,1> >,
+            typename TR =
+            MaxCardinalitySearchDefaultTraits<GR, CAP> >
+#endif
+  class MaxCardinalitySearch {
+  public:
+
+    typedef TR Traits;
+    ///The type of the underlying digraph.
+    typedef typename Traits::Digraph Digraph;
+
+    ///The type of the capacity of the arcs.
+    typedef typename Traits::CapacityMap::Value Value;
+    ///The type of the map that stores the arc capacities.
+    typedef typename Traits::CapacityMap CapacityMap;
+    ///The type of the map indicating if a node is processed.
+    typedef typename Traits::ProcessedMap ProcessedMap;
+    ///The type of the map that stores the cardinalities of the nodes.
+    typedef typename Traits::CardinalityMap CardinalityMap;
+    ///The cross reference type used for the current heap.
+    typedef typename Traits::HeapCrossRef HeapCrossRef;
+    ///The heap type used by the algorithm. It maximizes the priorities.
+    typedef typename Traits::Heap Heap;
+  private:
+    // Pointer to the underlying digraph.
+    const Digraph *_graph;
+    // Pointer to the capacity map
+    const CapacityMap *_capacity;
+    // Indicates if \ref _capacity is locally allocated (\c true) or not.
+    bool local_capacity;
+    // Pointer to the map of cardinality.
+    CardinalityMap *_cardinality;
+    // Indicates if \ref _cardinality is locally allocated (\c true) or not.
+    bool local_cardinality;
+    // Pointer to the map of processed status of the nodes.
+    ProcessedMap *_processed;
+    // Indicates if \ref _processed is locally allocated (\c true) or not.
+    bool local_processed;
+    // Pointer to the heap cross references.
+    HeapCrossRef *_heap_cross_ref;
+    // Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
+    bool local_heap_cross_ref;
+    // Pointer to the heap.
+    Heap *_heap;
+    // Indicates if \ref _heap is locally allocated (\c true) or not.
+    bool local_heap;
+
+  public :
+
+    typedef MaxCardinalitySearch Create;
+
+    ///\name Named template parameters
+
+    ///@{
+
+    template <class T>
+    struct DefCapacityMapTraits : public Traits {
+      typedef T CapacityMap;
+      static CapacityMap *createCapacityMap(const Digraph &) {
+               LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// CapacityMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting CapacityMap type
+    /// for the algorithm.
+    template <class T>
+    struct SetCapacityMap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefCapacityMapTraits<T> > {
+      typedef MaxCardinalitySearch<Digraph, CapacityMap,
+                                   DefCapacityMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct DefCardinalityMapTraits : public Traits {
+      typedef T CardinalityMap;
+      static CardinalityMap *createCardinalityMap(const Digraph &)
+      {
+        LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// CardinalityMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting CardinalityMap
+    /// type for the algorithm.
+    template <class T>
+    struct SetCardinalityMap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefCardinalityMapTraits<T> > {
+      typedef MaxCardinalitySearch<Digraph, CapacityMap,
+                                   DefCardinalityMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct DefProcessedMapTraits : public Traits {
+      typedef T ProcessedMap;
+      static ProcessedMap *createProcessedMap(const Digraph &) {
+               LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// ProcessedMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
+    /// for the algorithm.
+    template <class T>
+    struct SetProcessedMap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefProcessedMapTraits<T> > {
+      typedef MaxCardinalitySearch<Digraph, CapacityMap,
+                                   DefProcessedMapTraits<T> > Create;
+    };
+
+    template <class H, class CR>
+    struct DefHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
+             LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+      static Heap *createHeap(HeapCrossRef &) {
+               LEMON_ASSERT(false,"Uninitialized parameter.");
+        return 0;
+      }
+    };
+    /// \brief \ref named-templ-param "Named parameter" for setting heap
+    /// and cross reference type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting heap and cross
+    /// reference type for the algorithm.
+    template <class H, class CR = typename Digraph::template NodeMap<int> >
+    struct SetHeap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefHeapTraits<H, CR> > {
+      typedef MaxCardinalitySearch< Digraph, CapacityMap,
+                                    DefHeapTraits<H, CR> > Create;
+    };
+
+    template <class H, class CR>
+    struct DefStandardHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
+        return new HeapCrossRef(digraph);
+      }
+      static Heap *createHeap(HeapCrossRef &crossref) {
+        return new Heap(crossref);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting heap and
+    /// cross reference type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting heap and cross
+    /// reference type. It can allocate the heap and the cross reference
+    /// object if the cross reference's constructor waits for the digraph as
+    /// parameter and the heap's constructor waits for the cross reference.
+    template <class H, class CR = typename Digraph::template NodeMap<int> >
+    struct SetStandardHeap
+      : public MaxCardinalitySearch<Digraph, CapacityMap,
+                                    DefStandardHeapTraits<H, CR> > {
+      typedef MaxCardinalitySearch<Digraph, CapacityMap,
+                                   DefStandardHeapTraits<H, CR> >
+      Create;
+    };
+
+    ///@}
+
+
+  protected:
+
+    MaxCardinalitySearch() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    ///\param digraph the digraph the algorithm will run on.
+    ///\param capacity the capacity map used by the algorithm.
+    MaxCardinalitySearch(const Digraph& digraph,
+                         const CapacityMap& capacity) :
+      _graph(&digraph),
+      _capacity(&capacity), local_capacity(false),
+      _cardinality(0), local_cardinality(false),
+      _processed(0), local_processed(false),
+      _heap_cross_ref(0), local_heap_cross_ref(false),
+      _heap(0), local_heap(false)
+    { }
+
+    /// \brief Constructor.
+    ///
+    ///\param digraph the digraph the algorithm will run on.
+    ///
+    ///A constant 1 capacity map will be allocated.
+    MaxCardinalitySearch(const Digraph& digraph) :
+      _graph(&digraph),
+      _capacity(0), local_capacity(false),
+      _cardinality(0), local_cardinality(false),
+      _processed(0), local_processed(false),
+      _heap_cross_ref(0), local_heap_cross_ref(false),
+      _heap(0), local_heap(false)
+    { }
+
+    /// \brief Destructor.
+    ~MaxCardinalitySearch() {
+      if(local_capacity) delete _capacity;
+      if(local_cardinality) delete _cardinality;
+      if(local_processed) delete _processed;
+      if(local_heap_cross_ref) delete _heap_cross_ref;
+      if(local_heap) delete _heap;
+    }
+
+    /// \brief Sets the capacity map.
+    ///
+    /// Sets the capacity map.
+    /// \return <tt> (*this) </tt>
+    MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
+      if (local_capacity) {
+        delete _capacity;
+        local_capacity=false;
+      }
+      _capacity=&m;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the capacity map.
+    ///
+    /// Returns a const reference to the capacity map used by
+    /// the algorithm.
+    const CapacityMap &capacityMap() const {
+      return *_capacity;
+    }
+
+    /// \brief Sets the map storing the cardinalities calculated by the
+    /// algorithm.
+    ///
+    /// Sets the map storing the cardinalities calculated by the algorithm.
+    /// If you don't use this function before calling \ref run(),
+    /// it will allocate one. The destuctor deallocates this
+    /// automatically allocated map, of course.
+    /// \return <tt> (*this) </tt>
+    MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
+      if(local_cardinality) {
+        delete _cardinality;
+        local_cardinality=false;
+      }
+      _cardinality = &m;
+      return *this;
+    }
+
+    /// \brief Sets the map storing the processed nodes.
+    ///
+    /// Sets the map storing the processed nodes.
+    /// If you don't use this function before calling \ref run(),
+    /// it will allocate one. The destuctor deallocates this
+    /// automatically allocated map, of course.
+    /// \return <tt> (*this) </tt>
+    MaxCardinalitySearch &processedMap(ProcessedMap &m)
+    {
+      if(local_processed) {
+        delete _processed;
+        local_processed=false;
+      }
+      _processed = &m;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the cardinality map.
+    ///
+    /// Returns a const reference to the cardinality map used by
+    /// the algorithm.
+    const ProcessedMap &processedMap() const {
+      return *_processed;
+    }
+
+    /// \brief Sets the heap and the cross reference used by algorithm.
+    ///
+    /// Sets the heap and the cross reference used by algorithm.
+    /// If you don't use this function before calling \ref run(),
+    /// it will allocate one. The destuctor deallocates this
+    /// automatically allocated map, of course.
+    /// \return <tt> (*this) </tt>
+    MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) {
+      if(local_heap_cross_ref) {
+        delete _heap_cross_ref;
+        local_heap_cross_ref = false;
+      }
+      _heap_cross_ref = &cr;
+      if(local_heap) {
+        delete _heap;
+        local_heap = false;
+      }
+      _heap = &hp;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the heap.
+    ///
+    /// Returns a const reference to the heap used by
+    /// the algorithm.
+    const Heap &heap() const {
+      return *_heap;
+    }
+
+    /// \brief Returns a const reference to the cross reference.
+    ///
+    /// Returns a const reference to the cross reference
+    /// of the heap.
+    const HeapCrossRef &heapCrossRef() const {
+      return *_heap_cross_ref;
+    }
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::InArcIt InArcIt;
+
+    void create_maps() {
+      if(!_capacity) {
+        local_capacity = true;
+        _capacity = Traits::createCapacityMap(*_graph);
+      }
+      if(!_cardinality) {
+        local_cardinality = true;
+        _cardinality = Traits::createCardinalityMap(*_graph);
+      }
+      if(!_processed) {
+        local_processed = true;
+        _processed = Traits::createProcessedMap(*_graph);
+      }
+      if (!_heap_cross_ref) {
+        local_heap_cross_ref = true;
+        _heap_cross_ref = Traits::createHeapCrossRef(*_graph);
+      }
+      if (!_heap) {
+        local_heap = true;
+        _heap = Traits::createHeap(*_heap_cross_ref);
+      }
+    }
+
+    void finalizeNodeData(Node node, Value capacity) {
+      _processed->set(node, true);
+      _cardinality->set(node, capacity);
+    }
+
+  public:
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use
+    /// one of the member functions called \ref run().
+    /// \n
+    /// If you need more control on the execution,
+    /// first you must call \ref init(), then you can add several source nodes
+    /// with \ref addSource().
+    /// Finally \ref start() will perform the computation.
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures, and clears the heap.
+    void init() {
+      create_maps();
+      _heap->clear();
+      for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
+        _processed->set(it, false);
+        _heap_cross_ref->set(it, Heap::PRE_HEAP);
+      }
+    }
+
+    /// \brief Adds a new source node.
+    ///
+    /// Adds a new source node to the priority heap.
+    ///
+    /// It checks if the node has not yet been added to the heap.
+    void addSource(Node source, Value capacity = 0) {
+      if(_heap->state(source) == Heap::PRE_HEAP) {
+        _heap->push(source, capacity);
+      }
+    }
+
+    /// \brief Processes the next node in the priority heap
+    ///
+    /// Processes the next node in the priority heap.
+    ///
+    /// \return The processed node.
+    ///
+    /// \warning The priority heap must not be empty!
+    Node processNextNode() {
+      Node node = _heap->top();
+      finalizeNodeData(node, _heap->prio());
+      _heap->pop();
+
+      for (InArcIt it(*_graph, node); it != INVALID; ++it) {
+        Node source = _graph->source(it);
+        switch (_heap->state(source)) {
+        case Heap::PRE_HEAP:
+          _heap->push(source, (*_capacity)[it]);
+          break;
+        case Heap::IN_HEAP:
+          _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]);
+          break;
+        case Heap::POST_HEAP:
+          break;
+        }
+      }
+      return node;
+    }
+
+    /// \brief Next node to be processed.
+    ///
+    /// Next node to be processed.
+    ///
+    /// \return The next node to be processed or INVALID if the
+    /// priority heap is empty.
+    Node nextNode() {
+      return !_heap->empty() ? _heap->top() : INVALID;
+    }
+
+    /// \brief Returns \c false if there are nodes
+    /// to be processed in the priority heap
+    ///
+    /// Returns \c false if there are nodes
+    /// to be processed in the priority heap
+    bool emptyQueue() { return _heap->empty(); }
+    /// \brief Returns the number of the nodes to be processed
+    /// in the priority heap
+    ///
+    /// Returns the number of the nodes to be processed in the priority heap
+    int emptySize() { return _heap->size(); }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    ///\pre init() must be called and at least one node should be added
+    /// with addSource() before using this function.
+    ///
+    /// This method runs the Maximum Cardinality Search algorithm from the
+    /// source node(s).
+    void start() {
+      while ( !_heap->empty() ) processNextNode();
+    }
+
+    /// \brief Executes the algorithm until \c dest is reached.
+    ///
+    /// Executes the algorithm until \c dest is reached.
+    ///
+    /// \pre init() must be called and at least one node should be added
+    /// with addSource() before using this function.
+    ///
+    /// This method runs the %MaxCardinalitySearch algorithm from the source
+    /// nodes.
+    void start(Node dest) {
+      while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
+      if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
+    }
+
+    /// \brief Executes the algorithm until a condition is met.
+    ///
+    /// Executes the algorithm until a condition is met.
+    ///
+    /// \pre init() must be called and at least one node should be added
+    /// with addSource() before using this function.
+    ///
+    /// \param nm must be a bool (or convertible) node map. The algorithm
+    /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
+    template <typename NodeBoolMap>
+    void start(const NodeBoolMap &nm) {
+      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
+      if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
+    }
+
+    /// \brief Runs the maximum cardinality search algorithm from node \c s.
+    ///
+    /// This method runs the %MaxCardinalitySearch algorithm from a root
+    /// node \c s.
+    ///
+    ///\note d.run(s) is just a shortcut of the following code.
+    ///\code
+    ///  d.init();
+    ///  d.addSource(s);
+    ///  d.start();
+    ///\endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    /// \brief Runs the maximum cardinality search algorithm for the
+    /// whole digraph.
+    ///
+    /// This method runs the %MaxCardinalitySearch algorithm from all
+    /// unprocessed node of the digraph.
+    ///
+    ///\note d.run(s) is just a shortcut of the following code.
+    ///\code
+    ///  d.init();
+    ///  for (NodeIt it(digraph); it != INVALID; ++it) {
+    ///    if (!d.reached(it)) {
+    ///      d.addSource(s);
+    ///      d.start();
+    ///    }
+    ///  }
+    ///\endcode
+    void run() {
+      init();
+      for (NodeIt it(*_graph); it != INVALID; ++it) {
+        if (!reached(it)) {
+          addSource(it);
+          start();
+        }
+      }
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    /// The results of the maximum cardinality search algorithm can be
+    /// obtained using these functions.
+    /// \n
+    /// Before the use of these functions, either run() or start() must be
+    /// called.
+
+    ///@{
+
+    /// \brief The cardinality of a node.
+    ///
+    /// Returns the cardinality of a node.
+    /// \pre \ref run() must be called before using this function.
+    /// \warning If node \c v in unreachable from the root the return value
+    /// of this funcion is undefined.
+    Value cardinality(Node node) const { return (*_cardinality)[node]; }
+
+    /// \brief The current cardinality of a node.
+    ///
+    /// Returns the current cardinality of a node.
+    /// \pre the given node should be reached but not processed
+    Value currentCardinality(Node node) const { return (*_heap)[node]; }
+
+    /// \brief Returns a reference to the NodeMap of cardinalities.
+    ///
+    /// Returns a reference to the NodeMap of cardinalities. \pre \ref run()
+    /// must be called before using this function.
+    const CardinalityMap &cardinalityMap() const { return *_cardinality;}
+
+    /// \brief Checks if a node is reachable from the root.
+    ///
+    /// Returns \c true if \c v is reachable from the root.
+    /// \warning The source nodes are initated as unreached.
+    /// \pre \ref run() must be called before using this function.
+    bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
+
+    /// \brief Checks if a node is processed.
+    ///
+    /// Returns \c true if \c v is processed, i.e. the shortest
+    /// path to \c v has already found.
+    /// \pre \ref run() must be called before using this function.
+    bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }
+
+    ///@}
+  };
+
+}
+
+#endif
Index: lemon/min_cost_arborescence.h
===================================================================
--- lemon/min_cost_arborescence.h	(revision 956)
+++ lemon/min_cost_arborescence.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -102,5 +102,5 @@
   /// the minimum cost subgraph that is the union of arborescences with the
   /// given sources and spans all the nodes which are reachable from the
-  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
+  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+m).
   ///
   /// The algorithm also provides an optimal dual solution, therefore
@@ -129,5 +129,5 @@
   public:
 
-    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
+    /// \brief The \ref lemon::MinCostArborescenceDefaultTraits "traits class"
     /// of the algorithm.
     typedef TR Traits;
Index: lemon/nagamochi_ibaraki.h
===================================================================
--- lemon/nagamochi_ibaraki.h	(revision 1270)
+++ lemon/nagamochi_ibaraki.h	(revision 1270)
@@ -0,0 +1,702 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_NAGAMOCHI_IBARAKI_H
+#define LEMON_NAGAMOCHI_IBARAKI_H
+
+
+/// \ingroup min_cut
+/// \file
+/// \brief Implementation of the Nagamochi-Ibaraki algorithm.
+
+#include <lemon/core.h>
+#include <lemon/bin_heap.h>
+#include <lemon/bucket_heap.h>
+#include <lemon/maps.h>
+#include <lemon/radix_sort.h>
+#include <lemon/unionfind.h>
+
+#include <cassert>
+
+namespace lemon {
+
+  /// \brief Default traits class for NagamochiIbaraki class.
+  ///
+  /// Default traits class for NagamochiIbaraki class.
+  /// \param GR The undirected graph type.
+  /// \param CM Type of capacity map.
+  template <typename GR, typename CM>
+  struct NagamochiIbarakiDefaultTraits {
+    /// The type of the capacity map.
+    typedef typename CM::Value Value;
+
+    /// The undirected graph type the algorithm runs on.
+    typedef GR Graph;
+
+    /// \brief The type of the map that stores the edge capacities.
+    ///
+    /// The type of the map that stores the edge capacities.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef CM CapacityMap;
+
+    /// \brief Instantiates a CapacityMap.
+    ///
+    /// This function instantiates a \ref CapacityMap.
+#ifdef DOXYGEN
+    static CapacityMap *createCapacityMap(const Graph& graph)
+#else
+    static CapacityMap *createCapacityMap(const Graph&)
+#endif
+    {
+        LEMON_ASSERT(false, "CapacityMap is not initialized");
+        return 0; // ignore warnings
+    }
+
+    /// \brief The cross reference type used by heap.
+    ///
+    /// The cross reference type used by heap.
+    /// Usually \c Graph::NodeMap<int>.
+    typedef typename Graph::template NodeMap<int> HeapCrossRef;
+
+    /// \brief Instantiates a HeapCrossRef.
+    ///
+    /// This function instantiates a \ref HeapCrossRef.
+    /// \param g is the graph, to which we would like to define the
+    /// \ref HeapCrossRef.
+    static HeapCrossRef *createHeapCrossRef(const Graph& g) {
+      return new HeapCrossRef(g);
+    }
+
+    /// \brief The heap type used by NagamochiIbaraki algorithm.
+    ///
+    /// The heap type used by NagamochiIbaraki algorithm. It has to
+    /// maximize the priorities.
+    ///
+    /// \sa BinHeap
+    /// \sa NagamochiIbaraki
+    typedef BinHeap<Value, HeapCrossRef, std::greater<Value> > Heap;
+
+    /// \brief Instantiates a Heap.
+    ///
+    /// This function instantiates a \ref Heap.
+    /// \param r is the cross reference of the heap.
+    static Heap *createHeap(HeapCrossRef& r) {
+      return new Heap(r);
+    }
+  };
+
+  /// \ingroup min_cut
+  ///
+  /// \brief Calculates the minimum cut in an undirected graph.
+  ///
+  /// Calculates the minimum cut in an undirected graph with the
+  /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
+  /// nodes into two partitions with the minimum sum of edge capacities
+  /// between the two partitions. The algorithm can be used to test
+  /// the network reliability, especially to test how many links have
+  /// to be destroyed in the network to split it to at least two
+  /// distinict subnetworks.
+  ///
+  /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
+  /// \ref FibHeap "Fibonacci heap" it can be decreased to
+  /// \f$ O(nm+n^2\log(n)) \f$.  When the edges have unit capacities,
+  /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
+  /// complexity.
+  ///
+  /// \warning The value type of the capacity map should be able to
+  /// hold any cut value of the graph, otherwise the result can
+  /// overflow.
+  /// \note This capacity is supposed to be integer type.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template <typename GR,
+            typename CM = typename GR::template EdgeMap<int>,
+            typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
+#endif
+  class NagamochiIbaraki {
+  public:
+
+    typedef TR Traits;
+    /// The type of the underlying graph.
+    typedef typename Traits::Graph Graph;
+
+    /// The type of the capacity map.
+    typedef typename Traits::CapacityMap CapacityMap;
+    /// The value type of the capacity map.
+    typedef typename Traits::CapacityMap::Value Value;
+
+    /// The heap type used by the algorithm.
+    typedef typename Traits::Heap Heap;
+    /// The cross reference type used for the heap.
+    typedef typename Traits::HeapCrossRef HeapCrossRef;
+
+    ///\name Named template parameters
+
+    ///@{
+
+    struct SetUnitCapacityTraits : public Traits {
+      typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
+      static CapacityMap *createCapacityMap(const Graph&) {
+        return new CapacityMap();
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// the capacity map to a constMap<Edge, int, 1>() instance
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// the capacity map to a constMap<Edge, int, 1>() instance
+    struct SetUnitCapacity
+      : public NagamochiIbaraki<Graph, CapacityMap,
+                                SetUnitCapacityTraits> {
+      typedef NagamochiIbaraki<Graph, CapacityMap,
+                               SetUnitCapacityTraits> Create;
+    };
+
+
+    template <class H, class CR>
+    struct SetHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(int num) {
+        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
+        return 0; // ignore warnings
+      }
+      static Heap *createHeap(HeapCrossRef &) {
+        LEMON_ASSERT(false, "Heap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// heap and cross reference type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting heap and
+    /// cross reference type. The heap has to maximize the priorities.
+    template <class H, class CR = RangeMap<int> >
+    struct SetHeap
+      : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
+      typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
+      Create;
+    };
+
+    template <class H, class CR>
+    struct SetStandardHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(int size) {
+        return new HeapCrossRef(size);
+      }
+      static Heap *createHeap(HeapCrossRef &crossref) {
+        return new Heap(crossref);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// heap and cross reference type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting heap and
+    /// cross reference type with automatic allocation. They should
+    /// have standard constructor interfaces to be able to
+    /// automatically created by the algorithm (i.e. the graph should
+    /// be passed to the constructor of the cross reference and the
+    /// cross reference should be passed to the constructor of the
+    /// heap). However, external heap and cross reference objects
+    /// could also be passed to the algorithm using the \ref heap()
+    /// function before calling \ref run() or \ref init(). The heap
+    /// has to maximize the priorities.
+    /// \sa SetHeap
+    template <class H, class CR = RangeMap<int> >
+    struct SetStandardHeap
+      : public NagamochiIbaraki<Graph, CapacityMap,
+                                SetStandardHeapTraits<H, CR> > {
+      typedef NagamochiIbaraki<Graph, CapacityMap,
+                               SetStandardHeapTraits<H, CR> > Create;
+    };
+
+    ///@}
+
+
+  private:
+
+    const Graph &_graph;
+    const CapacityMap *_capacity;
+    bool _local_capacity; // unit capacity
+
+    struct ArcData {
+      typename Graph::Node target;
+      int prev, next;
+    };
+    struct EdgeData {
+      Value capacity;
+      Value cut;
+    };
+
+    struct NodeData {
+      int first_arc;
+      typename Graph::Node prev, next;
+      int curr_arc;
+      typename Graph::Node last_rep;
+      Value sum;
+    };
+
+    typename Graph::template NodeMap<NodeData> *_nodes;
+    std::vector<ArcData> _arcs;
+    std::vector<EdgeData> _edges;
+
+    typename Graph::Node _first_node;
+    int _node_num;
+
+    Value _min_cut;
+
+    HeapCrossRef *_heap_cross_ref;
+    bool _local_heap_cross_ref;
+    Heap *_heap;
+    bool _local_heap;
+
+    typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
+    NodeList *_next_rep;
+
+    typedef typename Graph::template NodeMap<bool> MinCutMap;
+    MinCutMap *_cut_map;
+
+    void createStructures() {
+      if (!_nodes) {
+        _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
+      }
+      if (!_capacity) {
+        _local_capacity = true;
+        _capacity = Traits::createCapacityMap(_graph);
+      }
+      if (!_heap_cross_ref) {
+        _local_heap_cross_ref = true;
+        _heap_cross_ref = Traits::createHeapCrossRef(_graph);
+      }
+      if (!_heap) {
+        _local_heap = true;
+        _heap = Traits::createHeap(*_heap_cross_ref);
+      }
+      if (!_next_rep) {
+        _next_rep = new NodeList(_graph);
+      }
+      if (!_cut_map) {
+        _cut_map = new MinCutMap(_graph);
+      }
+    }
+
+  protected:
+    //This is here to avoid a gcc-3.3 compilation error.
+    //It should never be called.
+    NagamochiIbaraki() {}
+
+  public:
+
+    typedef NagamochiIbaraki Create;
+
+
+    /// \brief Constructor.
+    ///
+    /// \param graph The graph the algorithm runs on.
+    /// \param capacity The capacity map used by the algorithm.
+    NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
+      : _graph(graph), _capacity(&capacity), _local_capacity(false),
+        _nodes(0), _arcs(), _edges(), _min_cut(),
+        _heap_cross_ref(0), _local_heap_cross_ref(false),
+        _heap(0), _local_heap(false),
+        _next_rep(0), _cut_map(0) {}
+
+    /// \brief Constructor.
+    ///
+    /// This constructor can be used only when the Traits class
+    /// defines how can the local capacity map be instantiated.
+    /// If the SetUnitCapacity used the algorithm automatically
+    /// constructs the capacity map.
+    ///
+    ///\param graph The graph the algorithm runs on.
+    NagamochiIbaraki(const Graph& graph)
+      : _graph(graph), _capacity(0), _local_capacity(false),
+        _nodes(0), _arcs(), _edges(), _min_cut(),
+        _heap_cross_ref(0), _local_heap_cross_ref(false),
+        _heap(0), _local_heap(false),
+        _next_rep(0), _cut_map(0) {}
+
+    /// \brief Destructor.
+    ///
+    /// Destructor.
+    ~NagamochiIbaraki() {
+      if (_local_capacity) delete _capacity;
+      if (_nodes) delete _nodes;
+      if (_local_heap) delete _heap;
+      if (_local_heap_cross_ref) delete _heap_cross_ref;
+      if (_next_rep) delete _next_rep;
+      if (_cut_map) delete _cut_map;
+    }
+
+    /// \brief Sets the heap and the cross reference used by algorithm.
+    ///
+    /// Sets the heap and the cross reference used by algorithm.
+    /// If you don't use this function before calling \ref run(),
+    /// it will allocate one. The destuctor deallocates this
+    /// automatically allocated heap and cross reference, of course.
+    /// \return <tt> (*this) </tt>
+    NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
+    {
+      if (_local_heap_cross_ref) {
+        delete _heap_cross_ref;
+        _local_heap_cross_ref = false;
+      }
+      _heap_cross_ref = &cr;
+      if (_local_heap) {
+        delete _heap;
+        _local_heap = false;
+      }
+      _heap = &hp;
+      return *this;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use
+    /// one of the member functions called \c run().
+    /// \n
+    /// If you need more control on the execution,
+    /// first you must call \ref init() and then call the start()
+    /// or proper times the processNextPhase() member functions.
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures.
+    void init() {
+      createStructures();
+
+      int edge_num = countEdges(_graph);
+      _edges.resize(edge_num);
+      _arcs.resize(2 * edge_num);
+
+      typename Graph::Node prev = INVALID;
+      _node_num = 0;
+      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+        (*_cut_map)[n] = false;
+        (*_next_rep)[n] = INVALID;
+        (*_nodes)[n].last_rep = n;
+        (*_nodes)[n].first_arc = -1;
+        (*_nodes)[n].curr_arc = -1;
+        (*_nodes)[n].prev = prev;
+        if (prev != INVALID) {
+          (*_nodes)[prev].next = n;
+        }
+        (*_nodes)[n].next = INVALID;
+        (*_nodes)[n].sum = 0;
+        prev = n;
+        ++_node_num;
+      }
+
+      _first_node = typename Graph::NodeIt(_graph);
+
+      int index = 0;
+      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+        for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) {
+          typename Graph::Node m = _graph.target(a);
+
+          if (!(n < m)) continue;
+
+          (*_nodes)[n].sum += (*_capacity)[a];
+          (*_nodes)[m].sum += (*_capacity)[a];
+
+          int c = (*_nodes)[m].curr_arc;
+          if (c != -1 && _arcs[c ^ 1].target == n) {
+            _edges[c >> 1].capacity += (*_capacity)[a];
+          } else {
+            _edges[index].capacity = (*_capacity)[a];
+
+            _arcs[index << 1].prev = -1;
+            if ((*_nodes)[n].first_arc != -1) {
+              _arcs[(*_nodes)[n].first_arc].prev = (index << 1);
+            }
+            _arcs[index << 1].next = (*_nodes)[n].first_arc;
+            (*_nodes)[n].first_arc = (index << 1);
+            _arcs[index << 1].target = m;
+
+            (*_nodes)[m].curr_arc = (index << 1);
+
+            _arcs[(index << 1) | 1].prev = -1;
+            if ((*_nodes)[m].first_arc != -1) {
+              _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1);
+            }
+            _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc;
+            (*_nodes)[m].first_arc = ((index << 1) | 1);
+            _arcs[(index << 1) | 1].target = n;
+
+            ++index;
+          }
+        }
+      }
+
+      typename Graph::Node cut_node = INVALID;
+      _min_cut = std::numeric_limits<Value>::max();
+
+      for (typename Graph::Node n = _first_node;
+           n != INVALID; n = (*_nodes)[n].next) {
+        if ((*_nodes)[n].sum < _min_cut) {
+          cut_node = n;
+          _min_cut = (*_nodes)[n].sum;
+        }
+      }
+      (*_cut_map)[cut_node] = true;
+      if (_min_cut == 0) {
+        _first_node = INVALID;
+      }
+    }
+
+  public:
+
+    /// \brief Processes the next phase
+    ///
+    /// Processes the next phase in the algorithm. It must be called
+    /// at most one less the number of the nodes in the graph.
+    ///
+    ///\return %True when the algorithm finished.
+    bool processNextPhase() {
+      if (_first_node == INVALID) return true;
+
+      _heap->clear();
+      for (typename Graph::Node n = _first_node;
+           n != INVALID; n = (*_nodes)[n].next) {
+        (*_heap_cross_ref)[n] = Heap::PRE_HEAP;
+      }
+
+      std::vector<typename Graph::Node> order;
+      order.reserve(_node_num);
+      int sep = 0;
+
+      Value alpha = 0;
+      Value pmc = std::numeric_limits<Value>::max();
+
+      _heap->push(_first_node, static_cast<Value>(0));
+      while (!_heap->empty()) {
+        typename Graph::Node n = _heap->top();
+        Value v = _heap->prio();
+
+        _heap->pop();
+        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
+          switch (_heap->state(_arcs[a].target)) {
+          case Heap::PRE_HEAP:
+            {
+              Value nv = _edges[a >> 1].capacity;
+              _heap->push(_arcs[a].target, nv);
+              _edges[a >> 1].cut = nv;
+            } break;
+          case Heap::IN_HEAP:
+            {
+              Value nv = _edges[a >> 1].capacity + (*_heap)[_arcs[a].target];
+              _heap->decrease(_arcs[a].target, nv);
+              _edges[a >> 1].cut = nv;
+            } break;
+          case Heap::POST_HEAP:
+            break;
+          }
+        }
+
+        alpha += (*_nodes)[n].sum;
+        alpha -= 2 * v;
+
+        order.push_back(n);
+        if (!_heap->empty()) {
+          if (alpha < pmc) {
+            pmc = alpha;
+            sep = order.size();
+          }
+        }
+      }
+
+      if (static_cast<int>(order.size()) < _node_num) {
+        _first_node = INVALID;
+        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+          (*_cut_map)[n] = false;
+        }
+        for (int i = 0; i < static_cast<int>(order.size()); ++i) {
+          typename Graph::Node n = order[i];
+          while (n != INVALID) {
+            (*_cut_map)[n] = true;
+            n = (*_next_rep)[n];
+          }
+        }
+        _min_cut = 0;
+        return true;
+      }
+
+      if (pmc < _min_cut) {
+        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+          (*_cut_map)[n] = false;
+        }
+        for (int i = 0; i < sep; ++i) {
+          typename Graph::Node n = order[i];
+          while (n != INVALID) {
+            (*_cut_map)[n] = true;
+            n = (*_next_rep)[n];
+          }
+        }
+        _min_cut = pmc;
+      }
+
+      for (typename Graph::Node n = _first_node;
+           n != INVALID; n = (*_nodes)[n].next) {
+        bool merged = false;
+        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
+          if (!(_edges[a >> 1].cut < pmc)) {
+            if (!merged) {
+              for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) {
+                (*_nodes)[_arcs[b].target].curr_arc = b;
+              }
+              merged = true;
+            }
+            typename Graph::Node m = _arcs[a].target;
+            int nb = 0;
+            for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) {
+              nb = _arcs[b].next;
+              if ((b ^ a) == 1) continue;
+              typename Graph::Node o = _arcs[b].target;
+              int c = (*_nodes)[o].curr_arc;
+              if (c != -1 && _arcs[c ^ 1].target == n) {
+                _edges[c >> 1].capacity += _edges[b >> 1].capacity;
+                (*_nodes)[n].sum += _edges[b >> 1].capacity;
+                if (_edges[b >> 1].cut < _edges[c >> 1].cut) {
+                  _edges[b >> 1].cut = _edges[c >> 1].cut;
+                }
+                if (_arcs[b ^ 1].prev != -1) {
+                  _arcs[_arcs[b ^ 1].prev].next = _arcs[b ^ 1].next;
+                } else {
+                  (*_nodes)[o].first_arc = _arcs[b ^ 1].next;
+                }
+                if (_arcs[b ^ 1].next != -1) {
+                  _arcs[_arcs[b ^ 1].next].prev = _arcs[b ^ 1].prev;
+                }
+              } else {
+                if (_arcs[a].next != -1) {
+                  _arcs[_arcs[a].next].prev = b;
+                }
+                _arcs[b].next = _arcs[a].next;
+                _arcs[b].prev = a;
+                _arcs[a].next = b;
+                _arcs[b ^ 1].target = n;
+
+                (*_nodes)[n].sum += _edges[b >> 1].capacity;
+                (*_nodes)[o].curr_arc = b;
+              }
+            }
+
+            if (_arcs[a].prev != -1) {
+              _arcs[_arcs[a].prev].next = _arcs[a].next;
+            } else {
+              (*_nodes)[n].first_arc = _arcs[a].next;
+            }
+            if (_arcs[a].next != -1) {
+              _arcs[_arcs[a].next].prev = _arcs[a].prev;
+            }
+
+            (*_nodes)[n].sum -= _edges[a >> 1].capacity;
+            (*_next_rep)[(*_nodes)[n].last_rep] = m;
+            (*_nodes)[n].last_rep = (*_nodes)[m].last_rep;
+
+            if ((*_nodes)[m].prev != INVALID) {
+              (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next;
+            } else{
+              _first_node = (*_nodes)[m].next;
+            }
+            if ((*_nodes)[m].next != INVALID) {
+              (*_nodes)[(*_nodes)[m].next].prev = (*_nodes)[m].prev;
+            }
+            --_node_num;
+          }
+        }
+      }
+
+      if (_node_num == 1) {
+        _first_node = INVALID;
+        return true;
+      }
+
+      return false;
+    }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    /// \pre init() must be called
+    void start() {
+      while (!processNextPhase()) {}
+    }
+
+
+    /// \brief Runs %NagamochiIbaraki algorithm.
+    ///
+    /// This method runs the %Min cut algorithm
+    ///
+    /// \note mc.run(s) is just a shortcut of the following code.
+    ///\code
+    ///  mc.init();
+    ///  mc.start();
+    ///\endcode
+    void run() {
+      init();
+      start();
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    ///
+    /// The result of the %NagamochiIbaraki
+    /// algorithm can be obtained using these functions.\n
+    /// Before the use of these functions, either run() or start()
+    /// must be called.
+
+    ///@{
+
+    /// \brief Returns the min cut value.
+    ///
+    /// Returns the min cut value if the algorithm finished.
+    /// After the first processNextPhase() it is a value of a
+    /// valid cut in the graph.
+    Value minCutValue() const {
+      return _min_cut;
+    }
+
+    /// \brief Returns a min cut in a NodeMap.
+    ///
+    /// It sets the nodes of one of the two partitions to true and
+    /// the other partition to false.
+    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
+    /// \c bool (or convertible) value type.
+    template <typename CutMap>
+    Value minCutMap(CutMap& cutMap) const {
+      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
+        cutMap.set(n, (*_cut_map)[n]);
+      }
+      return minCutValue();
+    }
+
+    ///@}
+
+  };
+}
+
+#endif
Index: lemon/nearest_neighbor_tsp.h
===================================================================
--- lemon/nearest_neighbor_tsp.h	(revision 1294)
+++ lemon/nearest_neighbor_tsp.h	(revision 1294)
@@ -0,0 +1,238 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_NEAREST_NEIGHBOUR_TSP_H
+#define LEMON_NEAREST_NEIGHBOUR_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief Nearest neighbor algorithm for symmetric TSP
+
+#include <deque>
+#include <vector>
+#include <limits>
+#include <lemon/full_graph.h>
+#include <lemon/maps.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief Nearest neighbor algorithm for symmetric TSP.
+  ///
+  /// NearestNeighborTsp implements the nearest neighbor heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This is probably the simplest TSP heuristic.
+  /// It starts with a minimum cost edge and at each step, it connects the
+  /// nearest unvisited node to the current path.
+  /// Finally, it connects the two end points of the path to form a tour.
+  ///
+  /// This method runs in O(n<sup>2</sup>) time.
+  /// It quickly finds a relatively short tour for most TSP instances,
+  /// but it could also yield a really bad (or even the worst) solution
+  /// in special cases.
+  ///
+  /// \tparam CM Type of the cost map.
+  template <typename CM>
+  class NearestNeighborTsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      Cost _sum;
+      std::vector<Node> _path;
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      NearestNeighborTsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm.
+      ///
+      /// This function runs the algorithm.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run() {
+        _path.clear();
+        if (_gr.nodeNum() == 0) {
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+
+        std::deque<Node> path_dq;
+        Edge min_edge1 = INVALID,
+             min_edge2 = INVALID;
+
+        min_edge1 = mapMin(_gr, _cost);
+        Node n1 = _gr.u(min_edge1),
+             n2 = _gr.v(min_edge1);
+        path_dq.push_back(n1);
+        path_dq.push_back(n2);
+
+        FullGraph::NodeMap<bool> used(_gr, false);
+        used[n1] = true;
+        used[n2] = true;
+
+        min_edge1 = INVALID;
+        while (int(path_dq.size()) != _gr.nodeNum()) {
+          if (min_edge1 == INVALID) {
+            for (IncEdgeIt e(_gr, n1); e != INVALID; ++e) {
+              if (!used[_gr.runningNode(e)] &&
+                  (min_edge1 == INVALID || _cost[e] < _cost[min_edge1])) {
+                min_edge1 = e;
+              }
+            }
+          }
+
+          if (min_edge2 == INVALID) {
+            for (IncEdgeIt e(_gr, n2); e != INVALID; ++e) {
+              if (!used[_gr.runningNode(e)] &&
+                  (min_edge2 == INVALID||_cost[e] < _cost[min_edge2])) {
+                min_edge2 = e;
+              }
+            }
+          }
+
+          if (_cost[min_edge1] < _cost[min_edge2]) {
+            n1 = _gr.oppositeNode(n1, min_edge1);
+            path_dq.push_front(n1);
+
+            used[n1] = true;
+            min_edge1 = INVALID;
+
+            if (_gr.u(min_edge2) == n1 || _gr.v(min_edge2) == n1)
+              min_edge2 = INVALID;
+          } else {
+            n2 = _gr.oppositeNode(n2, min_edge2);
+            path_dq.push_back(n2);
+
+            used[n2] = true;
+            min_edge2 = INVALID;
+
+            if (_gr.u(min_edge1) == n2 || _gr.v(min_edge1) == n2)
+              min_edge1 = INVALID;
+          }
+        }
+
+        n1 = path_dq.back();
+        n2 = path_dq.front();
+        _path.push_back(n2);
+        _sum = _cost[_gr.edge(n1, n2)];
+        for (int i = 1; i < int(path_dq.size()); ++i) {
+          n1 = n2;
+          n2 = path_dq[i];
+          _path.push_back(n2);
+          _sum += _cost[_gr.edge(n1, n2)];
+        }
+
+        return _sum;
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _path;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_path.begin(), _path.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_path.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_path[i], _path[i+1]));
+        }
+        if (int(_path.size()) >= 2) {
+          path.addBack(_gr.arc(_path.back(), _path.front()));
+        }
+      }
+
+      /// @}
+
+  };
+
+}; // namespace lemon
+
+#endif
Index: lemon/network_simplex.h
===================================================================
--- lemon/network_simplex.h	(revision 978)
+++ lemon/network_simplex.h	(revision 1318)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -42,14 +42,15 @@
   /// \ref NetworkSimplex implements the primal Network Simplex algorithm
   /// for finding a \ref min_cost_flow "minimum cost flow"
-  /// \ref amo93networkflows, \ref dantzig63linearprog,
-  /// \ref kellyoneill91netsimplex.
+  /// \cite amo93networkflows, \cite dantzig63linearprog,
+  /// \cite kellyoneill91netsimplex.
   /// This algorithm is a highly efficient specialized version of the
   /// linear programming simplex method directly for the minimum cost
   /// flow problem.
   ///
-  /// In general, %NetworkSimplex is the fastest implementation available
-  /// in LEMON for this problem.
-  /// Moreover, it supports both directions of the supply/demand inequality
-  /// constraints. For more information, see \ref SupplyType.
+  /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest
+  /// implementations available in LEMON for solving this problem.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
+  /// Furthermore, this class supports both directions of the supply/demand
+  /// inequality constraints. For more information, see \ref SupplyType.
   ///
   /// Most of the parameters of the problem (except for the digraph)
@@ -64,5 +65,6 @@
   /// algorithm. By default, it is the same as \c V.
   ///
-  /// \warning Both number types must be signed and all input data must
+  /// \warning Both \c V and \c C must be signed number types.
+  /// \warning All input data (capacities, supply values, and costs) must
   /// be integer.
   ///
@@ -122,12 +124,15 @@
     /// the \ref run() function.
     ///
-    /// \ref NetworkSimplex provides five different pivot rule
-    /// implementations that significantly affect the running time
+    /// \ref NetworkSimplex provides five different implementations for
+    /// the pivot strategy that significantly affects the running time
     /// of the algorithm.
-    /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
-    /// proved to be the most efficient and the most robust on various
-    /// test inputs.
-    /// However, another pivot rule can be selected using the \ref run()
-    /// function with the proper parameter.
+    /// According to experimental tests conducted on various problem
+    /// instances, \ref BLOCK_SEARCH "Block Search" and
+    /// \ref ALTERING_LIST "Altering Candidate List" rules turned out
+    /// to be the most efficient.
+    /// Since \ref BLOCK_SEARCH "Block Search" is a simpler strategy that
+    /// seemed to be slightly more robust, it is used by default.
+    /// However, another pivot rule can easily be selected using the
+    /// \ref run() function with the proper parameter.
     enum PivotRule {
 
@@ -155,5 +160,5 @@
       /// The \e Altering \e Candidate \e List pivot rule.
       /// It is a modified version of the Candidate List method.
-      /// It keeps only the several best eligible arcs from the former
+      /// It keeps only a few of the best eligible arcs from the former
       /// candidate list and extends this list in every iteration.
       ALTERING_LIST
@@ -167,6 +172,7 @@
     typedef std::vector<Value> ValueVector;
     typedef std::vector<Cost> CostVector;
-    typedef std::vector<char> BoolVector;
-    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
+    typedef std::vector<signed char> CharVector;
+    // Note: vector<signed char> is used instead of vector<ArcState> and
+    // vector<ArcDirection> for efficiency reasons
 
     // State constants for arcs
@@ -177,7 +183,9 @@
     };
 
-    typedef std::vector<signed char> StateVector;
-    // Note: vector<signed char> is used instead of vector<ArcState> for
-    // efficiency reasons
+    // Direction constants for tree arcs
+    enum ArcDirection {
+      DIR_DOWN = -1,
+      DIR_UP   =  1
+    };
 
   private:
@@ -191,5 +199,5 @@
 
     // Parameters of the problem
-    bool _have_lower;
+    bool _has_lower;
     SupplyType _stype;
     Value _sum_supply;
@@ -218,13 +226,11 @@
     IntVector _succ_num;
     IntVector _last_succ;
+    CharVector _pred_dir;
+    CharVector _state;
     IntVector _dirty_revs;
-    BoolVector _forward;
-    StateVector _state;
     int _root;
 
     // Temporary data used in the current pivot iteration
     int in_arc, join, u_in, v_in, u_out, v_out;
-    int first, second, right, last;
-    int stem, par_stem, new_stem;
     Value delta;
 
@@ -251,5 +257,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const StateVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -303,5 +309,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const StateVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -342,5 +348,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const StateVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -415,5 +421,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const StateVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -518,5 +524,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const StateVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -537,5 +543,5 @@
         SortFunc(const CostVector &map) : _map(map) {}
         bool operator()(int left, int right) {
-          return _map[left] > _map[right];
+          return _map[left] < _map[right];
         }
       };
@@ -555,5 +561,5 @@
         const double BLOCK_SIZE_FACTOR = 1.0;
         const int MIN_BLOCK_SIZE = 10;
-        const double HEAD_LENGTH_FACTOR = 0.1;
+        const double HEAD_LENGTH_FACTOR = 0.01;
         const int MIN_HEAD_LENGTH = 3;
 
@@ -571,9 +577,11 @@
         // Check the current candidate list
         int e;
+        Cost c;
         for (int i = 0; i != _curr_length; ++i) {
           e = _candidates[i];
-          _cand_cost[e] = _state[e] *
-            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
-          if (_cand_cost[e] >= 0) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _cand_cost[e] = c;
+          } else {
             _candidates[i--] = _candidates[--_curr_length];
           }
@@ -585,7 +593,7 @@
 
         for (e = _next_arc; e != _search_arc_num; ++e) {
-          _cand_cost[e] = _state[e] *
-            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
-          if (_cand_cost[e] < 0) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _cand_cost[e] = c;
             _candidates[_curr_length++] = e;
           }
@@ -597,7 +605,7 @@
         }
         for (e = 0; e != _next_arc; ++e) {
-          _cand_cost[e] = _state[e] *
-            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
-          if (_cand_cost[e] < 0) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _cand_cost[e] = c;
             _candidates[_curr_length++] = e;
           }
@@ -612,14 +620,14 @@
       search_end:
 
-        // Make heap of the candidate list (approximating a partial sort)
-        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
-                   _sort_func );
-
-        // Pop the first element of the heap
+        // Perform partial sort operation on the candidate list
+        int new_length = std::min(_head_length + 1, _curr_length);
+        std::partial_sort(_candidates.begin(), _candidates.begin() + new_length,
+                          _candidates.begin() + _curr_length, _sort_func);
+
+        // Select the entering arc and remove it from the list
         _in_arc = _candidates[0];
         _next_arc = e;
-        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
-                  _sort_func );
-        _curr_length = std::min(_head_length, _curr_length - 1);
+        _candidates[0] = _candidates[new_length - 1];
+        _curr_length = new_length - 1;
         return true;
       }
@@ -634,9 +642,10 @@
     ///
     /// \param graph The digraph the algorithm runs on.
-    /// \param arc_mixing Indicate if the arcs have to be stored in a
+    /// \param arc_mixing Indicate if the arcs will be stored in a
     /// mixed order in the internal data structure.
-    /// In special cases, it could lead to better overall performance,
-    /// but it is usually slower. Therefore it is disabled by default.
-    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
+    /// In general, it leads to similar performance as using the original
+    /// arc order, but it makes the algorithm more robust and in special
+    /// cases, even significantly faster. Therefore, it is enabled by default.
+    NetworkSimplex(const GR& graph, bool arc_mixing = true) :
       _graph(graph), _node_id(graph), _arc_id(graph),
       _arc_mixing(arc_mixing),
@@ -674,5 +683,5 @@
     template <typename LowerMap>
     NetworkSimplex& lowerMap(const LowerMap& map) {
-      _have_lower = true;
+      _has_lower = true;
       for (ArcIt a(_graph); a != INVALID; ++a) {
         _lower[_arc_id[a]] = map[a];
@@ -731,4 +740,6 @@
     ///
     /// \return <tt>(*this)</tt>
+    ///
+    /// \sa supplyType()
     template<typename SupplyMap>
     NetworkSimplex& supplyMap(const SupplyMap& map) {
@@ -747,5 +758,5 @@
     ///
     /// Using this function has the same effect as using \ref supplyMap()
-    /// with such a map in which \c k is assigned to \c s, \c -k is
+    /// with a map in which \c k is assigned to \c s, \c -k is
     /// assigned to \c t and all other nodes have zero supply value.
     ///
@@ -869,5 +880,5 @@
         _cost[i] = 1;
       }
-      _have_lower = false;
+      _has_lower = false;
       _stype = GEQ;
       return *this;
@@ -914,5 +925,5 @@
       _parent.resize(all_node_num);
       _pred.resize(all_node_num);
-      _forward.resize(all_node_num);
+      _pred_dir.resize(all_node_num);
       _thread.resize(all_node_num);
       _rev_thread.resize(all_node_num);
@@ -926,7 +937,7 @@
         _node_id[n] = i;
       }
-      if (_arc_mixing) {
+      if (_arc_mixing && _node_num > 1) {
         // Store the arcs in a mixed order
-        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
+        const int skip = std::max(_arc_num / _node_num, 3);
         int i = 0, j = 0;
         for (ArcIt a(_graph); a != INVALID; ++a) {
@@ -934,5 +945,5 @@
           _source[i] = _node_id[_graph.source(a)];
           _target[i] = _node_id[_graph.target(a)];
-          if ((i += k) >= _arc_num) i = ++j;
+          if ((i += skip) >= _arc_num) i = ++j;
         }
       } else {
@@ -963,5 +974,5 @@
     ///
     /// This function returns the total cost of the found flow.
-    /// Its complexity is O(e).
+    /// Its complexity is O(m).
     ///
     /// \note The return type of the function can be specified as a
@@ -1000,5 +1011,6 @@
     }
 
-    /// \brief Return the flow map (the primal solution).
+    /// \brief Copy the flow values (the primal solution) into the
+    /// given map.
     ///
     /// This function copies the flow value on each arc into the given
@@ -1024,5 +1036,6 @@
     }
 
-    /// \brief Return the potential map (the dual solution).
+    /// \brief Copy the potential values (the dual solution) into the
+    /// given map.
     ///
     /// This function copies the potential (dual value) of each node
@@ -1055,6 +1068,10 @@
              (_stype == LEQ && _sum_supply >= 0)) ) return false;
 
+      // Check lower and upper bounds
+      LEMON_DEBUG(checkBoundMaps(),
+          "Upper bounds must be greater or equal to the lower bounds");
+
       // Remove non-zero lower bounds
-      if (_have_lower) {
+      if (_has_lower) {
         for (int i = 0; i != _arc_num; ++i) {
           Value c = _lower[i];
@@ -1117,5 +1134,5 @@
           _state[e] = STATE_TREE;
           if (_supply[u] >= 0) {
-            _forward[u] = true;
+            _pred_dir[u] = DIR_UP;
             _pi[u] = 0;
             _source[e] = u;
@@ -1124,5 +1141,5 @@
             _cost[e] = 0;
           } else {
-            _forward[u] = false;
+            _pred_dir[u] = DIR_DOWN;
             _pi[u] = ART_COST;
             _source[e] = _root;
@@ -1144,5 +1161,5 @@
           _last_succ[u] = u;
           if (_supply[u] >= 0) {
-            _forward[u] = true;
+            _pred_dir[u] = DIR_UP;
             _pi[u] = 0;
             _pred[u] = e;
@@ -1154,5 +1171,5 @@
             _state[e] = STATE_TREE;
           } else {
-            _forward[u] = false;
+            _pred_dir[u] = DIR_DOWN;
             _pi[u] = ART_COST;
             _pred[u] = f;
@@ -1185,5 +1202,5 @@
           _last_succ[u] = u;
           if (_supply[u] <= 0) {
-            _forward[u] = false;
+            _pred_dir[u] = DIR_DOWN;
             _pi[u] = 0;
             _pred[u] = e;
@@ -1195,5 +1212,5 @@
             _state[e] = STATE_TREE;
           } else {
-            _forward[u] = true;
+            _pred_dir[u] = DIR_UP;
             _pi[u] = -ART_COST;
             _pred[u] = f;
@@ -1219,4 +1236,13 @@
     }
 
+    // Check if the upper bound is greater than or equal to the lower bound
+    // on each arc.
+    bool checkBoundMaps() {
+      for (int j = 0; j != _arc_num; ++j) {
+        if (_upper[j] < _lower[j]) return false;
+      }
+      return true;
+    }
+
     // Find the join node
     void findJoinNode() {
@@ -1238,4 +1264,5 @@
       // Initialize first and second nodes according to the direction
       // of the cycle
+      int first, second;
       if (_state[in_arc] == STATE_LOWER) {
         first  = _source[in_arc];
@@ -1247,12 +1274,15 @@
       delta = _cap[in_arc];
       int result = 0;
-      Value d;
+      Value c, d;
       int e;
 
-      // Search the cycle along the path form the first node to the root
+      // Search the cycle form the first node to the join node
       for (int u = first; u != join; u = _parent[u]) {
         e = _pred[u];
-        d = _forward[u] ?
-          _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]);
+        d = _flow[e];
+        if (_pred_dir[u] == DIR_DOWN) {
+          c = _cap[e];
+          d = c >= MAX ? INF : c - d;
+        }
         if (d < delta) {
           delta = d;
@@ -1261,9 +1291,13 @@
         }
       }
-      // Search the cycle along the path form the second node to the root
+
+      // Search the cycle form the second node to the join node
       for (int u = second; u != join; u = _parent[u]) {
         e = _pred[u];
-        d = _forward[u] ?
-          (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
+        d = _flow[e];
+        if (_pred_dir[u] == DIR_UP) {
+          c = _cap[e];
+          d = c >= MAX ? INF : c - d;
+        }
         if (d <= delta) {
           delta = d;
@@ -1290,8 +1324,8 @@
         _flow[in_arc] += val;
         for (int u = _source[in_arc]; u != join; u = _parent[u]) {
-          _flow[_pred[u]] += _forward[u] ? -val : val;
+          _flow[_pred[u]] -= _pred_dir[u] * val;
         }
         for (int u = _target[in_arc]; u != join; u = _parent[u]) {
-          _flow[_pred[u]] += _forward[u] ? val : -val;
+          _flow[_pred[u]] += _pred_dir[u] * val;
         }
       }
@@ -1308,5 +1342,4 @@
     // Update the tree structure
     void updateTreeStructure() {
-      int u, w;
       int old_rev_thread = _rev_thread[u_out];
       int old_succ_num = _succ_num[u_out];
@@ -1314,122 +1347,127 @@
       v_out = _parent[u_out];
 
-      u = _last_succ[u_in];  // the last successor of u_in
-      right = _thread[u];    // the node after it
-
-      // Handle the case when old_rev_thread equals to v_in
-      // (it also means that join and v_out coincide)
-      if (old_rev_thread == v_in) {
-        last = _thread[_last_succ[u_out]];
+      // Check if u_in and u_out coincide
+      if (u_in == u_out) {
+        // Update _parent, _pred, _pred_dir
+        _parent[u_in] = v_in;
+        _pred[u_in] = in_arc;
+        _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
+
+        // Update _thread and _rev_thread
+        if (_thread[v_in] != u_out) {
+          int after = _thread[old_last_succ];
+          _thread[old_rev_thread] = after;
+          _rev_thread[after] = old_rev_thread;
+          after = _thread[v_in];
+          _thread[v_in] = u_out;
+          _rev_thread[u_out] = v_in;
+          _thread[old_last_succ] = after;
+          _rev_thread[after] = old_last_succ;
+        }
       } else {
-        last = _thread[v_in];
-      }
-
-      // Update _thread and _parent along the stem nodes (i.e. the nodes
-      // between u_in and u_out, whose parent have to be changed)
-      _thread[v_in] = stem = u_in;
-      _dirty_revs.clear();
-      _dirty_revs.push_back(v_in);
-      par_stem = v_in;
-      while (stem != u_out) {
-        // Insert the next stem node into the thread list
-        new_stem = _parent[stem];
-        _thread[u] = new_stem;
-        _dirty_revs.push_back(u);
-
-        // Remove the subtree of stem from the thread list
-        w = _rev_thread[stem];
-        _thread[w] = right;
-        _rev_thread[right] = w;
-
-        // Change the parent node and shift stem nodes
-        _parent[stem] = par_stem;
-        par_stem = stem;
-        stem = new_stem;
-
-        // Update u and right
-        u = _last_succ[stem] == _last_succ[par_stem] ?
-          _rev_thread[par_stem] : _last_succ[stem];
-        right = _thread[u];
-      }
-      _parent[u_out] = par_stem;
-      _thread[u] = last;
-      _rev_thread[last] = u;
-      _last_succ[u_out] = u;
-
-      // Remove the subtree of u_out from the thread list except for
-      // the case when old_rev_thread equals to v_in
-      // (it also means that join and v_out coincide)
-      if (old_rev_thread != v_in) {
-        _thread[old_rev_thread] = right;
-        _rev_thread[right] = old_rev_thread;
-      }
-
-      // Update _rev_thread using the new _thread values
-      for (int i = 0; i != int(_dirty_revs.size()); ++i) {
-        u = _dirty_revs[i];
-        _rev_thread[_thread[u]] = u;
-      }
-
-      // Update _pred, _forward, _last_succ and _succ_num for the
-      // stem nodes from u_out to u_in
-      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
-      u = u_out;
-      while (u != u_in) {
-        w = _parent[u];
-        _pred[u] = _pred[w];
-        _forward[u] = !_forward[w];
-        tmp_sc += _succ_num[u] - _succ_num[w];
-        _succ_num[u] = tmp_sc;
-        _last_succ[w] = tmp_ls;
-        u = w;
-      }
-      _pred[u_in] = in_arc;
-      _forward[u_in] = (u_in == _source[in_arc]);
-      _succ_num[u_in] = old_succ_num;
-
-      // Set limits for updating _last_succ form v_in and v_out
-      // towards the root
-      int up_limit_in = -1;
-      int up_limit_out = -1;
-      if (_last_succ[join] == v_in) {
-        up_limit_out = join;
-      } else {
-        up_limit_in = join;
+        // Handle the case when old_rev_thread equals to v_in
+        // (it also means that join and v_out coincide)
+        int thread_continue = old_rev_thread == v_in ?
+          _thread[old_last_succ] : _thread[v_in];
+
+        // Update _thread and _parent along the stem nodes (i.e. the nodes
+        // between u_in and u_out, whose parent have to be changed)
+        int stem = u_in;              // the current stem node
+        int par_stem = v_in;          // the new parent of stem
+        int next_stem;                // the next stem node
+        int last = _last_succ[u_in];  // the last successor of stem
+        int before, after = _thread[last];
+        _thread[v_in] = u_in;
+        _dirty_revs.clear();
+        _dirty_revs.push_back(v_in);
+        while (stem != u_out) {
+          // Insert the next stem node into the thread list
+          next_stem = _parent[stem];
+          _thread[last] = next_stem;
+          _dirty_revs.push_back(last);
+
+          // Remove the subtree of stem from the thread list
+          before = _rev_thread[stem];
+          _thread[before] = after;
+          _rev_thread[after] = before;
+
+          // Change the parent node and shift stem nodes
+          _parent[stem] = par_stem;
+          par_stem = stem;
+          stem = next_stem;
+
+          // Update last and after
+          last = _last_succ[stem] == _last_succ[par_stem] ?
+            _rev_thread[par_stem] : _last_succ[stem];
+          after = _thread[last];
+        }
+        _parent[u_out] = par_stem;
+        _thread[last] = thread_continue;
+        _rev_thread[thread_continue] = last;
+        _last_succ[u_out] = last;
+
+        // Remove the subtree of u_out from the thread list except for
+        // the case when old_rev_thread equals to v_in
+        if (old_rev_thread != v_in) {
+          _thread[old_rev_thread] = after;
+          _rev_thread[after] = old_rev_thread;
+        }
+
+        // Update _rev_thread using the new _thread values
+        for (int i = 0; i != int(_dirty_revs.size()); ++i) {
+          int u = _dirty_revs[i];
+          _rev_thread[_thread[u]] = u;
+        }
+
+        // Update _pred, _pred_dir, _last_succ and _succ_num for the
+        // stem nodes from u_out to u_in
+        int tmp_sc = 0, tmp_ls = _last_succ[u_out];
+        for (int u = u_out, p = _parent[u]; u != u_in; u = p, p = _parent[u]) {
+          _pred[u] = _pred[p];
+          _pred_dir[u] = -_pred_dir[p];
+          tmp_sc += _succ_num[u] - _succ_num[p];
+          _succ_num[u] = tmp_sc;
+          _last_succ[p] = tmp_ls;
+        }
+        _pred[u_in] = in_arc;
+        _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
+        _succ_num[u_in] = old_succ_num;
       }
 
       // Update _last_succ from v_in towards the root
-      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
-           u = _parent[u]) {
-        _last_succ[u] = _last_succ[u_out];
-      }
+      int up_limit_out = _last_succ[join] == v_in ? join : -1;
+      int last_succ_out = _last_succ[u_out];
+      for (int u = v_in; u != -1 && _last_succ[u] == v_in; u = _parent[u]) {
+        _last_succ[u] = last_succ_out;
+      }
+
       // Update _last_succ from v_out towards the root
       if (join != old_rev_thread && v_in != old_rev_thread) {
-        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
+        for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
              u = _parent[u]) {
           _last_succ[u] = old_rev_thread;
         }
-      } else {
-        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
+      }
+      else if (last_succ_out != old_last_succ) {
+        for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
              u = _parent[u]) {
-          _last_succ[u] = _last_succ[u_out];
+          _last_succ[u] = last_succ_out;
         }
       }
 
       // Update _succ_num from v_in to join
-      for (u = v_in; u != join; u = _parent[u]) {
+      for (int u = v_in; u != join; u = _parent[u]) {
         _succ_num[u] += old_succ_num;
       }
       // Update _succ_num from v_out to join
-      for (u = v_out; u != join; u = _parent[u]) {
+      for (int u = v_out; u != join; u = _parent[u]) {
         _succ_num[u] -= old_succ_num;
       }
     }
 
-    // Update potentials
+    // Update potentials in the subtree that has been moved
     void updatePotential() {
-      Cost sigma = _forward[u_in] ?
-        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
-        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
-      // Update potentials in the subtree, which has been moved
+      Cost sigma = _pi[v_in] - _pi[u_in] -
+                   _pred_dir[u_in] * _cost[in_arc];
       int end = _thread[_last_succ[u_in]];
       for (int u = u_in; u != end; u = _thread[u]) {
@@ -1479,5 +1517,5 @@
           }
         } else {
-          // Find the min. cost incomming arc for each demand node
+          // Find the min. cost incoming arc for each demand node
           for (int i = 0; i != int(demand_nodes.size()); ++i) {
             Node v = demand_nodes[i];
@@ -1575,5 +1613,5 @@
 
       // Transform the solution and the supply map to the original form
-      if (_have_lower) {
+      if (_has_lower) {
         for (int i = 0; i != _arc_num; ++i) {
           Value c = _lower[i];
Index: lemon/opt2_tsp.h
===================================================================
--- lemon/opt2_tsp.h	(revision 1270)
+++ lemon/opt2_tsp.h	(revision 1270)
@@ -0,0 +1,367 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_OPT2_TSP_H
+#define LEMON_OPT2_TSP_H
+
+/// \ingroup tsp
+/// \file
+/// \brief 2-opt algorithm for symmetric TSP.
+
+#include <vector>
+#include <lemon/full_graph.h>
+
+namespace lemon {
+
+  /// \ingroup tsp
+  ///
+  /// \brief 2-opt algorithm for symmetric TSP.
+  ///
+  /// Opt2Tsp implements the 2-opt heuristic for solving
+  /// symmetric \ref tsp "TSP".
+  ///
+  /// This algorithm starts with an initial tour and iteratively improves it.
+  /// At each step, it removes two edges and the reconnects the created two
+  /// paths in the other way if the resulting tour is shorter.
+  /// The algorithm finishes when no such 2-opt move can be applied, and so
+  /// the tour is 2-optimal.
+  ///
+  /// If no starting tour is given to the \ref run() function, then the
+  /// algorithm uses the node sequence determined by the node IDs.
+  /// Oherwise, it starts with the given tour.
+  ///
+  /// This is a rather slow but effective method.
+  /// Its typical usage is the improvement of the result of a fast tour
+  /// construction heuristic (e.g. the InsertionTsp algorithm).
+  ///
+  /// \tparam CM Type of the cost map.
+  template <typename CM>
+  class Opt2Tsp
+  {
+    public:
+
+      /// Type of the cost map
+      typedef CM CostMap;
+      /// Type of the edge costs
+      typedef typename CM::Value Cost;
+
+    private:
+
+      GRAPH_TYPEDEFS(FullGraph);
+
+      const FullGraph &_gr;
+      const CostMap &_cost;
+      Cost _sum;
+      std::vector<int> _plist;
+      std::vector<Node> _path;
+
+    public:
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
+      /// \param cost The cost map.
+      Opt2Tsp(const FullGraph &gr, const CostMap &cost)
+        : _gr(gr), _cost(cost) {}
+
+      /// \name Execution Control
+      /// @{
+
+      /// \brief Runs the algorithm from scratch.
+      ///
+      /// This function runs the algorithm starting from the tour that is
+      /// determined by the node ID sequence.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run() {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 2) {
+          _path.push_back(_gr(0));
+          _path.push_back(_gr(1));
+          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
+        }
+
+        _plist.resize(2*_gr.nodeNum());
+        for (int i = 1; i < _gr.nodeNum()-1; ++i) {
+          _plist[2*i] = i-1;
+          _plist[2*i+1] = i+1;
+        }
+        _plist[0] = _gr.nodeNum()-1;
+        _plist[1] = 1;
+        _plist[2*_gr.nodeNum()-2] = _gr.nodeNum()-2;
+        _plist[2*_gr.nodeNum()-1] = 0;
+
+        return start();
+      }
+
+      /// \brief Runs the algorithm starting from the given tour.
+      ///
+      /// This function runs the algorithm starting from the given tour.
+      ///
+      /// \param tour The tour as a path structure. It must be a
+      /// \ref checkPath() "valid path" containing excactly n arcs.
+      ///
+      /// \return The total cost of the found tour.
+      template <typename Path>
+      Cost run(const Path& tour) {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 2) {
+          _path.push_back(_gr(0));
+          _path.push_back(_gr(1));
+          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
+        }
+
+        _plist.resize(2*_gr.nodeNum());
+        typename Path::ArcIt it(tour);
+        int first = _gr.id(_gr.source(it)),
+            prev = first,
+            curr = _gr.id(_gr.target(it)),
+            next = -1;
+        _plist[2*first+1] = curr;
+        for (++it; it != INVALID; ++it) {
+          next = _gr.id(_gr.target(it));
+          _plist[2*curr] = prev;
+          _plist[2*curr+1] = next;
+          prev = curr;
+          curr = next;
+        }
+        _plist[2*first] = prev;
+
+        return start();
+      }
+
+      /// \brief Runs the algorithm starting from the given tour.
+      ///
+      /// This function runs the algorithm starting from the given tour
+      /// (node sequence).
+      ///
+      /// \param tour A vector that stores all <tt>Node</tt>s of the graph
+      /// in the desired order.
+      ///
+      /// \return The total cost of the found tour.
+      Cost run(const std::vector<Node>& tour) {
+        _path.clear();
+
+        if (_gr.nodeNum() == 0) return _sum = 0;
+        else if (_gr.nodeNum() == 1) {
+          _path.push_back(_gr(0));
+          return _sum = 0;
+        }
+        else if (_gr.nodeNum() == 2) {
+          _path.push_back(_gr(0));
+          _path.push_back(_gr(1));
+          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
+        }
+
+        _plist.resize(2*_gr.nodeNum());
+        typename std::vector<Node>::const_iterator it = tour.begin();
+        int first = _gr.id(*it),
+            prev = first,
+            curr = _gr.id(*(++it)),
+            next = -1;
+        _plist[2*first+1] = curr;
+        for (++it; it != tour.end(); ++it) {
+          next = _gr.id(*it);
+          _plist[2*curr] = prev;
+          _plist[2*curr+1] = next;
+          prev = curr;
+          curr = next;
+        }
+        _plist[2*first] = curr;
+        _plist[2*curr] = prev;
+        _plist[2*curr+1] = first;
+
+        return start();
+      }
+
+      /// @}
+
+      /// \name Query Functions
+      /// @{
+
+      /// \brief The total cost of the found tour.
+      ///
+      /// This function returns the total cost of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      Cost tourCost() const {
+        return _sum;
+      }
+
+      /// \brief Returns a const reference to the node sequence of the
+      /// found tour.
+      ///
+      /// This function returns a const reference to a vector
+      /// that stores the node sequence of the found tour.
+      ///
+      /// \pre run() must be called before using this function.
+      const std::vector<Node>& tourNodes() const {
+        return _path;
+      }
+
+      /// \brief Gives back the node sequence of the found tour.
+      ///
+      /// This function copies the node sequence of the found tour into
+      /// an STL container through the given output iterator. The
+      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
+      /// For example,
+      /// \code
+      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
+      /// tsp.tourNodes(nodes.begin());
+      /// \endcode
+      /// or
+      /// \code
+      /// std::list<FullGraph::Node> nodes;
+      /// tsp.tourNodes(std::back_inserter(nodes));
+      /// \endcode
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Iterator>
+      void tourNodes(Iterator out) const {
+        std::copy(_path.begin(), _path.end(), out);
+      }
+
+      /// \brief Gives back the found tour as a path.
+      ///
+      /// This function copies the found tour as a list of arcs/edges into
+      /// the given \ref lemon::concepts::Path "path structure".
+      ///
+      /// \pre run() must be called before using this function.
+      template <typename Path>
+      void tour(Path &path) const {
+        path.clear();
+        for (int i = 0; i < int(_path.size()) - 1; ++i) {
+          path.addBack(_gr.arc(_path[i], _path[i+1]));
+        }
+        if (int(_path.size()) >= 2) {
+          path.addBack(_gr.arc(_path.back(), _path.front()));
+        }
+      }
+
+      /// @}
+
+    private:
+
+      // Iterator class for the linked list storage of the tour
+      class PathListIt {
+        public:
+          PathListIt(const std::vector<int> &pl, int i=0)
+            : plist(&pl), act(i), last(pl[2*act]) {}
+          PathListIt(const std::vector<int> &pl, int i, int l)
+            : plist(&pl), act(i), last(l) {}
+
+          int nextIndex() const {
+            return (*plist)[2*act] == last ? 2*act+1 : 2*act;
+          }
+
+          int prevIndex() const {
+            return (*plist)[2*act] == last ? 2*act : 2*act+1;
+          }
+
+          int next() const {
+            int x = (*plist)[2*act];
+            return x == last ? (*plist)[2*act+1] : x;
+          }
+
+          int prev() const {
+            return last;
+          }
+
+          PathListIt& operator++() {
+            int tmp = act;
+            act = next();
+            last = tmp;
+            return *this;
+          }
+
+          operator int() const {
+            return act;
+          }
+
+        private:
+          const std::vector<int> *plist;
+          int act;
+          int last;
+      };
+
+      // Checks and applies 2-opt move (if it improves the tour)
+      bool checkOpt2(const PathListIt& i, const PathListIt& j) {
+        Node u  = _gr.nodeFromId(i),
+             un = _gr.nodeFromId(i.next()),
+             v  = _gr.nodeFromId(j),
+             vn = _gr.nodeFromId(j.next());
+
+        if (_cost[_gr.edge(u, un)] + _cost[_gr.edge(v, vn)] >
+            _cost[_gr.edge(u, v)] + _cost[_gr.edge(un, vn)])
+        {
+          _plist[PathListIt(_plist, i.next(), i).prevIndex()] = j.next();
+          _plist[PathListIt(_plist, j.next(), j).prevIndex()] = i.next();
+
+          _plist[i.nextIndex()] = j;
+          _plist[j.nextIndex()] = i;
+
+          return true;
+        }
+
+        return false;
+     }
+
+      // Executes the algorithm from the initial tour
+      Cost start() {
+
+      restart_search:
+        for (PathListIt i(_plist); true; ++i) {
+          PathListIt j = i;
+          if (++j == 0 || ++j == 0) break;
+          for (; j != 0 && j != i.prev(); ++j) {
+            if (checkOpt2(i, j))
+              goto restart_search;
+          }
+        }
+
+        PathListIt i(_plist);
+        _path.push_back(_gr.nodeFromId(i));
+        for (++i; i != 0; ++i)
+          _path.push_back(_gr.nodeFromId(i));
+
+        _sum = _cost[_gr.edge(_path.back(), _path.front())];
+        for (int i = 0; i < int(_path.size())-1; ++i) {
+          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
+        }
+
+        return _sum;
+      }
+
+  };
+
+}; // namespace lemon
+
+#endif
Index: lemon/path.h
===================================================================
--- lemon/path.h	(revision 1146)
+++ lemon/path.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -44,5 +44,5 @@
   ///
   /// In a sense, the path can be treated as a list of arcs. The
-  /// lemon path type stores just this list. As a consequence, it
+  /// LEMON path type stores just this list. As a consequence, it
   /// cannot enumerate the nodes of the path and the source node of
   /// a zero length path is undefined.
@@ -149,5 +149,5 @@
     void clear() { head.clear(); tail.clear(); }
 
-    /// \brief The nth arc.
+    /// \brief The n-th arc.
     ///
     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
@@ -157,5 +157,5 @@
     }
 
-    /// \brief Initialize arc iterator to point to the nth arc
+    /// \brief Initialize arc iterator to point to the n-th arc
     ///
     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
@@ -245,5 +245,5 @@
   ///
   /// In a sense, the path can be treated as a list of arcs. The
-  /// lemon path type stores just this list. As a consequence it
+  /// LEMON path type stores just this list. As a consequence it
   /// cannot enumerate the nodes in the path and the zero length paths
   /// cannot store the source.
@@ -318,5 +318,5 @@
       /// Constructor with starting point
       ArcIt(const SimplePath &_path, int _idx)
-        : idx(_idx), path(&_path) {}
+        : path(&_path), idx(_idx) {}
 
     public:
@@ -354,5 +354,5 @@
     void clear() { data.clear(); }
 
-    /// \brief The nth arc.
+    /// \brief The n-th arc.
     ///
     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
@@ -361,5 +361,5 @@
     }
 
-    /// \brief  Initializes arc iterator to point to the nth arc.
+    /// \brief  Initializes arc iterator to point to the n-th arc.
     ArcIt nthIt(int n) const {
       return ArcIt(*this, n);
@@ -422,5 +422,5 @@
   ///
   /// In a sense, the path can be treated as a list of arcs. The
-  /// lemon path type stores just this list. As a consequence it
+  /// LEMON path type stores just this list. As a consequence it
   /// cannot enumerate the nodes in the path and the zero length paths
   /// cannot store the source.
@@ -544,7 +544,7 @@
     };
 
-    /// \brief The nth arc.
-    ///
-    /// This function looks for the nth arc in O(n) time.
+    /// \brief The n-th arc.
+    ///
+    /// This function looks for the n-th arc in O(n) time.
     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
     const Arc& nth(int n) const {
@@ -556,5 +556,5 @@
     }
 
-    /// \brief Initializes arc iterator to point to the nth arc.
+    /// \brief Initializes arc iterator to point to the n-th arc.
     ArcIt nthIt(int n) const {
       Node *node = first;
@@ -775,5 +775,5 @@
   ///
   /// In a sense, the path can be treated as a list of arcs. The
-  /// lemon path type stores just this list. As a consequence it
+  /// LEMON path type stores just this list. As a consequence it
   /// cannot enumerate the nodes in the path and the source node of
   /// a zero length path is undefined.
@@ -884,5 +884,5 @@
     };
 
-    /// \brief The nth arc.
+    /// \brief The n-th arc.
     ///
     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
@@ -891,5 +891,5 @@
     }
 
-    /// \brief The arc iterator pointing to the nth arc.
+    /// \brief The arc iterator pointing to the n-th arc.
     ArcIt nthIt(int n) const {
       return ArcIt(*this, n);
@@ -1095,5 +1095,5 @@
   ///
   /// In a sense, the path can be treated as a list of arcs. The
-  /// lemon path type stores only this list. As a consequence, it
+  /// LEMON path type stores only this list. As a consequence, it
   /// cannot enumerate the nodes in the path and the zero length paths
   /// cannot have a source node.
Index: lemon/planarity.h
===================================================================
--- lemon/planarity.h	(revision 1160)
+++ lemon/planarity.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/preflow.h
===================================================================
--- lemon/preflow.h	(revision 1110)
+++ lemon/preflow.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -103,10 +103,10 @@
   /// This class provides an implementation of Goldberg-Tarjan's \e preflow
   /// \e push-relabel algorithm producing a \ref max_flow
-  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
-  /// \ref amo93networkflows, \ref goldberg88newapproach.
+  /// "flow of maximum value" in a digraph \cite clrs01algorithms,
+  /// \cite amo93networkflows, \cite goldberg88newapproach.
   /// The preflow algorithms are the fastest known maximum
   /// flow algorithms. The current implementation uses a mixture of the
   /// \e "highest label" and the \e "bound decrease" heuristics.
-  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
+  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{m})\f$.
   ///
   /// The algorithm consists of two phases. After the first phase
@@ -135,5 +135,5 @@
   public:
 
-    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
+    ///The \ref lemon::PreflowDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
     ///The type of the digraph the algorithm runs on.
Index: lemon/radix_sort.h
===================================================================
--- lemon/radix_sort.h	(revision 606)
+++ lemon/radix_sort.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -35,4 +35,10 @@
   namespace _radix_sort_bits {
 
+    template <typename Iterator>
+    bool unitRange(Iterator first, Iterator last) {
+      ++first;
+      return first == last;
+    }
+
     template <typename Value>
     struct Identity {
@@ -61,7 +67,4 @@
       std::iter_swap(first, last);
       ++first;
-      if (!(first < last)) {
-        return first;
-      }
       while (true) {
         while (!(functor(*first) & mask)) {
@@ -72,5 +75,5 @@
           --last;
         }
-        if (!(first < last)) {
+        if (unitRange(last, first)) {
           return first;
         }
@@ -98,7 +101,4 @@
       std::iter_swap(first, last);
       ++first;
-      if (!(first < last)) {
-        return first;
-      }
       while (true) {
         while (functor(*first) < 0) {
@@ -109,5 +109,5 @@
           --last;
         }
-        if (!(first < last)) {
+        if (unitRange(last, first)) {
           return first;
         }
@@ -120,5 +120,5 @@
     void radixIntroSort(Iterator first, Iterator last,
                         Functor functor, Value mask) {
-      while (mask != 0 && last - first > 1) {
+      while (mask != 0 && first != last && !unitRange(first, last)) {
         Iterator cut = radixSortPartition(first, last, functor, mask);
         mask >>= 1;
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 956)
+++ lemon/smart_graph.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -406,6 +406,4 @@
     std::vector<ArcT> arcs;
 
-    int first_free_arc;
-
   public:
 
@@ -812,4 +810,533 @@
   };
 
+  class SmartBpGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      int partition_next;
+      int partition_index;
+      bool red;
+    };
+
+    struct ArcT {
+      int target;
+      int next_out;
+    };
+
+    std::vector<NodeT> nodes;
+    std::vector<ArcT> arcs;
+
+    int first_red, first_blue;
+    int max_red, max_blue;
+
+  public:
+
+    typedef SmartBpGraphBase Graph;
+
+    class Node;
+    class Arc;
+    class Edge;
+
+    class Node {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Node(int id) { _id = id;}
+
+    public:
+      Node() {}
+      Node (Invalid) { _id = -1; }
+      bool operator==(const Node& node) const {return _id == node._id;}
+      bool operator!=(const Node& node) const {return _id != node._id;}
+      bool operator<(const Node& node) const {return _id < node._id;}
+    };
+
+    class RedNode : public Node {
+      friend class SmartBpGraphBase;
+    protected:
+
+      explicit RedNode(int pid) : Node(pid) {}
+
+    public:
+      RedNode() {}
+      RedNode(const RedNode& node) : Node(node) {}
+      RedNode(Invalid) : Node(INVALID){}
+    };
+
+    class BlueNode : public Node {
+      friend class SmartBpGraphBase;
+    protected:
+
+      explicit BlueNode(int pid) : Node(pid) {}
+
+    public:
+      BlueNode() {}
+      BlueNode(const BlueNode& node) : Node(node) {}
+      BlueNode(Invalid) : Node(INVALID){}
+    };
+
+    class Edge {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Edge(int id) { _id = id;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { _id = -1; }
+      bool operator==(const Edge& arc) const {return _id == arc._id;}
+      bool operator!=(const Edge& arc) const {return _id != arc._id;}
+      bool operator<(const Edge& arc) const {return _id < arc._id;}
+    };
+
+    class Arc {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Arc(int id) { _id = id;}
+
+    public:
+      operator Edge() const {
+        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
+      }
+
+      Arc() {}
+      Arc (Invalid) { _id = -1; }
+      bool operator==(const Arc& arc) const {return _id == arc._id;}
+      bool operator!=(const Arc& arc) const {return _id != arc._id;}
+      bool operator<(const Arc& arc) const {return _id < arc._id;}
+    };
+
+
+
+    SmartBpGraphBase()
+      : nodes(), arcs(), first_red(-1), first_blue(-1),
+        max_red(-1), max_blue(-1) {}
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return nodes.size(); }
+    int redNum() const { return max_red + 1; }
+    int blueNum() const { return max_blue + 1; }
+    int edgeNum() const { return arcs.size() / 2; }
+    int arcNum() const { return arcs.size(); }
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxRedId() const { return max_red; }
+    int maxBlueId() const { return max_blue; }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    bool red(Node n) const { return nodes[n._id].red; }
+    bool blue(Node n) const { return !nodes[n._id].red; }
+
+    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
+    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
+
+    Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); }
+    Node target(Arc a) const { return Node(arcs[a._id].target); }
+
+    RedNode redNode(Edge e) const {
+      return RedNode(arcs[2 * e._id].target);
+    }
+    BlueNode blueNode(Edge e) const {
+      return BlueNode(arcs[2 * e._id + 1].target);
+    }
+
+    static bool direction(Arc a) {
+      return (a._id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e._id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = nodes.size() - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(RedNode& node) const {
+      node._id = first_red;
+    }
+
+    void next(RedNode& node) const {
+      node._id = nodes[node._id].partition_next;
+    }
+
+    void first(BlueNode& node) const {
+      node._id = first_blue;
+    }
+
+    void next(BlueNode& node) const {
+      node._id = nodes[node._id].partition_next;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = arcs.size() - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void first(Edge& arc) const {
+      arc._id = arcs.size() / 2 - 1;
+    }
+
+    static void next(Edge& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc &arc, const Node& v) const {
+      arc._id = nodes[v._id].first_out;
+    }
+    void nextOut(Arc &arc) const {
+      arc._id = arcs[arc._id].next_out;
+    }
+
+    void firstIn(Arc &arc, const Node& v) const {
+      arc._id = ((nodes[v._id].first_out) ^ 1);
+      if (arc._id == -2) arc._id = -1;
+    }
+    void nextIn(Arc &arc) const {
+      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
+      if (arc._id == -2) arc._id = -1;
+    }
+
+    void firstInc(Edge &arc, bool& d, const Node& v) const {
+      int de = nodes[v._id].first_out;
+      if (de != -1) {
+        arc._id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        arc._id = -1;
+        d = true;
+      }
+    }
+    void nextInc(Edge &arc, bool& d) const {
+      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
+      if (de != -1) {
+        arc._id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        arc._id = -1;
+        d = true;
+      }
+    }
+
+    static int id(Node v) { return v._id; }
+    int id(RedNode v) const { return nodes[v._id].partition_index; }
+    int id(BlueNode v) const { return nodes[v._id].partition_index; }
+    static int id(Arc e) { return e._id; }
+    static int id(Edge e) { return e._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
+    }
+    bool valid(Arc a) const {
+      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
+    }
+    bool valid(Edge e) const {
+      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
+    }
+
+    RedNode addRedNode() {
+      int n = nodes.size();
+      nodes.push_back(NodeT());
+      nodes[n].first_out = -1;
+      nodes[n].red = true;
+      nodes[n].partition_index = ++max_red;
+      nodes[n].partition_next = first_red;
+      first_red = n;
+
+      return RedNode(n);
+    }
+
+    BlueNode addBlueNode() {
+      int n = nodes.size();
+      nodes.push_back(NodeT());
+      nodes[n].first_out = -1;
+      nodes[n].red = false;
+      nodes[n].partition_index = ++max_blue;
+      nodes[n].partition_next = first_blue;
+      first_blue = n;
+
+      return BlueNode(n);
+    }
+
+    Edge addEdge(RedNode u, BlueNode v) {
+      int n = arcs.size();
+      arcs.push_back(ArcT());
+      arcs.push_back(ArcT());
+
+      arcs[n].target = u._id;
+      arcs[n | 1].target = v._id;
+
+      arcs[n].next_out = nodes[v._id].first_out;
+      nodes[v._id].first_out = n;
+
+      arcs[n | 1].next_out = nodes[u._id].first_out;
+      nodes[u._id].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_red = -1;
+      first_blue = -1;
+      max_blue = -1;
+      max_red = -1;
+    }
+
+  };
+
+  typedef BpGraphExtender<SmartBpGraphBase> ExtendedSmartBpGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief A smart undirected bipartite graph class.
+  ///
+  /// \ref SmartBpGraph is a simple and fast bipartite graph implementation.
+  /// It is also quite memory efficient but at the price
+  /// that it does not support node and edge deletion
+  /// (except for the Snapshot feature).
+  ///
+  /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept"
+  /// and it also provides some additional functionalities.
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes, edges and arcs.
+  ///
+  /// \sa concepts::BpGraph
+  /// \sa SmartGraph
+  class SmartBpGraph : public ExtendedSmartBpGraphBase {
+    typedef ExtendedSmartBpGraphBase Parent;
+
+  private:
+    /// Graphs are \e not copy constructible. Use GraphCopy instead.
+    SmartBpGraph(const SmartBpGraph &) : ExtendedSmartBpGraphBase() {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use GraphCopy instead.
+    void operator=(const SmartBpGraph &) {}
+
+  public:
+
+    /// Constructor
+
+    /// Constructor.
+    ///
+    SmartBpGraph() {}
+
+    /// \brief Add a new red node to the graph.
+    ///
+    /// This function adds a red new node to the graph.
+    /// \return The new node.
+    RedNode addRedNode() { return Parent::addRedNode(); }
+
+    /// \brief Add a new blue node to the graph.
+    ///
+    /// This function adds a blue new node to the graph.
+    /// \return The new node.
+    BlueNode addBlueNode() { return Parent::addBlueNode(); }
+
+    /// \brief Add a new edge to the graph.
+    ///
+    /// This function adds a new edge to the graph between nodes
+    /// \c u and \c v with inherent orientation from node \c u to
+    /// node \c v.
+    /// \return The new edge.
+    Edge addEdge(RedNode u, BlueNode v) {
+      return Parent::addEdge(u, v);
+    }
+    Edge addEdge(BlueNode v, RedNode u) {
+      return Parent::addEdge(u, v);
+    }
+
+    /// \brief Node validity check
+    ///
+    /// This function gives back \c true if the given node is valid,
+    /// i.e. it is a real node of the graph.
+    ///
+    /// \warning A removed node (using Snapshot) could become valid again
+    /// if new nodes are added to the graph.
+    bool valid(Node n) const { return Parent::valid(n); }
+
+    /// \brief Edge validity check
+    ///
+    /// This function gives back \c true if the given edge is valid,
+    /// i.e. it is a real edge of the graph.
+    ///
+    /// \warning A removed edge (using Snapshot) could become valid again
+    /// if new edges are added to the graph.
+    bool valid(Edge e) const { return Parent::valid(e); }
+
+    /// \brief Arc validity check
+    ///
+    /// This function gives back \c true if the given arc is valid,
+    /// i.e. it is a real arc of the graph.
+    ///
+    /// \warning A removed arc (using Snapshot) could become valid again
+    /// if new edges are added to the graph.
+    bool valid(Arc a) const { return Parent::valid(a); }
+
+    ///Clear the graph.
+
+    ///This function erases all nodes and arcs from the graph.
+    ///
+    void clear() {
+      Parent::clear();
+    }
+
+    /// Reserve memory for nodes.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveEdge()
+    void reserveNode(int n) { nodes.reserve(n); };
+
+    /// Reserve memory for edges.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveNode()
+    void reserveEdge(int m) { arcs.reserve(2 * m); };
+
+  public:
+
+    class Snapshot;
+
+  protected:
+
+    void saveSnapshot(Snapshot &s)
+    {
+      s._graph = this;
+      s.node_num = nodes.size();
+      s.arc_num = arcs.size();
+    }
+
+    void restoreSnapshot(const Snapshot &s)
+    {
+      while(s.arc_num<arcs.size()) {
+        int n=arcs.size()-1;
+        Edge arc=edgeFromId(n/2);
+        Parent::notifier(Edge()).erase(arc);
+        std::vector<Arc> dir;
+        dir.push_back(arcFromId(n));
+        dir.push_back(arcFromId(n-1));
+        Parent::notifier(Arc()).erase(dir);
+        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
+        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
+        arcs.pop_back();
+        arcs.pop_back();
+      }
+      while(s.node_num<nodes.size()) {
+        int n=nodes.size()-1;
+        Node node = nodeFromId(n);
+        if (Parent::red(node)) {
+          first_red = nodes[n].partition_next;
+          if (first_red != -1) {
+            max_red = nodes[first_red].partition_index;
+          } else {
+            max_red = -1;
+          }
+          Parent::notifier(RedNode()).erase(asRedNodeUnsafe(node));
+        } else {
+          first_blue = nodes[n].partition_next;
+          if (first_blue != -1) {
+            max_blue = nodes[first_blue].partition_index;
+          } else {
+            max_blue = -1;
+          }
+          Parent::notifier(BlueNode()).erase(asBlueNodeUnsafe(node));
+        }
+        Parent::notifier(Node()).erase(node);
+        nodes.pop_back();
+      }
+    }
+
+  public:
+
+    ///Class to make a snapshot of the graph and to restore it later.
+
+    ///Class to make a snapshot of the graph and to restore it later.
+    ///
+    ///The newly added nodes and edges can be removed using the
+    ///restore() function. This is the only way for deleting nodes and/or
+    ///edges from a SmartBpGraph structure.
+    ///
+    ///\note After a state is restored, you cannot restore a later state,
+    ///i.e. you cannot add the removed nodes and edges again using
+    ///another Snapshot instance.
+    ///
+    ///\warning The validity of the snapshot is not stored due to
+    ///performance reasons. If you do not use the snapshot correctly,
+    ///it can cause broken program, invalid or not restored state of
+    ///the graph or no change.
+    class Snapshot
+    {
+      SmartBpGraph *_graph;
+    protected:
+      friend class SmartBpGraph;
+      unsigned int node_num;
+      unsigned int arc_num;
+    public:
+      ///Default constructor.
+
+      ///Default constructor.
+      ///You have to call save() to actually make a snapshot.
+      Snapshot() : _graph(0) {}
+      ///Constructor that immediately makes a snapshot
+
+      /// This constructor immediately makes a snapshot of the given graph.
+      ///
+      Snapshot(SmartBpGraph &gr) {
+        gr.saveSnapshot(*this);
+      }
+
+      ///Make a snapshot.
+
+      ///This function makes a snapshot of the given graph.
+      ///It can be called more than once. In case of a repeated
+      ///call, the previous snapshot gets lost.
+      void save(SmartBpGraph &gr)
+      {
+        gr.saveSnapshot(*this);
+      }
+
+      ///Undo the changes until the last snapshot.
+
+      ///This function undos the changes until the last snapshot
+      ///created by save() or Snapshot(SmartBpGraph&).
+      void restore()
+      {
+        _graph->restoreSnapshot(*this);
+      }
+    };
+  };
+
 } //namespace lemon
 
Index: lemon/soplex.cc
===================================================================
--- lemon/soplex.cc	(revision 956)
+++ lemon/soplex.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/soplex.h
===================================================================
--- lemon/soplex.h	(revision 956)
+++ lemon/soplex.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/suurballe.h
===================================================================
--- lemon/suurballe.h	(revision 956)
+++ lemon/suurballe.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -138,5 +138,5 @@
     typedef typename TR::Heap Heap;
 
-    /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
+    /// The \ref lemon::SuurballeDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
 
@@ -683,5 +683,5 @@
     /// This function returns the total length of the found paths, i.e.
     /// the total cost of the found flow.
-    /// The complexity of the function is O(e).
+    /// The complexity of the function is O(m).
     ///
     /// \pre \ref run() or \ref findFlow() must be called before using
Index: lemon/time_measure.h
===================================================================
--- lemon/time_measure.h	(revision 833)
+++ lemon/time_measure.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -35,4 +35,5 @@
 #include <fstream>
 #include <iostream>
+#include <lemon/math.h>
 
 namespace lemon {
@@ -64,4 +65,19 @@
     double rtime;
 
+  public:
+    ///Display format specifier
+
+    ///\e
+    ///
+    enum Format {
+      /// Reports all measured values
+      NORMAL = 0,
+      /// Only real time and an error indicator is displayed
+      SHORT = 1
+    };
+
+  private:
+    static Format _format;
+
     void _reset() {
       utime = stime = cutime = cstime = rtime = 0;
@@ -69,4 +85,18 @@
 
   public:
+
+    ///Set output format
+
+    ///Set output format.
+    ///
+    ///The output format is global for all timestamp instances.
+    static void format(Format f) { _format = f; }
+    ///Retrieve the current output format
+
+    ///Retrieve the current output format
+    ///
+    ///The output format is global for all timestamp instances.
+    static Format format() { return _format; }
+
 
     ///Read the current time values of the process
@@ -225,9 +255,22 @@
   inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
   {
-    os << "u: " << t.userTime() <<
-      "s, s: " << t.systemTime() <<
-      "s, cu: " << t.cUserTime() <<
-      "s, cs: " << t.cSystemTime() <<
-      "s, real: " << t.realTime() << "s";
+    switch(t._format)
+      {
+      case TimeStamp::NORMAL:
+        os << "u: " << t.userTime() <<
+          "s, s: " << t.systemTime() <<
+          "s, cu: " << t.cUserTime() <<
+          "s, cs: " << t.cSystemTime() <<
+          "s, real: " << t.realTime() << "s";
+        break;
+      case TimeStamp::SHORT:
+        double total = t.userTime()+t.systemTime()+
+          t.cUserTime()+t.cSystemTime();
+        os << t.realTime()
+           << "s (err: " << round((t.realTime()-total)/
+                                  t.realTime()*10000)/100
+           << "%)";
+        break;
+      }
     return os;
   }
@@ -469,4 +512,5 @@
     std::string _title;
     std::ostream &_os;
+    bool _active;
   public:
     ///Constructor
@@ -476,11 +520,25 @@
     ///\param os The stream to print the report to.
     ///\param run Sets whether the timer should start immediately.
-    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true)
-      : Timer(run), _title(title), _os(os){}
+    ///\param active Sets whether the report should actually be printed
+    ///       on destruction.
+    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true,
+               bool active=true)
+      : Timer(run), _title(title), _os(os), _active(active) {}
     ///Destructor that prints the ellapsed time
     ~TimeReport()
     {
-      _os << _title << *this << std::endl;
-    }
+      if(_active) _os << _title << *this << std::endl;
+    }
+
+    ///Retrieve the activity status
+
+    ///\e
+    ///
+    bool active() const { return _active; }
+    ///Set the activity status
+
+    /// This function set whether the time report should actually be printed
+    /// on destruction.
+    void active(bool a) { _active=a; }
   };
 
Index: lemon/unionfind.h
===================================================================
--- lemon/unionfind.h	(revision 956)
+++ lemon/unionfind.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lx_check_coin.m4
===================================================================
--- m4/lx_check_coin.m4	(revision 796)
+++ 	(revision )
@@ -1,136 +1,0 @@
-AC_DEFUN([LX_CHECK_COIN],
-[
-  AC_ARG_WITH([coin],
-AS_HELP_STRING([--with-coin@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
-AS_HELP_STRING([--without-coin], [disable checking for CLP]),
-              [], [with_coin=yes])
-
-  AC_ARG_WITH([coin-includedir],
-AS_HELP_STRING([--with-coin-includedir=DIR], [search for CLP headers in DIR]),
-              [], [with_coin_includedir=no])
-
-  AC_ARG_WITH([coin-libdir],
-AS_HELP_STRING([--with-coin-libdir=DIR], [search for CLP libraries in DIR]),
-              [], [with_coin_libdir=no])
-
-  lx_clp_found=no
-  if test x"$with_coin" != x"no"; then
-    AC_MSG_CHECKING([for CLP])
-
-    if test x"$with_coin_includedir" != x"no"; then
-      CLP_CXXFLAGS="-I$with_coin_includedir"
-    elif test x"$with_coin" != x"yes"; then
-      CLP_CXXFLAGS="-I$with_coin/include"
-    fi
-
-    if test x"$with_coin_libdir" != x"no"; then
-      CLP_LDFLAGS="-L$with_coin_libdir"
-    elif test x"$with_coin" != x"yes"; then
-      CLP_LDFLAGS="-L$with_coin/lib"
-    fi
-    CLP_LIBS="-lClp -lCoinUtils -lm"
-
-    lx_save_cxxflags="$CXXFLAGS"
-    lx_save_ldflags="$LDFLAGS"
-    lx_save_libs="$LIBS"
-    CXXFLAGS="$CLP_CXXFLAGS"
-    LDFLAGS="$CLP_LDFLAGS"
-    LIBS="$CLP_LIBS"
-
-    lx_clp_test_prog='
-      #include <coin/ClpModel.hpp>
-
-      int main(int argc, char** argv)
-      {
-        ClpModel clp;
-        return 0;
-      }'
-
-    AC_LANG_PUSH(C++)
-    AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
-    AC_LANG_POP(C++)
-
-    CXXFLAGS="$lx_save_cxxflags"
-    LDFLAGS="$lx_save_ldflags"
-    LIBS="$lx_save_libs"
-
-    if test x"$lx_clp_found" = x"yes"; then
-      AC_DEFINE([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.])
-      lx_lp_found=yes
-      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
-      AC_MSG_RESULT([yes])
-    else
-      CLP_CXXFLAGS=""
-      CLP_LDFLAGS=""
-      CLP_LIBS=""
-      AC_MSG_RESULT([no])
-    fi
-  fi
-  CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
-  AC_SUBST(CLP_CXXFLAGS)
-  AC_SUBST(CLP_LIBS)
-  AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
-
-
-  lx_cbc_found=no
-  if test x"$lx_clp_found" = x"yes"; then
-    if test x"$with_coin" != x"no"; then
-      AC_MSG_CHECKING([for CBC])
-
-      if test x"$with_coin_includedir" != x"no"; then
-        CBC_CXXFLAGS="-I$with_coin_includedir"
-      elif test x"$with_coin" != x"yes"; then
-        CBC_CXXFLAGS="-I$with_coin/include"
-      fi
-
-      if test x"$with_coin_libdir" != x"no"; then
-        CBC_LDFLAGS="-L$with_coin_libdir"
-      elif test x"$with_coin" != x"yes"; then
-        CBC_LDFLAGS="-L$with_coin/lib"
-      fi
-      CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
-
-      lx_save_cxxflags="$CXXFLAGS"
-      lx_save_ldflags="$LDFLAGS"
-      lx_save_libs="$LIBS"
-      CXXFLAGS="$CBC_CXXFLAGS"
-      LDFLAGS="$CBC_LDFLAGS"
-      LIBS="$CBC_LIBS"
-
-      lx_cbc_test_prog='
-        #include <coin/CbcModel.hpp>
-
-        int main(int argc, char** argv)
-        {
-          CbcModel cbc;
-          return 0;
-        }'
-
-      AC_LANG_PUSH(C++)
-      AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no])
-      AC_LANG_POP(C++)
-
-      CXXFLAGS="$lx_save_cxxflags"
-      LDFLAGS="$lx_save_ldflags"
-      LIBS="$lx_save_libs"
-
-      if test x"$lx_cbc_found" = x"yes"; then
-        AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.])
-        lx_lp_found=yes
-        AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
-        lx_mip_found=yes
-        AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
-        AC_MSG_RESULT([yes])
-      else
-        CBC_CXXFLAGS=""
-        CBC_LDFLAGS=""
-        CBC_LIBS=""
-        AC_MSG_RESULT([no])
-      fi
-    fi
-  fi
-  CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS"
-  AC_SUBST(CBC_CXXFLAGS)
-  AC_SUBST(CBC_LIBS)
-  AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"])
-])
Index: lx_check_cplex.m4
===================================================================
--- m4/lx_check_cplex.m4	(revision 674)
+++ 	(revision )
@@ -1,81 +1,0 @@
-AC_DEFUN([LX_CHECK_CPLEX],
-[
-  AC_ARG_WITH([cplex],
-AS_HELP_STRING([--with-cplex@<:@=PREFIX@:>@], [search for CPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
-AS_HELP_STRING([--without-cplex], [disable checking for CPLEX]),
-              [], [with_cplex=yes])
-
-  AC_ARG_WITH([cplex-includedir],
-AS_HELP_STRING([--with-cplex-includedir=DIR], [search for CPLEX headers in DIR]),
-              [], [with_cplex_includedir=no])
-
-  AC_ARG_WITH([cplex-libdir],
-AS_HELP_STRING([--with-cplex-libdir=DIR], [search for CPLEX libraries in DIR]),
-              [], [with_cplex_libdir=no])
-
-  lx_cplex_found=no
-  if test x"$with_cplex" != x"no"; then
-    AC_MSG_CHECKING([for CPLEX])
-
-    if test x"$with_cplex_includedir" != x"no"; then
-      CPLEX_CFLAGS="-I$with_cplex_includedir"
-    elif test x"$with_cplex" != x"yes"; then
-      CPLEX_CFLAGS="-I$with_cplex/include"
-    elif test x"$CPLEX_INCLUDEDIR" != x; then
-      CPLEX_CFLAGS="-I$CPLEX_INCLUDEDIR"
-    fi
-
-    if test x"$with_cplex_libdir" != x"no"; then
-      CPLEX_LDFLAGS="-L$with_cplex_libdir"
-    elif test x"$with_cplex" != x"yes"; then
-      CPLEX_LDFLAGS="-L$with_cplex/lib"
-    elif test x"$CPLEX_LIBDIR" != x; then
-      CPLEX_LDFLAGS="-L$CPLEX_LIBDIR"
-    fi
-    CPLEX_LIBS="-lcplex -lm -lpthread"
-
-    lx_save_cxxflags="$CXXFLAGS"
-    lx_save_ldflags="$LDFLAGS"
-    lx_save_libs="$LIBS"
-    CXXFLAGS="$CPLEX_CFLAGS"
-    LDFLAGS="$CPLEX_LDFLAGS"
-    LIBS="$CPLEX_LIBS"
-
-    lx_cplex_test_prog='
-      extern "C" {
-      #include <ilcplex/cplex.h>
-      }
-
-      int main(int argc, char** argv)
-      {
-        CPXENVptr env = NULL;
-        return 0;
-      }'
-
-    AC_LANG_PUSH(C++)
-    AC_LINK_IFELSE([$lx_cplex_test_prog], [lx_cplex_found=yes], [lx_cplex_found=no])
-    AC_LANG_POP(C++)
-
-    CXXFLAGS="$lx_save_cxxflags"
-    LDFLAGS="$lx_save_ldflags"
-    LIBS="$lx_save_libs"
-
-    if test x"$lx_cplex_found" = x"yes"; then
-      AC_DEFINE([LEMON_HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
-      lx_lp_found=yes
-      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
-      lx_mip_found=yes
-      AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
-      AC_MSG_RESULT([yes])
-    else
-      CPLEX_CFLAGS=""
-      CPLEX_LDFLAGS=""
-      CPLEX_LIBS=""
-      AC_MSG_RESULT([no])
-    fi
-  fi
-  CPLEX_LIBS="$CPLEX_LDFLAGS $CPLEX_LIBS"
-  AC_SUBST(CPLEX_CFLAGS)
-  AC_SUBST(CPLEX_LIBS)
-  AM_CONDITIONAL([HAVE_CPLEX], [test x"$lx_cplex_found" = x"yes"])
-])
Index: lx_check_glpk.m4
===================================================================
--- m4/lx_check_glpk.m4	(revision 674)
+++ 	(revision )
@@ -1,84 +1,0 @@
-AC_DEFUN([LX_CHECK_GLPK],
-[
-  AC_ARG_WITH([glpk],
-AS_HELP_STRING([--with-glpk@<:@=PREFIX@:>@], [search for GLPK under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
-AS_HELP_STRING([--without-glpk], [disable checking for GLPK]),
-              [], [with_glpk=yes])
-
-  AC_ARG_WITH([glpk-includedir],
-AS_HELP_STRING([--with-glpk-includedir=DIR], [search for GLPK headers in DIR]),
-              [], [with_glpk_includedir=no])
-
-  AC_ARG_WITH([glpk-libdir],
-AS_HELP_STRING([--with-glpk-libdir=DIR], [search for GLPK libraries in DIR]),
-              [], [with_glpk_libdir=no])
-
-  lx_glpk_found=no
-  if test x"$with_glpk" != x"no"; then
-    AC_MSG_CHECKING([for GLPK])
-
-    if test x"$with_glpk_includedir" != x"no"; then
-      GLPK_CFLAGS="-I$with_glpk_includedir"
-    elif test x"$with_glpk" != x"yes"; then
-      GLPK_CFLAGS="-I$with_glpk/include"
-    fi
-
-    if test x"$with_glpk_libdir" != x"no"; then
-      GLPK_LDFLAGS="-L$with_glpk_libdir"
-    elif test x"$with_glpk" != x"yes"; then
-      GLPK_LDFLAGS="-L$with_glpk/lib"
-    fi
-    GLPK_LIBS="-lglpk"
-
-    lx_save_cxxflags="$CXXFLAGS"
-    lx_save_ldflags="$LDFLAGS"
-    lx_save_libs="$LIBS"
-    CXXFLAGS="$GLPK_CFLAGS"
-    LDFLAGS="$GLPK_LDFLAGS"
-    LIBS="$GLPK_LIBS"
-
-    lx_glpk_test_prog='
-      extern "C" {
-      #include <glpk.h>
-      }
-
-      #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)
-      {
-        LPX *lp;
-        lp = lpx_create_prob();
-        lpx_delete_prob(lp);
-        return 0;
-      }'
-
-    AC_LANG_PUSH(C++)
-    AC_LINK_IFELSE([$lx_glpk_test_prog], [lx_glpk_found=yes], [lx_glpk_found=no])
-    AC_LANG_POP(C++)
-
-    CXXFLAGS="$lx_save_cxxflags"
-    LDFLAGS="$lx_save_ldflags"
-    LIBS="$lx_save_libs"
-
-    if test x"$lx_glpk_found" = x"yes"; then
-      AC_DEFINE([LEMON_HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
-      lx_lp_found=yes
-      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
-      lx_mip_found=yes
-      AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
-      AC_MSG_RESULT([yes])
-    else
-      GLPK_CFLAGS=""
-      GLPK_LDFLAGS=""
-      GLPK_LIBS=""
-      AC_MSG_RESULT([no])
-    fi
-  fi
-  GLPK_LIBS="$GLPK_LDFLAGS $GLPK_LIBS"
-  AC_SUBST(GLPK_CFLAGS)
-  AC_SUBST(GLPK_LIBS)
-  AM_CONDITIONAL([HAVE_GLPK], [test x"$lx_glpk_found" = x"yes"])
-])
Index: lx_check_soplex.m4
===================================================================
--- m4/lx_check_soplex.m4	(revision 674)
+++ 	(revision )
@@ -1,73 +1,0 @@
-AC_DEFUN([LX_CHECK_SOPLEX],
-[
-  AC_ARG_WITH([soplex],
-AS_HELP_STRING([--with-soplex@<:@=PREFIX@:>@], [search for SOPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
-AS_HELP_STRING([--without-soplex], [disable checking for SOPLEX]),
-              [], [with_soplex=yes])
-
-  AC_ARG_WITH([soplex-includedir],
-AS_HELP_STRING([--with-soplex-includedir=DIR], [search for SOPLEX headers in DIR]),
-              [], [with_soplex_includedir=no])
-
-  AC_ARG_WITH([soplex-libdir],
-AS_HELP_STRING([--with-soplex-libdir=DIR], [search for SOPLEX libraries in DIR]),
-              [], [with_soplex_libdir=no])
-
-  lx_soplex_found=no
-  if test x"$with_soplex" != x"no"; then
-    AC_MSG_CHECKING([for SOPLEX])
-
-    if test x"$with_soplex_includedir" != x"no"; then
-      SOPLEX_CXXFLAGS="-I$with_soplex_includedir"
-    elif test x"$with_soplex" != x"yes"; then
-      SOPLEX_CXXFLAGS="-I$with_soplex/src"
-    fi
-
-    if test x"$with_soplex_libdir" != x"no"; then
-      SOPLEX_LDFLAGS="-L$with_soplex_libdir"
-    elif test x"$with_soplex" != x"yes"; then
-      SOPLEX_LDFLAGS="-L$with_soplex/lib"
-    fi
-    SOPLEX_LIBS="-lsoplex -lz"
-
-    lx_save_cxxflags="$CXXFLAGS"
-    lx_save_ldflags="$LDFLAGS"
-    lx_save_libs="$LIBS"
-    CXXFLAGS="$SOPLEX_CXXFLAGS"
-    LDFLAGS="$SOPLEX_LDFLAGS"
-    LIBS="$SOPLEX_LIBS"
-
-    lx_soplex_test_prog='
-      #include <soplex.h>
-
-      int main(int argc, char** argv)
-      {
-        soplex::SoPlex soplex;
-        return 0;
-      }'
-
-    AC_LANG_PUSH(C++)
-    AC_LINK_IFELSE([$lx_soplex_test_prog], [lx_soplex_found=yes], [lx_soplex_found=no])
-    AC_LANG_POP(C++)
-
-    CXXFLAGS="$lx_save_cxxflags"
-    LDFLAGS="$lx_save_ldflags"
-    LIBS="$lx_save_libs"
-
-    if test x"$lx_soplex_found" = x"yes"; then
-      AC_DEFINE([LEMON_HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
-      lx_lp_found=yes
-      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
-      AC_MSG_RESULT([yes])
-    else
-      SOPLEX_CXXFLAGS=""
-      SOPLEX_LDFLAGS=""
-      SOPLEX_LIBS=""
-      AC_MSG_RESULT([no])
-    fi
-  fi
-  SOPLEX_LIBS="$SOPLEX_LDFLAGS $SOPLEX_LIBS"
-  AC_SUBST(SOPLEX_CXXFLAGS)
-  AC_SUBST(SOPLEX_LIBS)
-  AM_CONDITIONAL([HAVE_SOPLEX], [test x"$lx_soplex_found" = x"yes"])
-])
Index: ripts/Makefile.am
===================================================================
--- scripts/Makefile.am	(revision 840)
+++ 	(revision )
@@ -1,7 +1,0 @@
-EXTRA_DIST += \
-	scripts/bib2dox.py \
-	scripts/bootstrap.sh \
-	scripts/chg-len.py \
-	scripts/mk-release.sh \
-	scripts/unify-sources.sh \
-	scripts/valgrind-wrapper.sh
Index: ripts/bib2dox.py
===================================================================
--- scripts/bib2dox.py	(revision 905)
+++ 	(revision )
@@ -1,816 +1,0 @@
-#! /usr/bin/env python
-"""
-  BibTeX to Doxygen converter
-  Usage: python bib2dox.py bibfile.bib > bibfile.dox
-
-  This file is a part of LEMON, a generic C++ optimization library.
-
-  **********************************************************************
-
-  This code is the modification of the BibTeX to XML converter
-  by Vidar Bronken Gundersen et al.
-  See the original copyright notices below. 
-
-  **********************************************************************
-
-  Decoder for bibliographic data, BibTeX
-  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
-
-  v.8
-  (c)2002-06-23 Vidar Bronken Gundersen
-  http://bibtexml.sf.net/
-  Reuse approved as long as this notification is kept.
-  Licence: GPL.
-
-  Contributions/thanks to:
-  Egon Willighagen, http://sf.net/projects/jreferences/
-  Richard Mahoney (for providing a test case)
-
-  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
-  (c) 2003-01-15
-
-  1.  Changed bibtex: tags to bibxml: tags.
-  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
-  3.  Allow spaces between @type and first {
-  4.  "author" fields with multiple authors split by " and "
-      are put in separate xml "bibxml:author" tags.
-  5.  Option for Titles: words are capitalized
-      only if first letter in title or capitalized inside braces
-  6.  Removes braces from within field values
-  7.  Ignores comments in bibtex file (including @comment{ or % )
-  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
-  9.  Handles bibtex @string abbreviations
-        --> includes bibtex's default abbreviations for months
-        --> does concatenation of abbr # " more " and " more " # abbr
-  10. Handles @type( ... ) or @type{ ... }
-  11. The keywords field is split on , or ; and put into separate xml
-      "bibxml:keywords" tags
-  12. Ignores @preamble
-
-  Known Limitations
-  1.  Does not transform Latex encoding like math mode and special
-      latex symbols.
-  2.  Does not parse author fields into first and last names.
-      E.g., It does not do anything special to an author whose name is
-      in the form LAST_NAME, FIRST_NAME
-      In "author" tag, will show up as
-      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
-  3.  Does not handle "crossref" fields other than to print
-      <bibxml:crossref>...</bibxml:crossref>
-  4.  Does not inform user of the input's format errors.  You just won't
-      be able to transform the file later with XSL
-
-  You will have to manually edit the XML output if you need to handle
-  these (and unknown) limitations.
-
-"""
-
-import string, re
-
-# set of valid name characters
-valid_name_chars = '[\w\-:]'
-
-#
-# define global regular expression variables
-#
-author_rex = re.compile('\s+and\s+')
-rembraces_rex = re.compile('[{}]')
-capitalize_rex = re.compile('({[^}]*})')
-
-# used by bibtexkeywords(data)
-keywords_rex = re.compile('[,;]')
-
-# used by concat_line(line)
-concatsplit_rex = re.compile('\s*#\s*')
-
-# split on {, }, or " in verify_out_of_braces
-delimiter_rex = re.compile('([{}"])',re.I)
-
-field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
-data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
-
-url_rex = re.compile('\\\url\{([^}]*)\}')
-
-#
-# styles for html formatting
-#
-divstyle = 'margin-top: -4ex; margin-left: 8em;'
-
-#
-# return the string parameter without braces
-#
-def transformurls(str):
-    return url_rex.sub(r'<a href="\1">\1</a>', str)
-
-#
-# return the string parameter without braces
-#
-def removebraces(str):
-    return rembraces_rex.sub('', str)
-
-#
-# latex-specific replacements
-# (do this after braces were removed)
-#
-def latexreplacements(line):
-    line = string.replace(line, '~', '&nbsp;')
-    line = string.replace(line, '\\\'a', '&aacute;')
-    line = string.replace(line, '\\"a', '&auml;')
-    line = string.replace(line, '\\\'e', '&eacute;')
-    line = string.replace(line, '\\"e', '&euml;')
-    line = string.replace(line, '\\\'i', '&iacute;')
-    line = string.replace(line, '\\"i', '&iuml;')
-    line = string.replace(line, '\\\'o', '&oacute;')
-    line = string.replace(line, '\\"o', '&ouml;')
-    line = string.replace(line, '\\\'u', '&uacute;')
-    line = string.replace(line, '\\"u', '&uuml;')
-    line = string.replace(line, '\\H o', '&otilde;')
-    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
-    line = string.replace(line, '\\\'A', '&Aacute;')
-    line = string.replace(line, '\\"A', '&Auml;')
-    line = string.replace(line, '\\\'E', '&Eacute;')
-    line = string.replace(line, '\\"E', '&Euml;')
-    line = string.replace(line, '\\\'I', '&Iacute;')
-    line = string.replace(line, '\\"I', '&Iuml;')
-    line = string.replace(line, '\\\'O', '&Oacute;')
-    line = string.replace(line, '\\"O', '&Ouml;')
-    line = string.replace(line, '\\\'U', '&Uacute;')
-    line = string.replace(line, '\\"U', '&Uuml;')
-    line = string.replace(line, '\\H O', '&Otilde;')
-    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
-
-    return line
-
-#
-# copy characters form a string decoding html expressions (&xyz;)
-#
-def copychars(str, ifrom, count):
-    result = ''
-    i = ifrom
-    c = 0
-    html_spec = False
-    while (i < len(str)) and (c < count):
-        if str[i] == '&':
-            html_spec = True;
-            if i+1 < len(str):
-                result += str[i+1]
-            c += 1
-            i += 2
-        else:
-            if not html_spec:
-                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
-                   ((str[i] >= 'a') and (str[i] <= 'z')):
-                    result += str[i]
-                    c += 1
-            elif str[i] == ';':
-                html_spec = False;
-            i += 1
-    
-    return result
-
-
-# 
-# Handle a list of authors (separated by 'and').
-# It gives back an array of the follwing values:
-#  - num: the number of authors,
-#  - list: the list of the author names,
-#  - text: the bibtex text (separated by commas and/or 'and')
-#  - abbrev: abbreviation that can be used for indicate the
-#    bibliography entries
-#
-def bibtexauthor(data):
-    result = {}
-    bibtex = ''
-    result['list'] = author_rex.split(data)
-    result['num'] = len(result['list'])
-    for i, author in enumerate(result['list']):
-        # general transformations
-        author = latexreplacements(removebraces(author.strip()))
-        # transform "Xyz, A. B." to "A. B. Xyz"
-        pos = author.find(',')
-        if pos != -1:
-            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
-        result['list'][i] = author
-        bibtex += author + '#'
-    bibtex = bibtex[:-1]
-    if result['num'] > 1:
-        ix = bibtex.rfind('#')
-        if result['num'] == 2:
-            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
-        else:
-            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
-    bibtex = bibtex.replace('#', ', ')
-    result['text'] = bibtex
-    
-    result['abbrev'] = ''
-    for author in result['list']:
-        pos = author.rfind(' ') + 1
-        count = 1
-        if result['num'] == 1:
-            count = 3
-        result['abbrev'] += copychars(author, pos, count)
-
-    return result
-
-
-#
-# data = title string
-# @return the capitalized title (first letter is capitalized), rest are capitalized
-# only if capitalized inside braces
-#
-def capitalizetitle(data):
-    title_list = capitalize_rex.split(data)
-    title = ''
-    count = 0
-    for phrase in title_list:
-         check = string.lstrip(phrase)
-
-         # keep phrase's capitalization the same
-         if check.find('{') == 0:
-              title += removebraces(phrase)
-         else:
-         # first word --> capitalize first letter (after spaces)
-              if count == 0:
-                  title += check.capitalize()
-              else:
-                  title += phrase.lower()
-         count = count + 1
-
-    return title
-
-
-#
-# @return the bibtex for the title
-# @param data --> title string
-# braces are removed from title
-#
-def bibtextitle(data, entrytype):
-    if entrytype in ('book', 'inbook'):
-        title = removebraces(data.strip())
-    else:
-        title = removebraces(capitalizetitle(data.strip()))
-    bibtex = title
-    return bibtex
-
-
-#
-# function to compare entry lists
-#
-def entry_cmp(x, y):
-    return cmp(x[0], y[0])
-
-
-#
-# print the XML for the transformed "filecont_source"
-#
-def bibtexdecoder(filecont_source):
-    filecont = []
-    file = []
-    
-    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
-    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
-    endtype_rex = re.compile('}\s*$')
-    endtag_rex = re.compile('^\s*}\s*$')
-
-    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
-    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
-
-    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
-    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
-
-    for line in filecont_source:
-        line = line[:-1]
-
-        # encode character entities
-        line = string.replace(line, '&', '&amp;')
-        line = string.replace(line, '<', '&lt;')
-        line = string.replace(line, '>', '&gt;')
-
-        # start entry: publication type (store for later use)
-        if pubtype_rex.match(line):
-        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
-            entrycont = {}
-            entry = []
-            entrytype = pubtype_rex.sub('\g<1>',line)
-            entrytype = string.lower(entrytype)
-            entryid   = pubtype_rex.sub('\g<2>', line)
-
-        # end entry if just a }
-        elif endtype_rex.match(line):
-            # generate doxygen code for the entry
-
-            # enty type related formattings
-            if entrytype in ('book', 'inbook'):
-                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
-                if not entrycont.has_key('author'):
-                    entrycont['author'] = entrycont['editor']
-                    entrycont['author']['text'] += ', editors'
-            elif entrytype == 'article':
-                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
-            elif entrytype in ('inproceedings', 'incollection', 'conference'):
-                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
-            elif entrytype == 'techreport':
-                if not entrycont.has_key('type'):
-                    entrycont['type'] = 'Technical report'
-            elif entrytype == 'mastersthesis':
-                entrycont['type'] = 'Master\'s thesis'
-            elif entrytype == 'phdthesis':
-                entrycont['type'] = 'PhD thesis'
-
-            for eline in entrycont:
-                if eline != '':
-                    eline = latexreplacements(eline)
-
-            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
-                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
-
-            if entrycont.has_key('author') and (entrycont['author'] != ''):
-                entry.append(entrycont['author']['text'] + '.')
-            if entrycont.has_key('title') and (entrycont['title'] != ''):
-                entry.append(entrycont['title'] + '.')
-            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
-                entry.append(entrycont['journal'] + ',')
-            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
-                entry.append('In ' + entrycont['booktitle'] + ',')
-            if entrycont.has_key('type') and (entrycont['type'] != ''):
-                eline = entrycont['type']
-                if entrycont.has_key('number') and (entrycont['number'] != ''):
-                    eline += ' ' + entrycont['number']
-                eline += ','
-                entry.append(eline)
-            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
-                entry.append(entrycont['institution'] + ',')
-            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
-                entry.append(entrycont['publisher'] + ',')
-            if entrycont.has_key('school') and (entrycont['school'] != ''):
-                entry.append(entrycont['school'] + ',')
-            if entrycont.has_key('address') and (entrycont['address'] != ''):
-                entry.append(entrycont['address'] + ',')
-            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
-                entry.append(entrycont['edition'] + ' edition,')
-            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
-                entry.append(entrycont['howpublished'] + ',')
-            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
-                eline = entrycont['volume'];
-                if entrycont.has_key('number') and (entrycont['number'] != ''):
-                    eline += '(' + entrycont['number'] + ')'
-                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
-                    eline += ':' + entrycont['pages']
-                eline += ','
-                entry.append(eline)
-            else:
-                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
-                    entry.append('pages ' + entrycont['pages'] + ',')
-            if entrycont.has_key('year') and (entrycont['year'] != ''):
-                if entrycont.has_key('month') and (entrycont['month'] != ''):
-                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
-                else:
-                    entry.append(entrycont['year'] + '.')
-            if entrycont.has_key('note') and (entrycont['note'] != ''):
-                entry.append(entrycont['note'] + '.')
-            if entrycont.has_key('url') and (entrycont['url'] != ''):
-                entry.append(entrycont['url'] + '.')
-
-            # generate keys for sorting and for the output
-            sortkey = ''
-            bibkey = ''
-            if entrycont.has_key('author'):
-                for author in entrycont['author']['list']:
-                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
-                bibkey = entrycont['author']['abbrev']
-            else:
-                bibkey = 'x'
-            if entrycont.has_key('year'):
-                sortkey += entrycont['year']
-                bibkey += entrycont['year'][-2:]
-            if entrycont.has_key('title'):
-                sortkey += entrycont['title']
-            if entrycont.has_key('key'):
-                sortkey = entrycont['key'] + sortkey
-                bibkey = entrycont['key']
-            entry.insert(0, sortkey)
-            entry.insert(1, bibkey)
-            entry.insert(2, entryid)
-           
-            # add the entry to the file contents
-            filecont.append(entry)
-
-        else:
-            # field, publication info
-            field = ''
-            data = ''
-            
-            # field = {data} entries
-            if bracedata_rex.match(line):
-                field = bracefield_rex.sub('\g<1>', line)
-                field = string.lower(field)
-                data =  bracedata_rex.sub('\g<2>', line)
-
-            # field = "data" entries
-            elif quotedata_rex.match(line):
-                field = quotefield_rex.sub('\g<1>', line)
-                field = string.lower(field)
-                data =  quotedata_rex.sub('\g<2>', line)
-
-            # field = data entries
-            elif data_rex.match(line):
-                field = field_rex.sub('\g<1>', line)
-                field = string.lower(field)
-                data =  data_rex.sub('\g<2>', line)
-
-            if field == 'url':
-                data = '\\url{' + data.strip() + '}'
-            
-            if field in ('author', 'editor'):
-                entrycont[field] = bibtexauthor(data)
-                line = ''
-            elif field == 'title':
-                line = bibtextitle(data, entrytype)
-            elif field != '':
-                line = removebraces(transformurls(data.strip()))
-
-            if line != '':
-                line = latexreplacements(line)
-                entrycont[field] = line
-
-
-    # sort entries
-    filecont.sort(entry_cmp)
-    
-    # count the bibtex keys
-    keytable = {}
-    counttable = {}
-    for entry in filecont:
-        bibkey = entry[1]
-        if not keytable.has_key(bibkey):
-            keytable[bibkey] = 1
-        else:
-            keytable[bibkey] += 1
-
-    for bibkey in keytable.keys():
-        counttable[bibkey] = 0
-    
-    # generate output
-    for entry in filecont:
-        # generate output key form the bibtex key
-        bibkey = entry[1]
-        entryid = entry[2]
-        if keytable[bibkey] == 1:
-            outkey = bibkey
-        else:
-            outkey = bibkey + chr(97 + counttable[bibkey])
-        counttable[bibkey] += 1
-        
-        # append the entry code to the output
-        file.append('\\section ' + entryid + ' [' + outkey + ']')
-        file.append('<div style="' + divstyle + '">')
-        for line in entry[3:]:
-            file.append(line)
-        file.append('</div>')
-        file.append('')
-
-    return file
-
-
-#
-# return 1 iff abbr is in line but not inside braces or quotes
-# assumes that abbr appears only once on the line (out of braces and quotes)
-#
-def verify_out_of_braces(line, abbr):
-
-    phrase_split = delimiter_rex.split(line)
-
-    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
-
-    open_brace = 0
-    open_quote = 0
-
-    for phrase in phrase_split:
-        if phrase == "{":
-            open_brace = open_brace + 1
-        elif phrase == "}":
-            open_brace = open_brace - 1
-        elif phrase == '"':
-            if open_quote == 1:
-                open_quote = 0
-            else:
-                open_quote = 1
-        elif abbr_rex.search(phrase):
-            if open_brace == 0 and open_quote == 0:
-                return 1
-
-    return 0
-
-
-#
-# a line in the form phrase1 # phrase2 # ... # phrasen
-# is returned as phrase1 phrase2 ... phrasen
-# with the correct punctuation
-# Bug: Doesn't always work with multiple abbreviations plugged in
-#
-def concat_line(line):
-    # only look at part after equals
-    field = field_rex.sub('\g<1>',line)
-    rest = field_rex.sub('\g<2>',line)
-
-    concat_line = field + ' ='
-
-    pound_split = concatsplit_rex.split(rest)
-
-    phrase_count = 0
-    length = len(pound_split)
-
-    for phrase in pound_split:
-        phrase = phrase.strip()
-        if phrase_count != 0:
-            if phrase.startswith('"') or phrase.startswith('{'):
-                phrase = phrase[1:]
-        elif phrase.startswith('"'):
-            phrase = phrase.replace('"','{',1)
-
-        if phrase_count != length-1:
-            if phrase.endswith('"') or phrase.endswith('}'):
-                phrase = phrase[:-1]
-        else:
-            if phrase.endswith('"'):
-                phrase = phrase[:-1]
-                phrase = phrase + "}"
-            elif phrase.endswith('",'):
-                phrase = phrase[:-2]
-                phrase = phrase + "},"
-
-        # if phrase did have \#, add the \# back
-        if phrase.endswith('\\'):
-            phrase = phrase + "#"
-        concat_line = concat_line + ' ' + phrase
-
-        phrase_count = phrase_count + 1
-
-    return concat_line
-
-
-#
-# substitute abbreviations into filecont
-# @param filecont_source - string of data from file
-#
-def bibtex_replace_abbreviations(filecont_source):
-    filecont = filecont_source.splitlines()
-
-    #  These are defined in bibtex, so we'll define them too
-    abbr_list = ['jan','feb','mar','apr','may','jun',
-                 'jul','aug','sep','oct','nov','dec']
-    value_list = ['January','February','March','April',
-                  'May','June','July','August','September',
-                  'October','November','December']
-
-    abbr_rex = []
-    total_abbr_count = 0
-
-    front = '\\b'
-    back = '(,?)\\b'
-
-    for x in abbr_list:
-        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
-        total_abbr_count = total_abbr_count + 1
-
-
-    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
-                             re.I)
-
-    comment_rex = re.compile('@comment\s*{',re.I)
-    preamble_rex = re.compile('@preamble\s*{',re.I)
-
-    waiting_for_end_string = 0
-    i = 0
-    filecont2 = ''
-
-    for line in filecont:
-        if line == ' ' or line == '':
-            continue
-
-        if waiting_for_end_string:
-            if re.search('}',line):
-                waiting_for_end_string = 0
-                continue
-
-        if abbrdef_rex.search(line):
-            abbr = abbrdef_rex.sub('\g<1>', line)
-
-            if abbr_list.count(abbr) == 0:
-                val = abbrdef_rex.sub('\g<2>', line)
-                abbr_list.append(abbr)
-                value_list.append(string.strip(val))
-                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
-                total_abbr_count = total_abbr_count + 1
-            waiting_for_end_string = 1
-            continue
-
-        if comment_rex.search(line):
-            waiting_for_end_string = 1
-            continue
-
-        if preamble_rex.search(line):
-            waiting_for_end_string = 1
-            continue
-
-
-        # replace subsequent abbreviations with the value
-        abbr_count = 0
-
-        for x in abbr_list:
-
-            if abbr_rex[abbr_count].search(line):
-                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
-                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
-                # Check for # concatenations
-                if concatsplit_rex.search(line):
-                    line = concat_line(line)
-            abbr_count = abbr_count + 1
-
-
-        filecont2 = filecont2 + line + '\n'
-        i = i+1
-
-
-    # Do one final pass over file
-
-    # make sure that didn't end up with {" or }" after the substitution
-    filecont2 = filecont2.replace('{"','{{')
-    filecont2 = filecont2.replace('"}','}}')
-
-    afterquotevalue_rex = re.compile('"\s*,\s*')
-    afterbrace_rex = re.compile('"\s*}')
-    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
-
-    # add new lines to data that changed because of abbreviation substitutions
-    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
-    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
-    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
-
-    return filecont2
-
-#
-# convert @type( ... ) to @type{ ... }
-#
-def no_outer_parens(filecont):
-
-    # do checking for open parens
-    # will convert to braces
-    paren_split = re.split('([(){}])',filecont)
-
-    open_paren_count = 0
-    open_type = 0
-    look_next = 0
-
-    # rebuild filecont
-    filecont = ''
-
-    at_rex = re.compile('@\w*')
-
-    for phrase in paren_split:
-        if look_next == 1:
-            if phrase == '(':
-                phrase = '{'
-                open_paren_count = open_paren_count + 1
-            else:
-                open_type = 0
-            look_next = 0
-
-        if phrase == '(':
-            open_paren_count = open_paren_count + 1
-
-        elif phrase == ')':
-            open_paren_count = open_paren_count - 1
-            if open_type == 1 and open_paren_count == 0:
-                phrase = '}'
-                open_type = 0
-
-        elif at_rex.search( phrase ):
-            open_type = 1
-            look_next = 1
-
-        filecont = filecont + phrase
-
-    return filecont
-
-
-#
-# make all whitespace into just one space
-# format the bibtex file into a usable form.
-#
-def bibtexwasher(filecont_source):
-
-    space_rex = re.compile('\s+')
-    comment_rex = re.compile('\s*%')
-
-    filecont = []
-
-    # remove trailing and excessive whitespace
-    # ignore comments
-    for line in filecont_source:
-        line = string.strip(line)
-        line = space_rex.sub(' ', line)
-        # ignore comments
-        if not comment_rex.match(line) and line != '':
-            filecont.append(' '+ line)
-
-    filecont = string.join(filecont, '')
-
-    # the file is in one long string
-
-    filecont = no_outer_parens(filecont)
-
-    #
-    # split lines according to preferred syntax scheme
-    #
-    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
-
-    # add new lines after commas that are after values
-    filecont = re.sub('"\s*,', '",\n', filecont)
-    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
-    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
-                          '\n\n\g<1>\g<2>,\n', filecont)
-
-    # add new lines after }
-    filecont = re.sub('"\s*}','"\n}\n', filecont)
-    filecont = re.sub('}\s*,','},\n', filecont)
-
-
-    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
-
-    # character encoding, reserved latex characters
-    filecont = re.sub('{\\\&}', '&', filecont)
-    filecont = re.sub('\\\&', '&', filecont)
-
-    # do checking for open braces to get format correct
-    open_brace_count = 0
-    brace_split = re.split('([{}])',filecont)
-
-    # rebuild filecont
-    filecont = ''
-
-    for phrase in brace_split:
-        if phrase == '{':
-            open_brace_count = open_brace_count + 1
-        elif phrase == '}':
-            open_brace_count = open_brace_count - 1
-            if open_brace_count == 0:
-                filecont = filecont + '\n'
-
-        filecont = filecont + phrase
-
-    filecont2 = bibtex_replace_abbreviations(filecont)
-
-    # gather
-    filecont = filecont2.splitlines()
-    i=0
-    j=0         # count the number of blank lines
-    for line in filecont:
-        # ignore blank lines
-        if line == '' or line == ' ':
-            j = j+1
-            continue
-        filecont[i] = line + '\n'
-        i = i+1
-
-    # get rid of the extra stuff at the end of the array
-    # (The extra stuff are duplicates that are in the array because
-    # blank lines were removed.)
-    length = len( filecont)
-    filecont[length-j:length] = []
-
-    return filecont
-
-
-def filehandler(filepath):
-    try:
-        fd = open(filepath, 'r')
-        filecont_source = fd.readlines()
-        fd.close()
-    except:
-        print 'Could not open file:', filepath
-    washeddata = bibtexwasher(filecont_source)
-    outdata = bibtexdecoder(washeddata)
-    print '/**'
-    print '\page references References'
-    print
-    for line in outdata:
-        print line
-    print '*/'
-
-
-# main program
-
-def main():
-    import sys
-    if sys.argv[1:]:
-        filepath = sys.argv[1]
-    else:
-        print "No input file"
-        sys.exit()
-    filehandler(filepath)
-
-if __name__ == "__main__": main()
-
-
-# end python script
Index: ripts/bootstrap.sh
===================================================================
--- scripts/bootstrap.sh	(revision 923)
+++ 	(revision )
@@ -1,157 +1,0 @@
-#!/bin/bash
-#
-# This file is a part of LEMON, a generic C++ optimization library.
-#
-# Copyright (C) 2003-2009
-# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
-# (Egervary Research Group on Combinatorial Optimization, EGRES).
-#
-# Permission to use, modify and distribute this software is granted
-# provided that this copyright notice appears in all copies. For
-# precise terms see the accompanying LICENSE file.
-#
-# This software is provided "AS IS" with no warranty of any kind,
-# express or implied, and with no claim as to its suitability for any
-# purpose.
-
-
-if [ ! -f ~/.lemon-bootstrap ]; then
-    echo 'Create ~/.lemon-bootstrap'.
-    cat >~/.lemon-bootstrap <<EOF
-#
-# Default settings for bootstraping the LEMON source code repository
-#
-EOF
-fi
-
-source ~/.lemon-bootstrap
-if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
-if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
-if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
-if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
-
-
-function augment_config() { 
-    if [ "x${!1}" == "x" ]; then
-        eval $1=$2
-        echo Add "'$1'" to '~/.lemon-bootstrap'.
-        echo >>~/.lemon-bootstrap
-        echo $3 >>~/.lemon-bootstrap
-        echo $1=$2 >>~/.lemon-bootstrap
-    fi
-}
-
-augment_config LEMON_INSTALL_PREFIX /usr/local \
-    "# LEMON installation prefix"
-
-augment_config GLPK_PREFIX /usr/local/ \
-    "# GLPK installation root prefix"
-
-augment_config COIN_OR_PREFIX /usr/local/coin-or \
-    "# COIN-OR installation root prefix (used for CLP/CBC)"
-
-augment_config SOPLEX_PREFIX /usr/local/soplex \
-    "# Soplex build prefix"
-
-
-function ask() {
-echo -n "$1 [$2]? "
-read _an
-if [ "x$_an" == "x" ]; then
-    ret="$2"
-else
-    ret=$_an
-fi
-}
-
-function yesorno() {
-    ret='rossz'
-    while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
-        ask "$1" "$2"
-    done
-    if [ "$ret" != "y" -a "$ret" != "yes" ]; then
-        return 1
-    else
-        return 0
-    fi
-}
-
-if yesorno "External build" "n"
-then
-    CONFIGURE_PATH=".."
-else
-    CONFIGURE_PATH="."
-    if yesorno "Autoreconf" "y"
-    then
-        AUTORE=yes
-    else
-        AUTORE=no
-    fi
-fi
-
-if yesorno "Optimize" "n" 
-then
-    opt_flags=' -O2'
-else
-    opt_flags=''
-fi
-
-if yesorno "Stop on warning" "y" 
-then
-    werror_flags=' -Werror'
-else
-    werror_flags=''
-fi
-
-cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
-
-if yesorno "Check with valgrind" "n" 
-then
-    valgrind_flags=' --enable-valgrind'
-else
-    valgrind_flags=''
-fi
-
-if [ -f ${GLPK_PREFIX}/include/glpk.h ]; then
-    if yesorno "Use GLPK" "y"
-    then
-        glpk_flag="--with-glpk=$GLPK_PREFIX"
-    else
-        glpk_flag="--without-glpk"
-    fi
-else
-    glpk_flag="--without-glpk"        
-fi
-
-if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
-    if yesorno "Use COIN-OR (CBC/CLP)" "n"
-    then
-        coin_flag="--with-coin=$COIN_OR_PREFIX"
-    else
-        coin_flag="--without-coin"
-    fi
-else
-    coin_flag="--without-coin"        
-fi
-
-if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
-    if yesorno "Use Soplex" "n"
-    then
-        soplex_flag="--with-soplex=$SOPLEX_PREFIX"
-    else
-        soplex_flag="--without-soplex"
-    fi
-else
-    soplex_flag="--without-soplex"
-fi
-
-if [ "x$AUTORE" == "xyes" ]; then
-    autoreconf -vif;
-fi
-${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
-$valgrind_flags \
-"$cxx_flags" \
-$glpk_flag \
-$coin_flag \
-$soplex_flag \
-$*
Index: ripts/chg-len.py
===================================================================
--- scripts/chg-len.py	(revision 780)
+++ 	(revision )
@@ -1,46 +1,0 @@
-#! /usr/bin/env python
-#
-# This file is a part of LEMON, a generic C++ optimization library.
-#
-# Copyright (C) 2003-2009
-# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
-# (Egervary Research Group on Combinatorial Optimization, EGRES).
-#
-# Permission to use, modify and distribute this software is granted
-# provided that this copyright notice appears in all copies. For
-# precise terms see the accompanying LICENSE file.
-#
-# This software is provided "AS IS" with no warranty of any kind,
-# express or implied, and with no claim as to its suitability for any
-# purpose.
-
-import sys
-
-from mercurial import ui, hg
-from mercurial import util
-
-util.rcpath = lambda : []
-
-if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
-    print """
-This utility just prints the length of the longest path
-in the revision graph from revison 0 to the current one.
-"""
-    exit(0)
-
-u = ui.ui()
-r = hg.repository(u, ".")
-N = r.changectx(".").rev()
-lengths=[0]*(N+1)
-for i in range(N+1):
-    p=r.changectx(i).parents()
-    if p[0]:
-        p0=lengths[p[0].rev()]
-    else:
-        p0=-1
-    if len(p)>1 and p[1]:
-        p1=lengths[p[1].rev()]
-    else:
-        p1=-1
-    lengths[i]=max(p0,p1)+1
-print lengths[N]
Index: ripts/mk-release.sh
===================================================================
--- scripts/mk-release.sh	(revision 780)
+++ 	(revision )
@@ -1,49 +1,0 @@
-#!/bin/bash
-#
-# This file is a part of LEMON, a generic C++ optimization library.
-#
-# Copyright (C) 2003-2009
-# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
-# (Egervary Research Group on Combinatorial Optimization, EGRES).
-#
-# Permission to use, modify and distribute this software is granted
-# provided that this copyright notice appears in all copies. For
-# precise terms see the accompanying LICENSE file.
-#
-# This software is provided "AS IS" with no warranty of any kind,
-# express or implied, and with no claim as to its suitability for any
-# purpose.
-
-set -e
-
-if [ $# = 0 ]; then
-    echo "Usage: $0 release-id"
-    exit 1
-else
-    export LEMON_VERSION=$1
-fi
-
-echo '*****************************************************************'
-echo ' Start making release tarballs for version '${LEMON_VERSION}
-echo '*****************************************************************'
-
-autoreconf -vif
-./configure
-
-make
-make html
-make distcheck
-tar xf lemon-${LEMON_VERSION}.tar.gz
-zip -r lemon-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
-mv lemon-${LEMON_VERSION}/doc/html lemon-doc-${LEMON_VERSION}
-tar czf lemon-doc-${LEMON_VERSION}.tar.gz lemon-doc-${LEMON_VERSION}
-zip -r lemon-doc-${LEMON_VERSION}.zip lemon-doc-${LEMON_VERSION}
-tar czf lemon-nodoc-${LEMON_VERSION}.tar.gz lemon-${LEMON_VERSION}
-zip -r lemon-nodoc-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
-hg tag -m 'LEMON '${LEMON_VERSION}' released ('$(hg par --template="{node|short}")' tagged as r'${LEMON_VERSION}')' r${LEMON_VERSION}
-
-rm -rf lemon-${LEMON_VERSION} lemon-doc-${LEMON_VERSION}
-
-echo '*****************************************************************'
-echo '  Release '${LEMON_VERSION}' has been created' 
-echo '*****************************************************************'
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 1161)
+++ test/CMakeLists.txt	(revision 1264)
@@ -17,4 +17,5 @@
   bellman_ford_test
   bfs_test
+  bpgraph_test
   circulation_test
   connectivity_test
@@ -35,17 +36,22 @@
   heap_test
   kruskal_test
+  lgf_reader_writer_test
   lgf_test
   maps_test
   matching_test
+  max_cardinality_search_test
+  max_clique_test
+  max_flow_test
   min_cost_arborescence_test
   min_cost_flow_test
   min_mean_cycle_test
+  nagamochi_ibaraki_test
   path_test
   planarity_test
-  preflow_test
   radix_sort_test
   random_test
   suurballe_test
   time_measure_test
+  tsp_test
   unionfind_test
 )
@@ -64,8 +70,11 @@
   ENDIF()
   IF(LEMON_HAVE_CPLEX)
-    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${ILOG_LIBRARIES})
   ENDIF()
   IF(LEMON_HAVE_CLP)
     SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_SOPLEX)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${SOPLEX_LIBRARIES})
   ENDIF()
 
@@ -88,5 +97,5 @@
     GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
     ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
-      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
     )
   ENDIF()
@@ -106,5 +115,5 @@
   ENDIF()
   IF(LEMON_HAVE_CPLEX)
-    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${ILOG_LIBRARIES})
   ENDIF()
   IF(LEMON_HAVE_CBC)
@@ -130,5 +139,5 @@
     GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
     ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
-      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
     )
   ENDIF()
Index: st/Makefile.am
===================================================================
--- test/Makefile.am	(revision 1324)
+++ 	(revision )
@@ -1,103 +1,0 @@
-if USE_VALGRIND
-TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
-endif
-
-EXTRA_DIST += \
-	test/CMakeLists.txt
-
-noinst_HEADERS += \
-	test/graph_test.h \
-	test/test_tools.h
-
-check_PROGRAMS += \
-	test/adaptors_test \
-	test/arc_lookup_test \
-	test/bellman_ford_test \
-	test/bfs_test \
-	test/circulation_test \
-	test/connectivity_test \
-	test/counter_test \
-	test/dfs_test \
-	test/digraph_test \
-	test/dijkstra_test \
-	test/dim_test \
-	test/edge_set_test \
-	test/error_test \
-	test/euler_test \
-	test/fractional_matching_test \
-	test/gomory_hu_test \
-	test/graph_copy_test \
-	test/graph_test \
-	test/graph_utils_test \
-	test/hao_orlin_test \
-	test/heap_test \
-	test/kruskal_test \
-	test/lgf_test \
-	test/maps_test \
-	test/matching_test \
-	test/min_cost_arborescence_test \
-	test/min_cost_flow_test \
-	test/min_mean_cycle_test \
-	test/path_test \
-	test/planarity_test \
-	test/preflow_test \
-	test/radix_sort_test \
-	test/random_test \
-	test/suurballe_test \
-	test/test_tools_fail \
-	test/test_tools_pass \
-	test/time_measure_test \
-	test/unionfind_test
-
-test_test_tools_pass_DEPENDENCIES = demo
-
-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_adaptors_test_SOURCES = test/arc_lookup_test.cc
-test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
-test_bfs_test_SOURCES = test/bfs_test.cc
-test_circulation_test_SOURCES = test/circulation_test.cc
-test_counter_test_SOURCES = test/counter_test.cc
-test_connectivity_test_SOURCES = test/connectivity_test.cc
-test_dfs_test_SOURCES = test/dfs_test.cc
-test_digraph_test_SOURCES = test/digraph_test.cc
-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_euler_test_SOURCES = test/euler_test.cc
-test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
-test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
-test_graph_copy_test_SOURCES = test/graph_copy_test.cc
-test_graph_test_SOURCES = test/graph_test.cc
-test_graph_utils_test_SOURCES = test/graph_utils_test.cc
-test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
-test_heap_test_SOURCES = test/heap_test.cc
-test_kruskal_test_SOURCES = test/kruskal_test.cc
-test_lgf_test_SOURCES = test/lgf_test.cc
-test_lp_test_SOURCES = test/lp_test.cc
-test_maps_test_SOURCES = test/maps_test.cc
-test_mip_test_SOURCES = test/mip_test.cc
-test_matching_test_SOURCES = test/matching_test.cc
-test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
-test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
-test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
-test_path_test_SOURCES = test/path_test.cc
-test_planarity_test_SOURCES = test/planarity_test.cc
-test_preflow_test_SOURCES = test/preflow_test.cc
-test_radix_sort_test_SOURCES = test/radix_sort_test.cc
-test_suurballe_test_SOURCES = test/suurballe_test.cc
-test_random_test_SOURCES = test/random_test.cc
-test_test_tools_fail_SOURCES = test/test_tools_fail.cc
-test_test_tools_pass_SOURCES = test/test_tools_pass.cc
-test_time_measure_test_SOURCES = test/time_measure_test.cc
-test_unionfind_test_SOURCES = test/unionfind_test.cc
Index: test/adaptors_test.cc
===================================================================
--- test/adaptors_test.cc	(revision 1259)
+++ test/adaptors_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/arc_look_up_test.cc
===================================================================
--- test/arc_look_up_test.cc	(revision 1149)
+++ test/arc_look_up_test.cc	(revision 1312)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -25,5 +25,4 @@
 using namespace lemon;
 
-const int lgfn = 4;
 const std::string lgf =
   "@nodes\n"
@@ -69,15 +68,15 @@
   std::istringstream lgfs(lgf);
   DigraphReader<ListDigraph>(graph, lgfs).run();
-  
+
   AllArcLookUp<ListDigraph> lookup(graph);
-	
+
   int numArcs = countArcs(graph);
-	
+
   int arcCnt = 0;
   for(ListDigraph::NodeIt n1(graph); n1 != INVALID; ++n1)
     for(ListDigraph::NodeIt n2(graph); n2 != INVALID; ++n2)
       for(ListDigraph::Arc a = lookup(n1, n2); a != INVALID;
-	  a = lookup(n1, n2, a))
-	++arcCnt;
+          a = lookup(n1, n2, a))
+        ++arcCnt;
   check(arcCnt==numArcs, "Wrong total number of arcs");
 
Index: test/bellman_ford_test.cc
===================================================================
--- test/bellman_ford_test.cc	(revision 1260)
+++ test/bellman_ford_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/bfs_test.cc
===================================================================
--- test/bfs_test.cc	(revision 1259)
+++ test/bfs_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/bpgraph_test.cc
===================================================================
--- test/bpgraph_test.cc	(revision 1292)
+++ test/bpgraph_test.cc	(revision 1292)
@@ -0,0 +1,456 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/bpgraph.h>
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/full_graph.h>
+
+#include "test_tools.h"
+#include "graph_test.h"
+
+using namespace lemon;
+using namespace lemon::concepts;
+
+template <class BpGraph>
+void checkBpGraphBuild() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  checkGraphNodeList(G, 0);
+  checkGraphRedNodeList(G, 0);
+  checkGraphBlueNodeList(G, 0);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  G.reserveNode(3);
+  G.reserveEdge(3);
+
+  RedNode
+    rn1 = G.addRedNode();
+  checkGraphNodeList(G, 1);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 0);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  BlueNode
+    bn1 = G.addBlueNode(),
+    bn2 = G.addBlueNode();
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  Edge e1 = G.addEdge(rn1, bn2);
+  check(G.redNode(e1) == rn1 && G.blueNode(e1) == bn2, "Wrong edge");
+  check(G.u(e1) == rn1 && G.v(e1) == bn2, "Wrong edge");
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 1);
+  checkGraphArcList(G, 2);
+
+  checkGraphIncEdgeArcLists(G, rn1, 1);
+  checkGraphIncEdgeArcLists(G, bn1, 0);
+  checkGraphIncEdgeArcLists(G, bn2, 1);
+
+  checkGraphConEdgeList(G, 1);
+  checkGraphConArcList(G, 2);
+
+  Edge
+    e2 = G.addEdge(bn1, rn1),
+    e3 = G.addEdge(rn1, bn2);
+  ::lemon::ignore_unused_variable_warning(e2,e3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, rn1, 3);
+  checkGraphIncEdgeArcLists(G, bn1, 1);
+  checkGraphIncEdgeArcLists(G, bn2, 2);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkRedNodeIds(G);
+  checkBlueNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+
+  checkGraphNodeMap(G);
+  checkGraphRedNodeMap(G);
+  checkGraphBlueNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+}
+
+template <class BpGraph>
+void checkBpGraphErase() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  RedNode
+    n1 = G.addRedNode(), n4 = G.addRedNode();
+  BlueNode
+    n2 = G.addBlueNode(), n3 = G.addBlueNode();
+  Edge
+    e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3),
+    e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e3,e4);
+
+  // Check edge deletion
+  G.erase(e2);
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+  checkGraphIncEdgeArcLists(G, n4, 2);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+
+  // Check node deletion
+  G.erase(n3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 1);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n4, 1);
+
+  checkGraphConEdgeList(G, 2);
+  checkGraphConArcList(G, 4);
+
+}
+
+template <class BpGraph>
+void checkBpGraphAlter() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  RedNode
+    n1 = G.addRedNode(), n4 = G.addRedNode();
+  BlueNode
+    n2 = G.addBlueNode(), n3 = G.addBlueNode();
+  Edge
+    e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3),
+    e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e3,e4);
+
+  G.changeRed(e2, n4);
+  check(G.redNode(e2) == n4, "Wrong red node");
+  check(G.blueNode(e2) == n3, "Wrong blue node");
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n3, 2);
+  checkGraphIncEdgeArcLists(G, n4, 3);
+
+  checkGraphConEdgeList(G, 4);
+  checkGraphConArcList(G, 8);
+
+  G.changeBlue(e2, n2);
+  check(G.redNode(e2) == n4, "Wrong red node");
+  check(G.blueNode(e2) == n2, "Wrong blue node");
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+  checkGraphIncEdgeArcLists(G, n4, 3);
+
+  checkGraphConEdgeList(G, 4);
+  checkGraphConArcList(G, 8);
+}
+
+
+template <class BpGraph>
+void checkBpGraphSnapshot() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  RedNode
+    n1 = G.addRedNode();
+  BlueNode
+    n2 = G.addBlueNode(),
+    n3 = G.addBlueNode();
+  Edge
+    e1 = G.addEdge(n1, n2),
+    e2 = G.addEdge(n1, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e2);
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  typename BpGraph::Snapshot snapshot(G);
+
+  RedNode n4 = G.addRedNode();
+  G.addEdge(n4, n2);
+  G.addEdge(n4, n3);
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 1);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+
+  checkGraphConEdgeList(G, 2);
+  checkGraphConArcList(G, 4);
+
+  checkNodeIds(G);
+  checkRedNodeIds(G);
+  checkBlueNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+
+  checkGraphNodeMap(G);
+  checkGraphRedNodeMap(G);
+  checkGraphBlueNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+  G.addRedNode();
+  snapshot.save(G);
+
+  G.addEdge(G.addRedNode(), G.addBlueNode());
+
+  snapshot.restore();
+  snapshot.save(G);
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  G.addEdge(G.addRedNode(), G.addBlueNode());
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+}
+
+template <typename BpGraph>
+void checkBpGraphValidity() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+  BpGraph g;
+
+  RedNode
+    n1 = g.addRedNode();
+  BlueNode
+    n2 = g.addBlueNode(),
+    n3 = g.addBlueNode();
+
+  Edge
+    e1 = g.addEdge(n1, n2),
+    e2 = g.addEdge(n1, n3);
+  ::lemon::ignore_unused_variable_warning(e2);
+
+  check(g.valid(n1), "Wrong validity check");
+  check(g.valid(e1), "Wrong validity check");
+  check(g.valid(g.direct(e1, true)), "Wrong validity check");
+
+  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
+}
+
+void checkConcepts() {
+  { // Checking graph components
+    checkConcept<BaseBpGraphComponent, BaseBpGraphComponent >();
+
+    checkConcept<IDableBpGraphComponent<>,
+      IDableBpGraphComponent<> >();
+
+    checkConcept<IterableBpGraphComponent<>,
+      IterableBpGraphComponent<> >();
+
+    checkConcept<AlterableBpGraphComponent<>,
+      AlterableBpGraphComponent<> >();
+
+    checkConcept<MappableBpGraphComponent<>,
+      MappableBpGraphComponent<> >();
+
+    checkConcept<ExtendableBpGraphComponent<>,
+      ExtendableBpGraphComponent<> >();
+
+    checkConcept<ErasableBpGraphComponent<>,
+      ErasableBpGraphComponent<> >();
+
+    checkConcept<ClearableBpGraphComponent<>,
+      ClearableBpGraphComponent<> >();
+
+  }
+  { // Checking skeleton graph
+    checkConcept<BpGraph, BpGraph>();
+  }
+  { // Checking SmartBpGraph
+    checkConcept<BpGraph, SmartBpGraph>();
+    checkConcept<AlterableBpGraphComponent<>, SmartBpGraph>();
+    checkConcept<ExtendableBpGraphComponent<>, SmartBpGraph>();
+    checkConcept<ClearableBpGraphComponent<>, SmartBpGraph>();
+  }
+}
+
+void checkFullBpGraph(int redNum, int blueNum) {
+  typedef FullBpGraph BpGraph;
+  BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G(redNum, blueNum);
+  checkGraphNodeList(G, redNum + blueNum);
+  checkGraphRedNodeList(G, redNum);
+  checkGraphBlueNodeList(G, blueNum);
+  checkGraphEdgeList(G, redNum * blueNum);
+  checkGraphArcList(G, 2 * redNum * blueNum);
+
+  G.resize(redNum, blueNum);
+  checkGraphNodeList(G, redNum + blueNum);
+  checkGraphRedNodeList(G, redNum);
+  checkGraphBlueNodeList(G, blueNum);
+  checkGraphEdgeList(G, redNum * blueNum);
+  checkGraphArcList(G, 2 * redNum * blueNum);
+
+  for (RedNodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, blueNum);
+    checkGraphInArcList(G, n, blueNum);
+    checkGraphIncEdgeList(G, n, blueNum);
+  }
+
+  for (BlueNodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, redNum);
+    checkGraphInArcList(G, n, redNum);
+    checkGraphIncEdgeList(G, n, redNum);
+  }
+
+  checkGraphConArcList(G, 2 * redNum * blueNum);
+  checkGraphConEdgeList(G, redNum * blueNum);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkRedNodeIds(G);
+  checkBlueNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+
+  checkGraphNodeMap(G);
+  checkGraphRedNodeMap(G);
+  checkGraphBlueNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+  for (int i = 0; i < G.redNum(); ++i) {
+    check(G.red(G.redNode(i)), "Wrong node");
+    check(G.index(G.redNode(i)) == i, "Wrong index");
+  }
+
+  for (int i = 0; i < G.blueNum(); ++i) {
+    check(G.blue(G.blueNode(i)), "Wrong node");
+    check(G.index(G.blueNode(i)) == i, "Wrong index");
+  }
+
+  for (NodeIt u(G); u != INVALID; ++u) {
+    for (NodeIt v(G); v != INVALID; ++v) {
+      Edge e = G.edge(u, v);
+      Arc a = G.arc(u, v);
+      if (G.red(u) == G.red(v)) {
+        check(e == INVALID, "Wrong edge lookup");
+        check(a == INVALID, "Wrong arc lookup");
+      } else {
+        check((G.u(e) == u && G.v(e) == v) ||
+              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
+        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
+      }
+    }
+  }
+
+}
+
+void checkGraphs() {
+  { // Checking ListGraph
+    checkBpGraphBuild<ListBpGraph>();
+    checkBpGraphErase<ListBpGraph>();
+    checkBpGraphAlter<ListBpGraph>();
+    checkBpGraphSnapshot<ListBpGraph>();
+    checkBpGraphValidity<ListBpGraph>();
+  }
+  { // Checking SmartGraph
+    checkBpGraphBuild<SmartBpGraph>();
+    checkBpGraphSnapshot<SmartBpGraph>();
+    checkBpGraphValidity<SmartBpGraph>();
+  }
+  { // Checking FullBpGraph
+    checkFullBpGraph(6, 8);
+    checkFullBpGraph(7, 4);
+  }
+}
+
+int main() {
+  checkConcepts();
+  checkGraphs();
+  return 0;
+}
Index: test/circulation_test.cc
===================================================================
--- test/circulation_test.cc	(revision 1259)
+++ test/circulation_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/connectivity_test.cc
===================================================================
--- test/connectivity_test.cc	(revision 1268)
+++ test/connectivity_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/dfs_test.cc
===================================================================
--- test/dfs_test.cc	(revision 1263)
+++ test/dfs_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 1260)
+++ test/digraph_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/dijkstra_test.cc
===================================================================
--- test/dijkstra_test.cc	(revision 1259)
+++ test/dijkstra_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/edge_set_test.cc
===================================================================
--- test/edge_set_test.cc	(revision 1259)
+++ test/edge_set_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/euler_test.cc
===================================================================
--- test/euler_test.cc	(revision 1259)
+++ test/euler_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -103,5 +103,5 @@
     Digraph::Node n = d.addNode();
     ::lemon::ignore_unused_variable_warning(n);
-  
+
     checkDiEulerIt(d);
     checkDiEulerIt(g);
Index: test/fractional_matching_test.cc
===================================================================
--- test/fractional_matching_test.cc	(revision 1260)
+++ test/fractional_matching_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/gomory_hu_test.cc
===================================================================
--- test/gomory_hu_test.cc	(revision 1259)
+++ test/gomory_hu_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/graph_copy_test.cc
===================================================================
--- test/graph_copy_test.cc	(revision 1081)
+++ test/graph_copy_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -19,4 +19,5 @@
 #include <lemon/smart_graph.h>
 #include <lemon/list_graph.h>
+#include <lemon/static_graph.h>
 #include <lemon/lgf_reader.h>
 #include <lemon/error.h>
@@ -27,4 +28,5 @@
 using namespace lemon;
 
+template <typename GR>
 void digraph_copy_test() {
   const int nn = 10;
@@ -54,15 +56,15 @@
 
   // Test digraph copy
-  ListDigraph to;
-  ListDigraph::NodeMap<int> tnm(to);
-  ListDigraph::ArcMap<int> tam(to);
-  ListDigraph::Node tn;
-  ListDigraph::Arc ta;
-
-  SmartDigraph::NodeMap<ListDigraph::Node> nr(from);
-  SmartDigraph::ArcMap<ListDigraph::Arc> er(from);
-
-  ListDigraph::NodeMap<SmartDigraph::Node> ncr(to);
-  ListDigraph::ArcMap<SmartDigraph::Arc> ecr(to);
+  GR to;
+  typename GR::template NodeMap<int> tnm(to);
+  typename GR::template ArcMap<int> tam(to);
+  typename GR::Node tn;
+  typename GR::Arc ta;
+
+  SmartDigraph::NodeMap<typename GR::Node> nr(from);
+  SmartDigraph::ArcMap<typename GR::Arc> er(from);
+
+  typename GR::template NodeMap<SmartDigraph::Node> ncr(to);
+  typename GR::template ArcMap<SmartDigraph::Arc> ecr(to);
 
   digraphCopy(from, to).
@@ -87,9 +89,9 @@
   }
 
-  for (ListDigraph::NodeIt it(to); it != INVALID; ++it) {
+  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
     check(nr[ncr[it]] == it, "Wrong copy.");
   }
 
-  for (ListDigraph::ArcIt it(to); it != INVALID; ++it) {
+  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
     check(er[ecr[it]] == it, "Wrong copy.");
   }
@@ -104,4 +106,5 @@
 }
 
+template <typename GR>
 void graph_copy_test() {
   const int nn = 10;
@@ -136,19 +139,19 @@
 
   // Test graph copy
-  ListGraph to;
-  ListGraph::NodeMap<int> tnm(to);
-  ListGraph::ArcMap<int> tam(to);
-  ListGraph::EdgeMap<int> tem(to);
-  ListGraph::Node tn;
-  ListGraph::Arc ta;
-  ListGraph::Edge te;
-
-  SmartGraph::NodeMap<ListGraph::Node> nr(from);
-  SmartGraph::ArcMap<ListGraph::Arc> ar(from);
-  SmartGraph::EdgeMap<ListGraph::Edge> er(from);
-
-  ListGraph::NodeMap<SmartGraph::Node> ncr(to);
-  ListGraph::ArcMap<SmartGraph::Arc> acr(to);
-  ListGraph::EdgeMap<SmartGraph::Edge> ecr(to);
+  GR to;
+  typename GR::template NodeMap<int> tnm(to);
+  typename GR::template ArcMap<int> tam(to);
+  typename GR::template EdgeMap<int> tem(to);
+  typename GR::Node tn;
+  typename GR::Arc ta;
+  typename GR::Edge te;
+
+  SmartGraph::NodeMap<typename GR::Node> nr(from);
+  SmartGraph::ArcMap<typename GR::Arc> ar(from);
+  SmartGraph::EdgeMap<typename GR::Edge> er(from);
+
+  typename GR::template NodeMap<SmartGraph::Node> ncr(to);
+  typename GR::template ArcMap<SmartGraph::Arc> acr(to);
+  typename GR::template EdgeMap<SmartGraph::Edge> ecr(to);
 
   graphCopy(from, to).
@@ -185,12 +188,12 @@
   }
 
-  for (ListGraph::NodeIt it(to); it != INVALID; ++it) {
+  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
     check(nr[ncr[it]] == it, "Wrong copy.");
   }
 
-  for (ListGraph::ArcIt it(to); it != INVALID; ++it) {
+  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
     check(ar[acr[it]] == it, "Wrong copy.");
   }
-  for (ListGraph::EdgeIt it(to); it != INVALID; ++it) {
+  for (typename GR::EdgeIt it(to); it != INVALID; ++it) {
     check(er[ecr[it]] == it, "Wrong copy.");
   }
@@ -207,8 +210,178 @@
 }
 
+template <typename GR>
+void bpgraph_copy_test() {
+  const int nn = 10;
+
+  // Build a graph
+  SmartBpGraph from;
+  SmartBpGraph::NodeMap<int> fnm(from);
+  SmartBpGraph::RedNodeMap<int> frnm(from);
+  SmartBpGraph::BlueNodeMap<int> fbnm(from);
+  SmartBpGraph::ArcMap<int> fam(from);
+  SmartBpGraph::EdgeMap<int> fem(from);
+  SmartBpGraph::Node fn = INVALID;
+  SmartBpGraph::RedNode frn = INVALID;
+  SmartBpGraph::BlueNode fbn = INVALID;
+  SmartBpGraph::Arc fa = INVALID;
+  SmartBpGraph::Edge fe = INVALID;
+
+  std::vector<SmartBpGraph::RedNode> frnv;
+  for (int i = 0; i < nn; ++i) {
+    SmartBpGraph::RedNode node = from.addRedNode();
+    frnv.push_back(node);
+    fnm[node] = i * i;
+    frnm[node] = i + i;
+    if (i == 0) {
+      fn = node;
+      frn = node;
+    }
+  }
+
+  std::vector<SmartBpGraph::BlueNode> fbnv;
+  for (int i = 0; i < nn; ++i) {
+    SmartBpGraph::BlueNode node = from.addBlueNode();
+    fbnv.push_back(node);
+    fnm[node] = i * i;
+    fbnm[node] = i + i;
+    if (i == 0) fbn = node;
+  }
+
+  for (int i = 0; i < nn; ++i) {
+    for (int j = 0; j < nn; ++j) {
+      SmartBpGraph::Edge edge = from.addEdge(frnv[i], fbnv[j]);
+      fem[edge] = i * i + j * j;
+      fam[from.direct(edge, true)] = i + j * j;
+      fam[from.direct(edge, false)] = i * i + j;
+      if (i == 0 && j == 0) fa = from.direct(edge, true);
+      if (i == 0 && j == 0) fe = edge;
+    }
+  }
+
+  // Test graph copy
+  GR to;
+  typename GR::template NodeMap<int> tnm(to);
+  typename GR::template RedNodeMap<int> trnm(to);
+  typename GR::template BlueNodeMap<int> tbnm(to);
+  typename GR::template ArcMap<int> tam(to);
+  typename GR::template EdgeMap<int> tem(to);
+  typename GR::Node tn;
+  typename GR::RedNode trn;
+  typename GR::BlueNode tbn;
+  typename GR::Arc ta;
+  typename GR::Edge te;
+
+  SmartBpGraph::NodeMap<typename GR::Node> nr(from);
+  SmartBpGraph::RedNodeMap<typename GR::RedNode> rnr(from);
+  SmartBpGraph::BlueNodeMap<typename GR::BlueNode> bnr(from);
+  SmartBpGraph::ArcMap<typename GR::Arc> ar(from);
+  SmartBpGraph::EdgeMap<typename GR::Edge> er(from);
+
+  typename GR::template NodeMap<SmartBpGraph::Node> ncr(to);
+  typename GR::template RedNodeMap<SmartBpGraph::RedNode> rncr(to);
+  typename GR::template BlueNodeMap<SmartBpGraph::BlueNode> bncr(to);
+  typename GR::template ArcMap<SmartBpGraph::Arc> acr(to);
+  typename GR::template EdgeMap<SmartBpGraph::Edge> ecr(to);
+
+  bpGraphCopy(from, to).
+    nodeMap(fnm, tnm).
+    redNodeMap(frnm, trnm).blueNodeMap(fbnm, tbnm).
+    arcMap(fam, tam).edgeMap(fem, tem).
+    nodeRef(nr).redRef(rnr).blueRef(bnr).
+    arcRef(ar).edgeRef(er).
+    nodeCrossRef(ncr).redCrossRef(rncr).blueCrossRef(bncr).
+    arcCrossRef(acr).edgeCrossRef(ecr).
+    node(fn, tn).redNode(frn, trn).blueNode(fbn, tbn).
+    arc(fa, ta).edge(fe, te).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countRedNodes(from) == countRedNodes(to), "Wrong copy.");
+  check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy.");
+  check(countEdges(from) == countEdges(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+
+  for (SmartBpGraph::NodeIt it(from); it != INVALID; ++it) {
+    check(ncr[nr[it]] == it, "Wrong copy.");
+    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
+  }
+
+  for (SmartBpGraph::RedNodeIt it(from); it != INVALID; ++it) {
+    check(ncr[nr[it]] == it, "Wrong copy.");
+    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
+    check(rnr[it] == nr[it], "Wrong copy.");
+    check(rncr[rnr[it]] == it, "Wrong copy.");
+    check(frnm[it] == trnm[rnr[it]], "Wrong copy.");
+    check(to.red(rnr[it]), "Wrong copy.");
+  }
+
+  for (SmartBpGraph::BlueNodeIt it(from); it != INVALID; ++it) {
+    check(ncr[nr[it]] == it, "Wrong copy.");
+    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
+    check(bnr[it] == nr[it], "Wrong copy.");
+    check(bncr[bnr[it]] == it, "Wrong copy.");
+    check(fbnm[it] == tbnm[bnr[it]], "Wrong copy.");
+    check(to.blue(bnr[it]), "Wrong copy.");
+  }
+
+  for (SmartBpGraph::ArcIt it(from); it != INVALID; ++it) {
+    check(acr[ar[it]] == it, "Wrong copy.");
+    check(fam[it] == tam[ar[it]], "Wrong copy.");
+    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
+    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
+  }
+
+  for (SmartBpGraph::EdgeIt it(from); it != INVALID; ++it) {
+    check(ecr[er[it]] == it, "Wrong copy.");
+    check(fem[it] == tem[er[it]], "Wrong copy.");
+    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
+          "Wrong copy.");
+    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
+          "Wrong copy.");
+    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
+          "Wrong copy.");
+  }
+
+  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
+    check(nr[ncr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::RedNodeIt it(to); it != INVALID; ++it) {
+    check(rncr[it] == ncr[it], "Wrong copy.");
+    check(rnr[rncr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::BlueNodeIt it(to); it != INVALID; ++it) {
+    check(bncr[it] == ncr[it], "Wrong copy.");
+    check(bnr[bncr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
+    check(ar[acr[it]] == it, "Wrong copy.");
+  }
+  for (typename GR::EdgeIt it(to); it != INVALID; ++it) {
+    check(er[ecr[it]] == it, "Wrong copy.");
+  }
+  check(tn == nr[fn], "Wrong copy.");
+  check(trn == rnr[frn], "Wrong copy.");
+  check(tbn == bnr[fbn], "Wrong copy.");
+  check(ta == ar[fa], "Wrong copy.");
+  check(te == er[fe], "Wrong copy.");
+
+  // Test repeated copy
+  bpGraphCopy(from, to).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countRedNodes(from) == countRedNodes(to), "Wrong copy.");
+  check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy.");
+  check(countEdges(from) == countEdges(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+}
+
 
 int main() {
-  digraph_copy_test();
-  graph_copy_test();
+  digraph_copy_test<SmartDigraph>();
+  digraph_copy_test<ListDigraph>();
+  digraph_copy_test<StaticDigraph>();
+  graph_copy_test<SmartGraph>();
+  graph_copy_test<ListGraph>();
+  bpgraph_copy_test<SmartBpGraph>();
+  bpgraph_copy_test<ListBpGraph>();
 
   return 0;
Index: test/graph_test.cc
===================================================================
--- test/graph_test.cc	(revision 1259)
+++ test/graph_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/graph_test.h
===================================================================
--- test/graph_test.h	(revision 463)
+++ test/graph_test.h	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -42,4 +42,40 @@
 
   template<class Graph>
+  void checkGraphRedNodeList(const Graph &G, int cnt)
+  {
+    typename Graph::RedNodeIt n(G);
+    for(int i=0;i<cnt;i++) {
+      check(n!=INVALID,"Wrong red Node list linking.");
+      check(G.red(n),"Wrong node set check.");
+      check(!G.blue(n),"Wrong node set check.");
+      typename Graph::Node nn = n;
+      check(G.asRedNodeUnsafe(nn) == n,"Wrong node conversion.");
+      check(G.asRedNode(nn) == n,"Wrong node conversion.");
+      check(G.asBlueNode(nn) == INVALID,"Wrong node conversion.");
+      ++n;
+    }
+    check(n==INVALID,"Wrong red Node list linking.");
+    check(countRedNodes(G)==cnt,"Wrong red Node number.");
+  }
+
+  template<class Graph>
+  void checkGraphBlueNodeList(const Graph &G, int cnt)
+  {
+    typename Graph::BlueNodeIt n(G);
+    for(int i=0;i<cnt;i++) {
+      check(n!=INVALID,"Wrong blue Node list linking.");
+      check(G.blue(n),"Wrong node set check.");
+      check(!G.red(n),"Wrong node set check.");
+      typename Graph::Node nn = n;
+      check(G.asBlueNodeUnsafe(nn) == n,"Wrong node conversion.");
+      check(G.asBlueNode(nn) == n,"Wrong node conversion.");
+      check(G.asRedNode(nn) == INVALID,"Wrong node conversion.");
+      ++n;
+    }
+    check(n==INVALID,"Wrong blue Node list linking.");
+    check(countBlueNodes(G)==cnt,"Wrong blue Node number.");
+  }
+
+  template<class Graph>
   void checkGraphArcList(const Graph &G, int cnt)
   {
@@ -167,4 +203,5 @@
   template <typename Graph>
   void checkNodeIds(const Graph& G) {
+    typedef typename Graph::Node Node;
     std::set<int> values;
     for (typename Graph::NodeIt n(G); n != INVALID; ++n) {
@@ -174,8 +211,36 @@
       values.insert(G.id(n));
     }
+    check(G.maxId(Node()) <= G.maxNodeId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkRedNodeIds(const Graph& G) {
+    typedef typename Graph::RedNode RedNode;
+    std::set<int> values;
+    for (typename Graph::RedNodeIt n(G); n != INVALID; ++n) {
+      check(G.red(n), "Wrong partition");
+      check(values.find(G.id(n)) == values.end(), "Wrong id");
+      check(G.id(n) <= G.maxRedId(), "Wrong maximum id");
+      values.insert(G.id(n));
+    }
+    check(G.maxId(RedNode()) == G.maxRedId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkBlueNodeIds(const Graph& G) {
+    typedef typename Graph::BlueNode BlueNode;
+    std::set<int> values;
+    for (typename Graph::BlueNodeIt n(G); n != INVALID; ++n) {
+      check(G.blue(n), "Wrong partition");
+      check(values.find(G.id(n)) == values.end(), "Wrong id");
+      check(G.id(n) <= G.maxBlueId(), "Wrong maximum id");
+      values.insert(G.id(n));
+    }
+    check(G.maxId(BlueNode()) == G.maxBlueId(), "Wrong maximum id");
   }
 
   template <typename Graph>
   void checkArcIds(const Graph& G) {
+    typedef typename Graph::Arc Arc;
     std::set<int> values;
     for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
@@ -185,8 +250,10 @@
       values.insert(G.id(a));
     }
+    check(G.maxId(Arc()) <= G.maxArcId(), "Wrong maximum id");
   }
 
   template <typename Graph>
   void checkEdgeIds(const Graph& G) {
+    typedef typename Graph::Edge Edge;
     std::set<int> values;
     for (typename Graph::EdgeIt e(G); e != INVALID; ++e) {
@@ -196,4 +263,5 @@
       values.insert(G.id(e));
     }
+    check(G.maxId(Edge()) <= G.maxEdgeId(), "Wrong maximum id");
   }
 
@@ -229,4 +297,64 @@
 
   template <typename Graph>
+  void checkGraphRedNodeMap(const Graph& G) {
+    typedef typename Graph::Node Node;
+    typedef typename Graph::RedNodeIt RedNodeIt;
+
+    typedef typename Graph::template RedNodeMap<int> IntRedNodeMap;
+    IntRedNodeMap map(G, 42);
+    for (RedNodeIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (RedNodeIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (RedNodeIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Node>(12);
+    // for (NodeIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+  template <typename Graph>
+  void checkGraphBlueNodeMap(const Graph& G) {
+    typedef typename Graph::Node Node;
+    typedef typename Graph::BlueNodeIt BlueNodeIt;
+
+    typedef typename Graph::template BlueNodeMap<int> IntBlueNodeMap;
+    IntBlueNodeMap map(G, 42);
+    for (BlueNodeIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (BlueNodeIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (BlueNodeIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Node>(12);
+    // for (NodeIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+  template <typename Graph>
   void checkGraphArcMap(const Graph& G) {
     typedef typename Graph::Arc Arc;
Index: test/hao_orlin_test.cc
===================================================================
--- test/hao_orlin_test.cc	(revision 1259)
+++ test/hao_orlin_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/heap_test.cc
===================================================================
--- test/heap_test.cc	(revision 1084)
+++ test/heap_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/lgf_reader_writer_test.cc
===================================================================
--- test/lgf_reader_writer_test.cc	(revision 1270)
+++ test/lgf_reader_writer_test.cc	(revision 1270)
@@ -0,0 +1,578 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <string>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/bpgraph.h>
+
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+
+#include "test_tools.h"
+
+struct ReaderConverter {
+  int operator()(const std::string& str) const {
+    return str.length();
+  }
+};
+
+struct WriterConverter {
+  std::string operator()(int value) const {
+    return std::string(value, '*');
+  }
+};
+
+void checkDigraphReaderCompile() {
+  typedef lemon::concepts::ExtendableDigraphComponent<
+    lemon::concepts::Digraph> Digraph;
+  Digraph digraph;
+  Digraph::NodeMap<int> node_map(digraph);
+  Digraph::ArcMap<int> arc_map(digraph);
+  Digraph::Node node;
+  Digraph::Arc arc;
+  int attr;
+
+  lemon::DigraphReader<Digraph> reader(digraph, "filename");
+  reader.nodeMap("node_map", node_map);
+  reader.nodeMap("node_map", node_map, ReaderConverter());
+  reader.arcMap("arc_map", arc_map);
+  reader.arcMap("arc_map", arc_map, ReaderConverter());
+  reader.attribute("attr", attr);
+  reader.attribute("attr", attr, ReaderConverter());
+  reader.node("node", node);
+  reader.arc("arc", arc);
+
+  reader.nodes("alt_nodes_caption");
+  reader.arcs("alt_arcs_caption");
+  reader.attributes("alt_attrs_caption");
+
+  reader.useNodes(node_map);
+  reader.useNodes(node_map, WriterConverter());
+  reader.useArcs(arc_map);
+  reader.useArcs(arc_map, WriterConverter());
+
+  reader.skipNodes();
+  reader.skipArcs();
+
+  reader.run();
+
+  lemon::DigraphReader<Digraph> reader2(digraph, std::cin);
+}
+
+void checkDigraphWriterCompile() {
+  typedef lemon::concepts::Digraph Digraph;
+  Digraph digraph;
+  Digraph::NodeMap<int> node_map(digraph);
+  Digraph::ArcMap<int> arc_map(digraph);
+  Digraph::Node node;
+  Digraph::Arc arc;
+  int attr;
+
+  lemon::DigraphWriter<Digraph> writer(digraph, "filename");
+  writer.nodeMap("node_map", node_map);
+  writer.nodeMap("node_map", node_map, WriterConverter());
+  writer.arcMap("arc_map", arc_map);
+  writer.arcMap("arc_map", arc_map, WriterConverter());
+  writer.attribute("attr", attr);
+  writer.attribute("attr", attr, WriterConverter());
+  writer.node("node", node);
+  writer.arc("arc", arc);
+
+  writer.nodes("alt_nodes_caption");
+  writer.arcs("alt_arcs_caption");
+  writer.attributes("alt_attrs_caption");
+
+  writer.skipNodes();
+  writer.skipArcs();
+
+  writer.run();
+}
+
+void checkGraphReaderCompile() {
+  typedef lemon::concepts::ExtendableGraphComponent<
+    lemon::concepts::Graph> Graph;
+  Graph graph;
+  Graph::NodeMap<int> node_map(graph);
+  Graph::ArcMap<int> arc_map(graph);
+  Graph::EdgeMap<int> edge_map(graph);
+  Graph::Node node;
+  Graph::Arc arc;
+  Graph::Edge edge;
+  int attr;
+
+  lemon::GraphReader<Graph> reader(graph, "filename");
+  reader.nodeMap("node_map", node_map);
+  reader.nodeMap("node_map", node_map, ReaderConverter());
+  reader.arcMap("arc_map", arc_map);
+  reader.arcMap("arc_map", arc_map, ReaderConverter());
+  reader.edgeMap("edge_map", edge_map);
+  reader.edgeMap("edge_map", edge_map, ReaderConverter());
+  reader.attribute("attr", attr);
+  reader.attribute("attr", attr, ReaderConverter());
+  reader.node("node", node);
+  reader.arc("arc", arc);
+
+  reader.nodes("alt_nodes_caption");
+  reader.edges("alt_edges_caption");
+  reader.attributes("alt_attrs_caption");
+
+  reader.useNodes(node_map);
+  reader.useNodes(node_map, WriterConverter());
+  reader.useEdges(edge_map);
+  reader.useEdges(edge_map, WriterConverter());
+
+  reader.skipNodes();
+  reader.skipEdges();
+
+  reader.run();
+
+  lemon::GraphReader<Graph> reader2(graph, std::cin);
+}
+
+void checkGraphWriterCompile() {
+  typedef lemon::concepts::Graph Graph;
+  Graph graph;
+  Graph::NodeMap<int> node_map(graph);
+  Graph::ArcMap<int> arc_map(graph);
+  Graph::EdgeMap<int> edge_map(graph);
+  Graph::Node node;
+  Graph::Arc arc;
+  Graph::Edge edge;
+  int attr;
+
+  lemon::GraphWriter<Graph> writer(graph, "filename");
+  writer.nodeMap("node_map", node_map);
+  writer.nodeMap("node_map", node_map, WriterConverter());
+  writer.arcMap("arc_map", arc_map);
+  writer.arcMap("arc_map", arc_map, WriterConverter());
+  writer.edgeMap("edge_map", edge_map);
+  writer.edgeMap("edge_map", edge_map, WriterConverter());
+  writer.attribute("attr", attr);
+  writer.attribute("attr", attr, WriterConverter());
+  writer.node("node", node);
+  writer.arc("arc", arc);
+  writer.edge("edge", edge);
+
+  writer.nodes("alt_nodes_caption");
+  writer.edges("alt_edges_caption");
+  writer.attributes("alt_attrs_caption");
+
+  writer.skipNodes();
+  writer.skipEdges();
+
+  writer.run();
+
+  lemon::GraphWriter<Graph> writer2(graph, std::cout);
+}
+
+void checkBpGraphReaderCompile() {
+  typedef lemon::concepts::ExtendableBpGraphComponent<
+    lemon::concepts::BpGraph> BpGraph;
+  BpGraph graph;
+  BpGraph::NodeMap<int> node_map(graph);
+  BpGraph::RedNodeMap<int> red_node_map(graph);
+  BpGraph::BlueNodeMap<int> blue_node_map(graph);
+  BpGraph::ArcMap<int> arc_map(graph);
+  BpGraph::EdgeMap<int> edge_map(graph);
+  BpGraph::Node node;
+  BpGraph::RedNode red_node;
+  BpGraph::BlueNode blue_node;
+  BpGraph::Arc arc;
+  BpGraph::Edge edge;
+  int attr;
+
+  lemon::BpGraphReader<BpGraph> reader(graph, "filename");
+  reader.nodeMap("node_map", node_map);
+  reader.nodeMap("node_map", node_map, ReaderConverter());
+  reader.redNodeMap("red_node_map", red_node_map);
+  reader.redNodeMap("red_node_map", red_node_map, ReaderConverter());
+  reader.blueNodeMap("blue_node_map", blue_node_map);
+  reader.blueNodeMap("blue_node_map", blue_node_map, ReaderConverter());
+  reader.arcMap("arc_map", arc_map);
+  reader.arcMap("arc_map", arc_map, ReaderConverter());
+  reader.edgeMap("edge_map", edge_map);
+  reader.edgeMap("edge_map", edge_map, ReaderConverter());
+  reader.attribute("attr", attr);
+  reader.attribute("attr", attr, ReaderConverter());
+  reader.node("node", node);
+  reader.redNode("red_node", red_node);
+  reader.blueNode("blue_node", blue_node);
+  reader.arc("arc", arc);
+
+  reader.nodes("alt_nodes_caption");
+  reader.edges("alt_edges_caption");
+  reader.attributes("alt_attrs_caption");
+
+  reader.useNodes(node_map);
+  reader.useNodes(node_map, WriterConverter());
+  reader.useEdges(edge_map);
+  reader.useEdges(edge_map, WriterConverter());
+
+  reader.skipNodes();
+  reader.skipEdges();
+
+  reader.run();
+
+  lemon::BpGraphReader<BpGraph> reader2(graph, std::cin);
+}
+
+void checkBpGraphWriterCompile() {
+  typedef lemon::concepts::BpGraph BpGraph;
+  BpGraph graph;
+  BpGraph::NodeMap<int> node_map(graph);
+  BpGraph::RedNodeMap<int> red_node_map(graph);
+  BpGraph::BlueNodeMap<int> blue_node_map(graph);
+  BpGraph::ArcMap<int> arc_map(graph);
+  BpGraph::EdgeMap<int> edge_map(graph);
+  BpGraph::Node node;
+  BpGraph::RedNode red_node;
+  BpGraph::BlueNode blue_node;
+  BpGraph::Arc arc;
+  BpGraph::Edge edge;
+  int attr;
+
+  lemon::BpGraphWriter<BpGraph> writer(graph, "filename");
+  writer.nodeMap("node_map", node_map);
+  writer.nodeMap("node_map", node_map, WriterConverter());
+  writer.redNodeMap("red_node_map", red_node_map);
+  writer.redNodeMap("red_node_map", red_node_map, WriterConverter());
+  writer.blueNodeMap("blue_node_map", blue_node_map);
+  writer.blueNodeMap("blue_node_map", blue_node_map, WriterConverter());
+  writer.arcMap("arc_map", arc_map);
+  writer.arcMap("arc_map", arc_map, WriterConverter());
+  writer.edgeMap("edge_map", edge_map);
+  writer.edgeMap("edge_map", edge_map, WriterConverter());
+  writer.attribute("attr", attr);
+  writer.attribute("attr", attr, WriterConverter());
+  writer.node("node", node);
+  writer.redNode("red_node", red_node);
+  writer.blueNode("blue_node", blue_node);
+  writer.arc("arc", arc);
+
+  writer.nodes("alt_nodes_caption");
+  writer.edges("alt_edges_caption");
+  writer.attributes("alt_attrs_caption");
+
+  writer.skipNodes();
+  writer.skipEdges();
+
+  writer.run();
+
+  lemon::BpGraphWriter<BpGraph> writer2(graph, std::cout);
+}
+
+void checkDigraphReaderWriter() {
+  typedef lemon::SmartDigraph Digraph;
+  Digraph digraph;
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n2, n3);
+
+  Digraph::NodeMap<int> node_map(digraph);
+  node_map[n1] = 11;
+  node_map[n2] = 12;
+  node_map[n3] = 13;
+
+  Digraph::ArcMap<int> arc_map(digraph);
+  arc_map[a1] = 21;
+  arc_map[a2] = 22;
+
+  int attr = 100;
+
+  std::ostringstream os;
+  lemon::DigraphWriter<Digraph> writer(digraph, os);
+
+  writer.nodeMap("node_map1", node_map);
+  writer.nodeMap("node_map2", node_map, WriterConverter());
+  writer.arcMap("arc_map1", arc_map);
+  writer.arcMap("arc_map2", arc_map, WriterConverter());
+  writer.node("node", n2);
+  writer.arc("arc", a1);
+  writer.attribute("attr1", attr);
+  writer.attribute("attr2", attr, WriterConverter());
+
+  writer.run();
+
+  typedef lemon::ListDigraph ExpDigraph;
+  ExpDigraph exp_digraph;
+  ExpDigraph::NodeMap<int> exp_node_map1(exp_digraph);
+  ExpDigraph::NodeMap<int> exp_node_map2(exp_digraph);
+  ExpDigraph::ArcMap<int> exp_arc_map1(exp_digraph);
+  ExpDigraph::ArcMap<int> exp_arc_map2(exp_digraph);
+  ExpDigraph::Node exp_n2;
+  ExpDigraph::Arc exp_a1;
+  int exp_attr1;
+  int exp_attr2;
+
+  std::istringstream is(os.str());
+  lemon::DigraphReader<ExpDigraph> reader(exp_digraph, is);
+
+  reader.nodeMap("node_map1", exp_node_map1);
+  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
+  reader.arcMap("arc_map1", exp_arc_map1);
+  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
+  reader.node("node", exp_n2);
+  reader.arc("arc", exp_a1);
+  reader.attribute("attr1", exp_attr1);
+  reader.attribute("attr2", exp_attr2, ReaderConverter());
+
+  reader.run();
+
+  check(lemon::countNodes(exp_digraph) == 3, "Wrong number of nodes");
+  check(lemon::countArcs(exp_digraph) == 2, "Wrong number of arcs");
+  check(exp_node_map1[exp_n2] == 12, "Wrong map value");
+  check(exp_node_map2[exp_n2] == 12, "Wrong map value");
+  check(exp_arc_map1[exp_a1] == 21, "Wrong map value");
+  check(exp_arc_map2[exp_a1] == 21, "Wrong map value");
+  check(exp_attr1 == 100, "Wrong attr value");
+  check(exp_attr2 == 100, "Wrong attr value");
+}
+
+void checkGraphReaderWriter() {
+  typedef lemon::SmartGraph Graph;
+  Graph graph;
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Graph::Node n3 = graph.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n2, n3);
+
+  Graph::NodeMap<int> node_map(graph);
+  node_map[n1] = 11;
+  node_map[n2] = 12;
+  node_map[n3] = 13;
+
+  Graph::EdgeMap<int> edge_map(graph);
+  edge_map[e1] = 21;
+  edge_map[e2] = 22;
+
+  Graph::ArcMap<int> arc_map(graph);
+  arc_map[graph.direct(e1, true)] = 211;
+  arc_map[graph.direct(e1, false)] = 212;
+  arc_map[graph.direct(e2, true)] = 221;
+  arc_map[graph.direct(e2, false)] = 222;
+
+  int attr = 100;
+
+  std::ostringstream os;
+  lemon::GraphWriter<Graph> writer(graph, os);
+
+  writer.nodeMap("node_map1", node_map);
+  writer.nodeMap("node_map2", node_map, WriterConverter());
+  writer.edgeMap("edge_map1", edge_map);
+  writer.edgeMap("edge_map2", edge_map, WriterConverter());
+  writer.arcMap("arc_map1", arc_map);
+  writer.arcMap("arc_map2", arc_map, WriterConverter());
+  writer.node("node", n2);
+  writer.edge("edge", e1);
+  writer.arc("arc", graph.direct(e1, false));
+  writer.attribute("attr1", attr);
+  writer.attribute("attr2", attr, WriterConverter());
+
+  writer.run();
+
+  typedef lemon::ListGraph ExpGraph;
+  ExpGraph exp_graph;
+  ExpGraph::NodeMap<int> exp_node_map1(exp_graph);
+  ExpGraph::NodeMap<int> exp_node_map2(exp_graph);
+  ExpGraph::EdgeMap<int> exp_edge_map1(exp_graph);
+  ExpGraph::EdgeMap<int> exp_edge_map2(exp_graph);
+  ExpGraph::ArcMap<int> exp_arc_map1(exp_graph);
+  ExpGraph::ArcMap<int> exp_arc_map2(exp_graph);
+  ExpGraph::Node exp_n2;
+  ExpGraph::Edge exp_e1;
+  ExpGraph::Arc exp_a1;
+  int exp_attr1;
+  int exp_attr2;
+
+  std::istringstream is(os.str());
+  lemon::GraphReader<ExpGraph> reader(exp_graph, is);
+
+  reader.nodeMap("node_map1", exp_node_map1);
+  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
+  reader.edgeMap("edge_map1", exp_edge_map1);
+  reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter());
+  reader.arcMap("arc_map1", exp_arc_map1);
+  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
+  reader.node("node", exp_n2);
+  reader.edge("edge", exp_e1);
+  reader.arc("arc", exp_a1);
+  reader.attribute("attr1", exp_attr1);
+  reader.attribute("attr2", exp_attr2, ReaderConverter());
+
+  reader.run();
+
+  check(lemon::countNodes(exp_graph) == 3, "Wrong number of nodes");
+  check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges");
+  check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs");
+  check(exp_node_map1[exp_n2] == 12, "Wrong map value");
+  check(exp_node_map2[exp_n2] == 12, "Wrong map value");
+  check(exp_edge_map1[exp_e1] == 21, "Wrong map value");
+  check(exp_edge_map2[exp_e1] == 21, "Wrong map value");
+  check(exp_arc_map1[exp_a1] == 212, "Wrong map value");
+  check(exp_arc_map2[exp_a1] == 212, "Wrong map value");
+  check(exp_attr1 == 100, "Wrong attr value");
+  check(exp_attr2 == 100, "Wrong attr value");
+}
+
+void checkBpGraphReaderWriter() {
+  typedef lemon::SmartBpGraph Graph;
+  Graph graph;
+  Graph::RedNode rn1 = graph.addRedNode();
+  Graph::RedNode rn2 = graph.addRedNode();
+  Graph::RedNode rn3 = graph.addRedNode();
+  Graph::BlueNode bn1 = graph.addBlueNode();
+  Graph::BlueNode bn2 = graph.addBlueNode();
+  Graph::Node n = bn1;
+
+  Graph::Edge e1 = graph.addEdge(rn1, bn1);
+  Graph::Edge e2 = graph.addEdge(rn2, bn1);
+
+  Graph::NodeMap<int> node_map(graph);
+  node_map[rn1] = 11;
+  node_map[rn2] = 12;
+  node_map[rn3] = 13;
+  node_map[bn1] = 14;
+  node_map[bn2] = 15;
+
+  Graph::NodeMap<int> red_node_map(graph);
+  red_node_map[rn1] = 411;
+  red_node_map[rn2] = 412;
+  red_node_map[rn3] = 413;
+
+  Graph::NodeMap<int> blue_node_map(graph);
+  blue_node_map[bn1] = 414;
+  blue_node_map[bn2] = 415;
+
+  Graph::EdgeMap<int> edge_map(graph);
+  edge_map[e1] = 21;
+  edge_map[e2] = 22;
+
+  Graph::ArcMap<int> arc_map(graph);
+  arc_map[graph.direct(e1, true)] = 211;
+  arc_map[graph.direct(e1, false)] = 212;
+  arc_map[graph.direct(e2, true)] = 221;
+  arc_map[graph.direct(e2, false)] = 222;
+
+  int attr = 100;
+
+  std::ostringstream os;
+  lemon::BpGraphWriter<Graph> writer(graph, os);
+
+  writer.nodeMap("node_map1", node_map);
+  writer.nodeMap("node_map2", node_map, WriterConverter());
+  writer.nodeMap("red_node_map1", red_node_map);
+  writer.nodeMap("red_node_map2", red_node_map, WriterConverter());
+  writer.nodeMap("blue_node_map1", blue_node_map);
+  writer.nodeMap("blue_node_map2", blue_node_map, WriterConverter());
+  writer.edgeMap("edge_map1", edge_map);
+  writer.edgeMap("edge_map2", edge_map, WriterConverter());
+  writer.arcMap("arc_map1", arc_map);
+  writer.arcMap("arc_map2", arc_map, WriterConverter());
+  writer.node("node", n);
+  writer.redNode("red_node", rn1);
+  writer.blueNode("blue_node", bn2);
+  writer.edge("edge", e1);
+  writer.arc("arc", graph.direct(e1, false));
+  writer.attribute("attr1", attr);
+  writer.attribute("attr2", attr, WriterConverter());
+
+  writer.run();
+
+  typedef lemon::ListBpGraph ExpGraph;
+  ExpGraph exp_graph;
+  ExpGraph::NodeMap<int> exp_node_map1(exp_graph);
+  ExpGraph::NodeMap<int> exp_node_map2(exp_graph);
+  ExpGraph::RedNodeMap<int> exp_red_node_map1(exp_graph);
+  ExpGraph::RedNodeMap<int> exp_red_node_map2(exp_graph);
+  ExpGraph::BlueNodeMap<int> exp_blue_node_map1(exp_graph);
+  ExpGraph::BlueNodeMap<int> exp_blue_node_map2(exp_graph);
+  ExpGraph::EdgeMap<int> exp_edge_map1(exp_graph);
+  ExpGraph::EdgeMap<int> exp_edge_map2(exp_graph);
+  ExpGraph::ArcMap<int> exp_arc_map1(exp_graph);
+  ExpGraph::ArcMap<int> exp_arc_map2(exp_graph);
+  ExpGraph::Node exp_n;
+  ExpGraph::RedNode exp_rn1;
+  ExpGraph::BlueNode exp_bn2;
+  ExpGraph::Edge exp_e1;
+  ExpGraph::Arc exp_a1;
+  int exp_attr1;
+  int exp_attr2;
+
+  std::istringstream is(os.str());
+  lemon::BpGraphReader<ExpGraph> reader(exp_graph, is);
+
+  reader.nodeMap("node_map1", exp_node_map1);
+  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
+  reader.redNodeMap("red_node_map1", exp_red_node_map1);
+  reader.redNodeMap("red_node_map2", exp_red_node_map2, ReaderConverter());
+  reader.blueNodeMap("blue_node_map1", exp_blue_node_map1);
+  reader.blueNodeMap("blue_node_map2", exp_blue_node_map2, ReaderConverter());
+  reader.edgeMap("edge_map1", exp_edge_map1);
+  reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter());
+  reader.arcMap("arc_map1", exp_arc_map1);
+  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
+  reader.node("node", exp_n);
+  reader.redNode("red_node", exp_rn1);
+  reader.blueNode("blue_node", exp_bn2);
+  reader.edge("edge", exp_e1);
+  reader.arc("arc", exp_a1);
+  reader.attribute("attr1", exp_attr1);
+  reader.attribute("attr2", exp_attr2, ReaderConverter());
+
+  reader.run();
+
+  check(lemon::countNodes(exp_graph) == 5, "Wrong number of nodes");
+  check(lemon::countRedNodes(exp_graph) == 3, "Wrong number of red nodes");
+  check(lemon::countBlueNodes(exp_graph) == 2, "Wrong number of blue nodes");
+  check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges");
+  check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs");
+  check(exp_node_map1[exp_n] == 14, "Wrong map value");
+  check(exp_node_map2[exp_n] == 14, "Wrong map value");
+  check(exp_red_node_map1[exp_rn1] == 411, "Wrong map value");
+  check(exp_red_node_map2[exp_rn1] == 411, "Wrong map value");
+  check(exp_blue_node_map1[exp_bn2] == 415, "Wrong map value");
+  check(exp_blue_node_map2[exp_bn2] == 415, "Wrong map value");
+  check(exp_edge_map1[exp_e1] == 21, "Wrong map value");
+  check(exp_edge_map2[exp_e1] == 21, "Wrong map value");
+  check(exp_arc_map1[exp_a1] == 212, "Wrong map value");
+  check(exp_arc_map2[exp_a1] == 212, "Wrong map value");
+  check(exp_attr1 == 100, "Wrong attr value");
+  check(exp_attr2 == 100, "Wrong attr value");
+}
+
+
+int main() {
+  { // Check digrpah
+    checkDigraphReaderWriter();
+  }
+  { // Check graph
+    checkGraphReaderWriter();
+  }
+  { // Check bipartite graph
+    checkBpGraphReaderWriter();
+  }
+  return 0;
+}
Index: test/lgf_test.cc
===================================================================
--- test/lgf_test.cc	(revision 1097)
+++ test/lgf_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/lp_test.cc
===================================================================
--- test/lp_test.cc	(revision 1248)
+++ test/lp_test.cc	(revision 1300)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -40,4 +40,7 @@
 #endif
 
+#ifdef LEMON_HAVE_LP
+#include <lemon/lp.h>
+#endif
 using namespace lemon;
 
@@ -417,4 +420,13 @@
   lpTest(lp_skel);
 
+#ifdef LEMON_HAVE_LP
+  {
+    Lp lp,lp2;
+    lpTest(lp);
+    aTest(lp2);
+    cloneTest<Lp>();
+  }
+#endif
+
 #ifdef LEMON_HAVE_GLPK
   {
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 1277)
+++ test/maps_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2011
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/matching_test.cc
===================================================================
--- test/matching_test.cc	(revision 1259)
+++ test/matching_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/max_cardinality_search_test.cc
===================================================================
--- test/max_cardinality_search_test.cc	(revision 1270)
+++ test/max_cardinality_search_test.cc	(revision 1270)
@@ -0,0 +1,162 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/max_cardinality_search.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concepts/heap.h>
+#include <lemon/lgf_reader.h>
+
+using namespace lemon;
+using namespace std;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "@arcs\n"
+  "    label capacity\n"
+  "0 1 0     2\n"
+  "1 0 1     2\n"
+  "2 1 2     1\n"
+  "2 3 3     3\n"
+  "3 2 4     3\n"
+  "3 1 5     5\n"
+  "@attributes\n"
+  "s 0\n"
+  "x 1\n"
+  "y 2\n"
+  "z 3\n";
+
+void checkMaxCardSearchCompile() {
+
+  typedef concepts::Digraph Digraph;
+  typedef int Value;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc,Value> CapMap;
+  typedef concepts::ReadWriteMap<Node,Value> CardMap;
+  typedef concepts::ReadWriteMap<Node,bool> ProcMap;
+  typedef Digraph::NodeMap<int> HeapCrossRef;
+
+  Digraph g;
+  Node n,s;
+  CapMap cap;
+  CardMap card;
+  ProcMap proc;
+  HeapCrossRef crossref(g);
+
+  typedef MaxCardinalitySearch<Digraph,CapMap>
+    ::SetCapacityMap<CapMap>
+    ::SetCardinalityMap<CardMap>
+    ::SetProcessedMap<ProcMap>
+    ::SetStandardHeap<BinHeap<Value,HeapCrossRef> >
+    ::Create MaxCardType;
+
+  MaxCardType maxcard(g,cap);
+  const MaxCardType& const_maxcard = maxcard;
+
+  const MaxCardType::Heap& heap_const = const_maxcard.heap();
+  MaxCardType::Heap& heap = const_cast<MaxCardType::Heap&>(heap_const);
+  maxcard.heap(heap,crossref);
+
+  maxcard.capacityMap(cap).cardinalityMap(card).processedMap(proc);
+
+  maxcard.init();
+  maxcard.addSource(s);
+  n = maxcard.nextNode();
+   maxcard.processNextNode();
+   maxcard.start();
+   maxcard.run(s);
+   maxcard.run();
+ }
+
+ void checkWithIntMap( std::istringstream& input)
+ {
+   typedef SmartDigraph Digraph;
+   typedef Digraph::Node Node;
+   typedef Digraph::ArcMap<int> CapMap;
+
+   Digraph g;
+   Node s,x,y,z,a;
+   CapMap cap(g);
+
+   DigraphReader<Digraph>(g,input).
+     arcMap("capacity", cap).
+     node("s",s).
+     node("x",x).
+     node("y",y).
+     node("z",z).
+     run();
+
+   MaxCardinalitySearch<Digraph,CapMap> maxcard(g,cap);
+
+   maxcard.init();
+   maxcard.addSource(s);
+   maxcard.start(x);
+
+   check(maxcard.processed(s) && !maxcard.processed(x) &&
+         !maxcard.processed(y), "Wrong processed()!");
+
+   a=maxcard.nextNode();
+   check(maxcard.processNextNode()==a,
+         "Wrong nextNode() or processNextNode() return value!");
+
+   check(maxcard.processed(a), "Wrong processNextNode()!");
+
+   maxcard.start();
+   check(maxcard.cardinality(x)==2 && maxcard.cardinality(y)>=4,
+         "Wrong cardinalities!");
+ }
+
+ void checkWithConst1Map(std::istringstream &input) {
+   typedef SmartDigraph Digraph;
+   typedef Digraph::Node Node;
+
+   Digraph g;
+   Node s,x,y,z;
+
+  DigraphReader<Digraph>(g,input).
+    node("s",s).
+    node("x",x).
+    node("y",y).
+    node("z",z).
+    run();
+
+  MaxCardinalitySearch<Digraph> maxcard(g);
+  maxcard.run(s);
+  check(maxcard.cardinality(x)==1 &&
+        maxcard.cardinality(y)+maxcard.cardinality(z)==3,
+        "Wrong cardinalities!");
+}
+
+int main() {
+
+  std::istringstream input1(test_lgf);
+  checkWithIntMap(input1);
+
+  std::istringstream input2(test_lgf);
+  checkWithConst1Map(input2);
+}
Index: test/max_clique_test.cc
===================================================================
--- test/max_clique_test.cc	(revision 1270)
+++ test/max_clique_test.cc	(revision 1270)
@@ -0,0 +1,188 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <sstream>
+#include <lemon/list_graph.h>
+#include <lemon/full_graph.h>
+#include <lemon/grid_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/grosso_locatelli_pullan_mc.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label max_clique\n"
+  "1     0\n"
+  "2     0\n"
+  "3     0\n"
+  "4     1\n"
+  "5     1\n"
+  "6     1\n"
+  "7     1\n"
+  "@edges\n"
+  "    label\n"
+  "1 2     1\n"
+  "1 3     2\n"
+  "1 4     3\n"
+  "1 6     4\n"
+  "2 3     5\n"
+  "2 5     6\n"
+  "2 7     7\n"
+  "3 4     8\n"
+  "3 5     9\n"
+  "4 5    10\n"
+  "4 6    11\n"
+  "4 7    12\n"
+  "5 6    13\n"
+  "5 7    14\n"
+  "6 7    15\n";
+
+
+// Check with general graphs
+template <typename Param>
+void checkMaxCliqueGeneral(Param rule) {
+  typedef ListGraph GR;
+  typedef GrossoLocatelliPullanMc<GR> McAlg;
+  typedef McAlg::CliqueNodeIt CliqueIt;
+
+  // Basic tests
+  {
+    GR g;
+    GR::NodeMap<bool> map(g);
+    McAlg mc(g);
+    mc.iterationLimit(50);
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 0, "Wrong clique size");
+    check(CliqueIt(mc) == INVALID, "Wrong CliqueNodeIt");
+
+    GR::Node u = g.addNode();
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 1, "Wrong clique size");
+    mc.cliqueMap(map);
+    check(map[u], "Wrong clique map");
+    CliqueIt it1(mc);
+    check(static_cast<GR::Node>(it1) == u && ++it1 == INVALID,
+          "Wrong CliqueNodeIt");
+
+    GR::Node v = g.addNode();
+    check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 1, "Wrong clique size");
+    mc.cliqueMap(map);
+    check((map[u] && !map[v]) || (map[v] && !map[u]), "Wrong clique map");
+    CliqueIt it2(mc);
+    check(it2 != INVALID && ++it2 == INVALID, "Wrong CliqueNodeIt");
+
+    g.addEdge(u, v);
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 2, "Wrong clique size");
+    mc.cliqueMap(map);
+    check(map[u] && map[v], "Wrong clique map");
+    CliqueIt it3(mc);
+    check(it3 != INVALID && ++it3 != INVALID && ++it3 == INVALID,
+          "Wrong CliqueNodeIt");
+  }
+
+  // Test graph
+  {
+    GR g;
+    GR::NodeMap<bool> max_clique(g);
+    GR::NodeMap<bool> map(g);
+    std::istringstream input(test_lgf);
+    graphReader(g, input)
+      .nodeMap("max_clique", max_clique)
+      .run();
+
+    McAlg mc(g);
+    mc.iterationLimit(50);
+    check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == 4, "Wrong clique size");
+    mc.cliqueMap(map);
+    for (GR::NodeIt n(g); n != INVALID; ++n) {
+      check(map[n] == max_clique[n], "Wrong clique map");
+    }
+    int cnt = 0;
+    for (CliqueIt n(mc); n != INVALID; ++n) {
+      cnt++;
+      check(map[n] && max_clique[n], "Wrong CliqueNodeIt");
+    }
+    check(cnt == 4, "Wrong CliqueNodeIt");
+  }
+}
+
+// Check with full graphs
+template <typename Param>
+void checkMaxCliqueFullGraph(Param rule) {
+  typedef FullGraph GR;
+  typedef GrossoLocatelliPullanMc<FullGraph> McAlg;
+  typedef McAlg::CliqueNodeIt CliqueIt;
+
+  for (int size = 0; size <= 40; size = size * 3 + 1) {
+    GR g(size);
+    GR::NodeMap<bool> map(g);
+    McAlg mc(g);
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
+    check(mc.cliqueSize() == size, "Wrong clique size");
+    mc.cliqueMap(map);
+    for (GR::NodeIt n(g); n != INVALID; ++n) {
+      check(map[n], "Wrong clique map");
+    }
+    int cnt = 0;
+    for (CliqueIt n(mc); n != INVALID; ++n) cnt++;
+    check(cnt == size, "Wrong CliqueNodeIt");
+  }
+}
+
+// Check with grid graphs
+template <typename Param>
+void checkMaxCliqueGridGraph(Param rule) {
+  GridGraph g(5, 7);
+  GridGraph::NodeMap<char> map(g);
+  GrossoLocatelliPullanMc<GridGraph> mc(g);
+
+  mc.iterationLimit(100);
+  check(mc.run(rule) == mc.ITERATION_LIMIT, "Wrong termination cause");
+  check(mc.cliqueSize() == 2, "Wrong clique size");
+
+  mc.stepLimit(100);
+  check(mc.run(rule) == mc.STEP_LIMIT, "Wrong termination cause");
+  check(mc.cliqueSize() == 2, "Wrong clique size");
+
+  mc.sizeLimit(2);
+  check(mc.run(rule) == mc.SIZE_LIMIT, "Wrong termination cause");
+  check(mc.cliqueSize() == 2, "Wrong clique size");
+}
+
+
+int main() {
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::RANDOM);
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::DEGREE_BASED);
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::PENALTY_BASED);
+
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::RANDOM);
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::DEGREE_BASED);
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::PENALTY_BASED);
+
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::RANDOM);
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::DEGREE_BASED);
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::PENALTY_BASED);
+
+  return 0;
+}
Index: test/max_flow_test.cc
===================================================================
--- test/max_flow_test.cc	(revision 1270)
+++ test/max_flow_test.cc	(revision 1270)
@@ -0,0 +1,395 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/preflow.h>
+#include <lemon/edmonds_karp.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/elevator.h>
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "    label capacity\n"
+  "0 1 0     20\n"
+  "0 2 1     0\n"
+  "1 1 2     3\n"
+  "1 2 3     8\n"
+  "1 3 4     8\n"
+  "2 5 5     5\n"
+  "3 2 6     5\n"
+  "3 5 7     5\n"
+  "3 6 8     5\n"
+  "4 3 9     3\n"
+  "5 7 10    3\n"
+  "5 6 11    10\n"
+  "5 8 12    10\n"
+  "6 8 13    8\n"
+  "8 9 14    20\n"
+  "8 1 15    5\n"
+  "9 5 16    5\n"
+  "@attributes\n"
+  "source 1\n"
+  "target 8\n";
+
+
+// Checks the general interface of a max flow algorithm
+template <typename GR, typename CAP>
+struct MaxFlowClassConcept
+{
+
+  template <typename MF>
+  struct Constraints {
+
+    typedef typename GR::Node Node;
+    typedef typename GR::Arc Arc;
+    typedef typename CAP::Value Value;
+    typedef concepts::ReadWriteMap<Arc, Value> FlowMap;
+    typedef concepts::WriteMap<Node, bool> CutMap;
+
+    GR g;
+    Node n;
+    Arc e;
+    CAP cap;
+    FlowMap flow;
+    CutMap cut;
+    Value v;
+    bool b;
+
+    void constraints() {
+      checkConcept<concepts::Digraph, GR>();
+
+      const Constraints& me = *this;
+
+      typedef typename MF
+          ::template SetFlowMap<FlowMap>
+          ::Create MaxFlowType;
+      typedef typename MF::Create MaxFlowType2;
+      MaxFlowType max_flow(me.g, me.cap, me.n, me.n);
+      const MaxFlowType& const_max_flow = max_flow;
+
+      max_flow
+          .capacityMap(cap)
+          .flowMap(flow)
+          .source(n)
+          .target(n);
+
+      typename MaxFlowType::Tolerance tol = const_max_flow.tolerance();
+      max_flow.tolerance(tol);
+
+      max_flow.init();
+      max_flow.init(cap);
+      max_flow.run();
+
+      v = const_max_flow.flowValue();
+      v = const_max_flow.flow(e);
+      const FlowMap& fm = const_max_flow.flowMap();
+
+      b = const_max_flow.minCut(n);
+      const_max_flow.minCutMap(cut);
+
+      ::lemon::ignore_unused_variable_warning(fm);
+    }
+
+  };
+
+};
+
+// Checks the specific parts of Preflow's interface
+void checkPreflowCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Digraph::Node n;
+  CapMap cap;
+
+  typedef Preflow<Digraph, CapMap>
+      ::SetElevator<Elev>
+      ::SetStandardElevator<LinkedElev>
+      ::Create PreflowType;
+  PreflowType preflow_test(g, cap, n, n);
+  const PreflowType& const_preflow_test = preflow_test;
+
+  const PreflowType::Elevator& elev = const_preflow_test.elevator();
+  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
+
+  bool b = preflow_test.init(cap);
+  preflow_test.startFirstPhase();
+  preflow_test.startSecondPhase();
+  preflow_test.runMinCut();
+
+  ::lemon::ignore_unused_variable_warning(b);
+}
+
+// Checks the specific parts of EdmondsKarp's interface
+void checkEdmondsKarpCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Digraph::Node n;
+  CapMap cap;
+
+  EdmondsKarp<Digraph, CapMap> ek_test(g, cap, n, n);
+
+  ek_test.init(cap);
+  bool b = ek_test.checkedInit(cap);
+  b = ek_test.augment();
+  ek_test.start();
+
+  ::lemon::ignore_unused_variable_warning(b);
+}
+
+
+template <typename T>
+T cutValue (const SmartDigraph& g,
+              const SmartDigraph::NodeMap<bool>& cut,
+              const SmartDigraph::ArcMap<T>& cap) {
+
+  T c=0;
+  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
+    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
+  }
+  return c;
+}
+
+template <typename T>
+bool checkFlow(const SmartDigraph& g,
+               const SmartDigraph::ArcMap<T>& flow,
+               const SmartDigraph::ArcMap<T>& cap,
+               SmartDigraph::Node s, SmartDigraph::Node t) {
+
+  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
+    if (flow[e] < 0 || flow[e] > cap[e]) return false;
+  }
+
+  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
+    if (n == s || n == t) continue;
+    T sum = 0;
+    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
+      sum += flow[e];
+    }
+    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
+      sum -= flow[e];
+    }
+    if (sum != 0) return false;
+  }
+  return true;
+}
+
+void initFlowTest()
+{
+  DIGRAPH_TYPEDEFS(SmartDigraph);
+
+  SmartDigraph g;
+  SmartDigraph::ArcMap<int> cap(g),iflow(g);
+  Node s=g.addNode(); Node t=g.addNode();
+  Node n1=g.addNode(); Node n2=g.addNode();
+  Arc a;
+  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
+  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
+  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
+
+  Preflow<SmartDigraph> pre(g,cap,s,t);
+  pre.init(iflow);
+  pre.startFirstPhase();
+  check(pre.flowValue() == 10, "The incorrect max flow value.");
+  check(pre.minCut(s), "Wrong min cut (Node s).");
+  check(pre.minCut(n1), "Wrong min cut (Node n1).");
+  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
+  check(!pre.minCut(t), "Wrong min cut (Node t).");
+}
+
+template <typename MF, typename SF>
+void checkMaxFlowAlg() {
+  typedef SmartDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+
+  typedef typename MF::Value Value;
+  typedef Digraph::ArcMap<Value> CapMap;
+  typedef CapMap FlowMap;
+  typedef BoolNodeMap CutMap;
+
+  Digraph g;
+  Node s, t;
+  CapMap cap(g);
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(g,input)
+      .arcMap("capacity", cap)
+      .node("source",s)
+      .node("target",t)
+      .run();
+
+  MF max_flow(g, cap, s, t);
+  max_flow.run();
+
+  check(checkFlow(g, max_flow.flowMap(), cap, s, t),
+        "The flow is not feasible.");
+
+  CutMap min_cut(g);
+  max_flow.minCutMap(min_cut);
+  Value min_cut_value = cutValue(g, min_cut, cap);
+
+  check(max_flow.flowValue() == min_cut_value,
+        "The max flow value is not equal to the min cut value.");
+
+  FlowMap flow(g);
+  for (ArcIt e(g); e != INVALID; ++e) flow[e] = max_flow.flowMap()[e];
+
+  Value flow_value = max_flow.flowValue();
+
+  for (ArcIt e(g); e != INVALID; ++e) cap[e] = 2 * cap[e];
+  max_flow.init(flow);
+
+  SF::startFirstPhase(max_flow);       // start first phase of the algorithm
+
+  CutMap min_cut1(g);
+  max_flow.minCutMap(min_cut1);
+  min_cut_value = cutValue(g, min_cut1, cap);
+
+  check(max_flow.flowValue() == min_cut_value &&
+        min_cut_value == 2 * flow_value,
+        "The max flow value or the min cut value is wrong.");
+
+  SF::startSecondPhase(max_flow);       // start second phase of the algorithm
+
+  check(checkFlow(g, max_flow.flowMap(), cap, s, t),
+        "The flow is not feasible.");
+
+  CutMap min_cut2(g);
+  max_flow.minCutMap(min_cut2);
+  min_cut_value = cutValue(g, min_cut2, cap);
+
+  check(max_flow.flowValue() == min_cut_value &&
+        min_cut_value == 2 * flow_value,
+        "The max flow value or the min cut value was not doubled");
+
+
+  max_flow.flowMap(flow);
+
+  NodeIt tmp1(g, s);
+  ++tmp1;
+  if (tmp1 != INVALID) s = tmp1;
+
+  NodeIt tmp2(g, t);
+  ++tmp2;
+  if (tmp2 != INVALID) t = tmp2;
+
+  max_flow.source(s);
+  max_flow.target(t);
+
+  max_flow.run();
+
+  CutMap min_cut3(g);
+  max_flow.minCutMap(min_cut3);
+  min_cut_value=cutValue(g, min_cut3, cap);
+
+  check(max_flow.flowValue() == min_cut_value,
+        "The max flow value or the min cut value is wrong.");
+}
+
+// Struct for calling start functions of a general max flow algorithm
+template <typename MF>
+struct GeneralStartFunctions {
+
+  static void startFirstPhase(MF& mf) {
+    mf.start();
+  }
+
+  static void startSecondPhase(MF& mf) {
+    ::lemon::ignore_unused_variable_warning(mf);
+  }
+
+};
+
+// Struct for calling start functions of Preflow
+template <typename MF>
+struct PreflowStartFunctions {
+
+  static void startFirstPhase(MF& mf) {
+    mf.startFirstPhase();
+  }
+
+  static void startSecondPhase(MF& mf) {
+    mf.startSecondPhase();
+  }
+
+};
+
+int main() {
+
+  typedef concepts::Digraph GR;
+  typedef concepts::ReadMap<GR::Arc, int> CM1;
+  typedef concepts::ReadMap<GR::Arc, double> CM2;
+
+  // Check the interface of Preflow
+  checkConcept< MaxFlowClassConcept<GR, CM1>,
+                Preflow<GR, CM1> >();
+  checkConcept< MaxFlowClassConcept<GR, CM2>,
+                Preflow<GR, CM2> >();
+
+  // Check the interface of EdmondsKarp
+  checkConcept< MaxFlowClassConcept<GR, CM1>,
+                EdmondsKarp<GR, CM1> >();
+  checkConcept< MaxFlowClassConcept<GR, CM2>,
+                EdmondsKarp<GR, CM2> >();
+
+  // Check Preflow
+  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1;
+  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
+  checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >();
+  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >();
+  initFlowTest();
+
+  // Check EdmondsKarp
+  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
+  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2;
+  checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >();
+  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >();
+
+  initFlowTest();
+
+  return 0;
+}
Index: test/min_cost_arborescence_test.cc
===================================================================
--- test/min_cost_arborescence_test.cc	(revision 1259)
+++ test/min_cost_arborescence_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/min_cost_flow_test.cc
===================================================================
--- test/min_cost_flow_test.cc	(revision 956)
+++ test/min_cost_flow_test.cc	(revision 1318)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -396,4 +396,10 @@
   checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
            mcf3.OPTIMAL, true,     -300, test_str + "-18", GEQ);
+
+  // Tests for empty graph
+  Digraph gr0;
+  MCF mcf0(gr0);
+  mcf0.run(param);
+  check(mcf0.totalCost() == 0, "Wrong total cost");  
 }
 
Index: test/min_mean_cycle_test.cc
===================================================================
--- test/min_mean_cycle_test.cc	(revision 956)
+++ test/min_mean_cycle_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -111,5 +111,5 @@
                  int cost, int size) {
   MMC alg(gr, lm);
-  alg.findCycleMean();
+  check(alg.findCycleMean(), "Wrong result");
   check(alg.cycleMean() == static_cast<double>(cost) / size,
         "Wrong cycle mean");
@@ -211,4 +211,11 @@
     checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
     checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+
+    // Howard with iteration limit
+    HowardMmc<GR, IntArcMap> mmc(gr, l1);
+    check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT),
+      "Wrong termination cause");
+    check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL),
+      "Wrong termination cause");
   }
 
Index: test/mip_test.cc
===================================================================
--- test/mip_test.cc	(revision 795)
+++ test/mip_test.cc	(revision 1300)
@@ -31,4 +31,8 @@
 #ifdef LEMON_HAVE_CBC
 #include <lemon/cbc.h>
+#endif
+
+#ifdef LEMON_HAVE_MIP
+#include <lemon/lp.h>
 #endif
 
@@ -129,4 +133,12 @@
 {
 
+#ifdef LEMON_HAVE_MIP
+  {
+    Mip mip1;
+    aTest(mip1);
+    cloneTest<Mip>();
+  }
+#endif
+
 #ifdef LEMON_HAVE_GLPK
   {
Index: test/nagamochi_ibaraki_test.cc
===================================================================
--- test/nagamochi_ibaraki_test.cc	(revision 1270)
+++ test/nagamochi_ibaraki_test.cc	(revision 1270)
@@ -0,0 +1,142 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <sstream>
+
+#include <lemon/smart_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/nagamochi_ibaraki.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace std;
+
+const std::string lgf =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@edges\n"
+  "     cap1 cap2 cap3\n"
+  "0 1  1    1    1   \n"
+  "0 2  2    2    4   \n"
+  "1 2  4    4    4   \n"
+  "3 4  1    1    1   \n"
+  "3 5  2    2    4   \n"
+  "4 5  4    4    4   \n"
+  "2 3  1    6    6   \n";
+
+void checkNagamochiIbarakiCompile()
+{
+  typedef int Value;
+  typedef concepts::Graph Graph;
+
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef concepts::ReadMap<Edge, Value> CapMap;
+  typedef concepts::WriteMap<Node, bool> CutMap;
+
+  Graph g;
+  Node n;
+  CapMap cap;
+  CutMap cut;
+  Value v;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(v,b);
+
+  NagamochiIbaraki<Graph, CapMap> ni_test(g, cap);
+  const NagamochiIbaraki<Graph, CapMap>& const_ni_test = ni_test;
+
+  ni_test.init();
+  ni_test.start();
+  b = ni_test.processNextPhase();
+  ni_test.run();
+
+  v = const_ni_test.minCutValue();
+  v = const_ni_test.minCutMap(cut);
+}
+
+template <typename Graph, typename CapMap, typename CutMap>
+typename CapMap::Value
+  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
+{
+  typename CapMap::Value sum = 0;
+  for (typename Graph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (cut[graph.u(e)] != cut[graph.v(e)]) {
+      sum += cap[e];
+    }
+  }
+  return sum;
+}
+
+int main() {
+  SmartGraph graph;
+  SmartGraph::EdgeMap<int> cap1(graph), cap2(graph), cap3(graph);
+  SmartGraph::NodeMap<bool> cut(graph);
+
+  istringstream input(lgf);
+  graphReader(graph, input)
+    .edgeMap("cap1", cap1)
+    .edgeMap("cap2", cap2)
+    .edgeMap("cap3", cap3)
+    .run();
+
+  {
+    NagamochiIbaraki<SmartGraph> ni(graph, cap1);
+    ni.run();
+    ni.minCutMap(cut);
+
+    check(ni.minCutValue() == 1, "Wrong cut value");
+    check(ni.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
+  }
+  {
+    NagamochiIbaraki<SmartGraph> ni(graph, cap2);
+    ni.run();
+    ni.minCutMap(cut);
+
+    check(ni.minCutValue() == 3, "Wrong cut value");
+    check(ni.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
+  }
+  {
+    NagamochiIbaraki<SmartGraph> ni(graph, cap3);
+    ni.run();
+    ni.minCutMap(cut);
+
+    check(ni.minCutValue() == 5, "Wrong cut value");
+    check(ni.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
+  }
+  {
+    NagamochiIbaraki<SmartGraph>::SetUnitCapacity::Create ni(graph);
+    ni.run();
+    ni.minCutMap(cut);
+
+    ConstMap<SmartGraph::Edge, int> cap4(1);
+    check(ni.minCutValue() == 1, "Wrong cut value");
+    check(ni.minCutValue() == cutValue(graph, cap4, cut), "Wrong cut value");
+  }
+
+  return 0;
+}
Index: test/path_test.cc
===================================================================
--- test/path_test.cc	(revision 1144)
+++ test/path_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -22,4 +22,5 @@
 #include <lemon/concepts/path.h>
 #include <lemon/concepts/digraph.h>
+#include <lemon/concept_check.h>
 
 #include <lemon/path.h>
@@ -31,42 +32,307 @@
 using namespace lemon;
 
-void check_concepts() {
-  checkConcept<concepts::Path<ListDigraph>, concepts::Path<ListDigraph> >();
-  checkConcept<concepts::Path<ListDigraph>, Path<ListDigraph> >();
-  checkConcept<concepts::Path<ListDigraph>, SimplePath<ListDigraph> >();
-  checkConcept<concepts::Path<ListDigraph>, StaticPath<ListDigraph> >();
-  checkConcept<concepts::Path<ListDigraph>, ListPath<ListDigraph> >();
+template <typename GR>
+void checkConcepts() {
+  checkConcept<concepts::Path<GR>, concepts::Path<GR> >();
+  checkConcept<concepts::Path<GR>, Path<GR> >();
+  checkConcept<concepts::Path<GR>, SimplePath<GR> >();
+  checkConcept<concepts::Path<GR>, StaticPath<GR> >();
+  checkConcept<concepts::Path<GR>, ListPath<GR> >();
+}
+
+// Conecpt checking for path structures
+void checkPathConcepts() {
+  checkConcepts<concepts::Digraph>();
+  checkConcepts<ListDigraph>();
 }
 
 // Check if proper copy consructor is called (use valgrind for testing)
-template<class _Path>
-void checkCopy()
-{
+template <typename GR, typename P1, typename P2>
+void checkCopy(typename GR::Arc a) {
+  P1 p;
+  p.addBack(a);
+  P1 q;
+  q = p;
+  P1 r(p);
+  P2 q2;
+  q2 = p;
+  P2 r2(p);
+}
+
+// Tests for copy constructors and assignment operators of paths
+void checkPathCopy() {
   ListDigraph g;
-  ListDigraph::Arc a  = g.addArc(g.addNode(), g.addNode());
-  
-  _Path p,q;
-  p.addBack(a);
-  q=p;
-  _Path r(p);
-  StaticPath<ListDigraph> s(r);
-}
-  
+  ListDigraph::Arc a = g.addArc(g.addNode(), g.addNode());
+
+  typedef Path<ListDigraph> Path1;
+  typedef SimplePath<ListDigraph> Path2;
+  typedef ListPath<ListDigraph> Path3;
+  typedef StaticPath<ListDigraph> Path4;
+  checkCopy<ListDigraph, Path1, Path2>(a);
+  checkCopy<ListDigraph, Path1, Path3>(a);
+  checkCopy<ListDigraph, Path1, Path4>(a);
+  checkCopy<ListDigraph, Path2, Path1>(a);
+  checkCopy<ListDigraph, Path2, Path3>(a);
+  checkCopy<ListDigraph, Path2, Path4>(a);
+  checkCopy<ListDigraph, Path3, Path1>(a);
+  checkCopy<ListDigraph, Path3, Path2>(a);
+  checkCopy<ListDigraph, Path3, Path4>(a);
+}
+
+// Class for testing path functions
+class CheckPathFunctions {
+  typedef ListDigraph GR;
+  DIGRAPH_TYPEDEFS(GR);
+  GR gr;
+  const GR& cgr;
+  Node n1, n2, n3, n4;
+  Node tmp_n;
+  Arc a1, a2, a3, a4;
+  Arc tmp_a;
+
+public:
+
+  CheckPathFunctions() : cgr(gr) {
+    n1 = gr.addNode();
+    n2 = gr.addNode();
+    n3 = gr.addNode();
+    n4 = gr.addNode();
+    a1 = gr.addArc(n1, n2);
+    a2 = gr.addArc(n2, n3);
+    a3 = gr.addArc(n3, n4);
+    a4 = gr.addArc(n4, n1);
+  }
+
+  void run() {
+    checkBackAndFrontInsertablePath<Path<GR> >();
+    checkBackAndFrontInsertablePath<ListPath<GR> >();
+    checkBackInsertablePath<SimplePath<GR> >();
+
+    checkListPathSplitAndSplice();
+  }
+
+private:
+
+  template <typename P>
+  void checkBackInsertablePath() {
+
+    // Create and check empty path
+    P p;
+    const P& cp = p;
+    check(cp.empty(), "The path is not empty");
+    check(cp.length() == 0, "The path is not empty");
+//    check(cp.front() == INVALID, "Wrong front()");
+//    check(cp.back() == INVALID, "Wrong back()");
+    typename P::ArcIt ai(cp);
+    check(ai == INVALID, "Wrong ArcIt");
+    check(pathSource(cgr, cp) == INVALID, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == INVALID, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+    PathNodeIt<P> ni(cgr, cp);
+    check(ni == INVALID, "Wrong PathNodeIt");
+
+    // Check single-arc path
+    p.addBack(a1);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 1, "Wrong length");
+    check(cp.front() == a1, "Wrong front()");
+    check(cp.back() == a1, "Wrong back()");
+    check(cp.nth(0) == a1, "Wrong nth()");
+    ai = cp.nthIt(0);
+    check((tmp_a = ai) == a1, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    typename P::ArcIt ai2(cp);
+    check((tmp_a = ai2) == a1, "Wrong ArcIt");
+    check(++ai2 == INVALID, "Wrong ArcIt");
+    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+    PathNodeIt<P> ni2(cgr, cp);
+    check((tmp_n = ni2) == n1, "Wrong PathNodeIt");
+    check((tmp_n = ++ni2) == n2, "Wrong PathNodeIt");
+    check(++ni2 == INVALID, "Wrong PathNodeIt");
+
+    // Check adding more arcs
+    p.addBack(a2);
+    p.addBack(a3);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 3, "Wrong length");
+    check(cp.front() == a1, "Wrong front()");
+    check(cp.back() == a3, "Wrong back()");
+    check(cp.nth(0) == a1, "Wrong nth()");
+    check(cp.nth(1) == a2, "Wrong nth()");
+    check(cp.nth(2) == a3, "Wrong nth()");
+    typename P::ArcIt ai3(cp);
+    check((tmp_a = ai3) == a1, "Wrong ArcIt");
+    check((tmp_a = ++ai3) == a2, "Wrong nthIt()");
+    check((tmp_a = ++ai3) == a3, "Wrong nthIt()");
+    check(++ai3 == INVALID, "Wrong nthIt()");
+    ai = cp.nthIt(0);
+    check((tmp_a = ai) == a1, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
+    ai = cp.nthIt(2);
+    check((tmp_a = ai) == a3, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n4, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+    PathNodeIt<P> ni3(cgr, cp);
+    check((tmp_n = ni3) == n1, "Wrong PathNodeIt");
+    check((tmp_n = ++ni3) == n2, "Wrong PathNodeIt");
+    check((tmp_n = ++ni3) == n3, "Wrong PathNodeIt");
+    check((tmp_n = ++ni3) == n4, "Wrong PathNodeIt");
+    check(++ni3 == INVALID, "Wrong PathNodeIt");
+
+    // Check arc removal and addition
+    p.eraseBack();
+    p.eraseBack();
+    p.addBack(a2);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 2, "Wrong length");
+    check(cp.front() == a1, "Wrong front()");
+    check(cp.back() == a2, "Wrong back()");
+    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+
+    // Check clear()
+    p.clear();
+    check(cp.empty(), "The path is not empty");
+    check(cp.length() == 0, "The path is not empty");
+
+    // Check inconsistent path
+    p.addBack(a4);
+    p.addBack(a2);
+    p.addBack(a1);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 3, "Wrong length");
+    check(cp.front() == a4, "Wrong front()");
+    check(cp.back() == a1, "Wrong back()");
+    check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
+    check(!checkPath(cgr, cp), "Wrong checkPath()");
+  }
+
+  template <typename P>
+  void checkBackAndFrontInsertablePath() {
+
+    // Include back insertable test cases
+    checkBackInsertablePath<P>();
+
+    // Check front and back insertion
+    P p;
+    const P& cp = p;
+    p.addFront(a4);
+    p.addBack(a1);
+    p.addFront(a3);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 3, "Wrong length");
+    check(cp.front() == a3, "Wrong front()");
+    check(cp.back() == a1, "Wrong back()");
+    check(cp.nth(0) == a3, "Wrong nth()");
+    check(cp.nth(1) == a4, "Wrong nth()");
+    check(cp.nth(2) == a1, "Wrong nth()");
+    typename P::ArcIt ai(cp);
+    check((tmp_a = ai) == a3, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a1, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    ai = cp.nthIt(0);
+    check((tmp_a = ai) == a3, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    ai = cp.nthIt(2);
+    check((tmp_a = ai) == a1, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(pathSource(cgr, cp) == n3, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+
+    // Check eraseFront()
+    p.eraseFront();
+    p.addBack(a2);
+    check(!cp.empty(), "Wrong empty()");
+    check(cp.length() == 3, "Wrong length");
+    check(cp.front() == a4, "Wrong front()");
+    check(cp.back() == a2, "Wrong back()");
+    check(cp.nth(0) == a4, "Wrong nth()");
+    check(cp.nth(1) == a1, "Wrong nth()");
+    check(cp.nth(2) == a2, "Wrong nth()");
+    typename P::ArcIt ai2(cp);
+    check((tmp_a = ai2) == a4, "Wrong ArcIt");
+    check((tmp_a = ++ai2) == a1, "Wrong nthIt()");
+    check((tmp_a = ++ai2) == a2, "Wrong nthIt()");
+    check(++ai2 == INVALID, "Wrong nthIt()");
+    ai = cp.nthIt(0);
+    check((tmp_a = ai) == a4, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a1, "Wrong nthIt()");
+    ai = cp.nthIt(2);
+    check((tmp_a = ai) == a2, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
+    check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
+    check(checkPath(cgr, cp), "Wrong checkPath()");
+  }
+
+  void checkListPathSplitAndSplice() {
+
+    // Build a path with spliceFront() and spliceBack()
+    ListPath<GR> p1, p2, p3, p4;
+    p1.addBack(a3);
+    p1.addFront(a2);
+    p2.addBack(a1);
+    p1.spliceFront(p2);
+    p3.addFront(a4);
+    p1.spliceBack(p3);
+    check(p1.length() == 4, "Wrong length");
+    check(p1.front() == a1, "Wrong front()");
+    check(p1.back() == a4, "Wrong back()");
+    ListPath<GR>::ArcIt ai(p1);
+    check((tmp_a = ai) == a1, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a3, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(checkPath(cgr, p1), "Wrong checkPath()");
+
+    // Check split()
+    p1.split(p1.nthIt(2), p2);
+    check(p1.length() == 2, "Wrong length");
+    ai = p1.nthIt(0);
+    check((tmp_a = ai) == a1, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(checkPath(cgr, p1), "Wrong checkPath()");
+    check(p2.length() == 2, "Wrong length");
+    ai = p2.nthIt(0);
+    check((tmp_a = ai) == a3, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(checkPath(cgr, p2), "Wrong checkPath()");
+
+    // Check split() and splice()
+    p1.spliceFront(p2);
+    p1.split(p1.nthIt(2), p2);
+    p2.split(p2.nthIt(1), p3);
+    p2.spliceBack(p1);
+    p2.splice(p2.nthIt(1), p3);
+    check(p2.length() == 4, "Wrong length");
+    check(p2.front() == a1, "Wrong front()");
+    check(p2.back() == a4, "Wrong back()");
+    ai = p2.nthIt(0);
+    check((tmp_a = ai) == a1, "Wrong ArcIt");
+    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a3, "Wrong nthIt()");
+    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
+    check(++ai == INVALID, "Wrong nthIt()");
+    check(checkPath(cgr, p2), "Wrong checkPath()");
+  }
+
+};
+
 int main() {
-  check_concepts();
-
-  checkCopy<Path<ListDigraph> >();
-  checkCopy<SimplePath<ListDigraph> >();
-  checkCopy<ListPath<ListDigraph> >();
-
-  ListDigraph g;
-  ListDigraph::Arc a  = g.addArc(g.addNode(), g.addNode());
-  
-  Path<ListDigraph> p;
-  StaticPath<ListDigraph> q,r;
-  p.addBack(a);
-  q=p;
-  r=q;
-  StaticPath<ListDigraph> s(q);
+  checkPathConcepts();
+  checkPathCopy();
+  CheckPathFunctions cpf;
+  cpf.run();
 
   return 0;
Index: st/preflow_test.cc
===================================================================
--- test/preflow_test.cc	(revision 1263)
+++ 	(revision )
@@ -1,277 +1,0 @@
-/* -*- mode: C++; indent-tabs-mode: nil; -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library.
- *
- * Copyright (C) 2003-2011
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-#include <iostream>
-
-#include "test_tools.h"
-#include <lemon/smart_graph.h>
-#include <lemon/preflow.h>
-#include <lemon/concepts/digraph.h>
-#include <lemon/concepts/maps.h>
-#include <lemon/lgf_reader.h>
-#include <lemon/elevator.h>
-
-using namespace lemon;
-
-char test_lgf[] =
-  "@nodes\n"
-  "label\n"
-  "0\n"
-  "1\n"
-  "2\n"
-  "3\n"
-  "4\n"
-  "5\n"
-  "6\n"
-  "7\n"
-  "8\n"
-  "9\n"
-  "@arcs\n"
-  "    label capacity\n"
-  "0 1 0     20\n"
-  "0 2 1     0\n"
-  "1 1 2     3\n"
-  "1 2 3     8\n"
-  "1 3 4     8\n"
-  "2 5 5     5\n"
-  "3 2 6     5\n"
-  "3 5 7     5\n"
-  "3 6 8     5\n"
-  "4 3 9     3\n"
-  "5 7 10    3\n"
-  "5 6 11    10\n"
-  "5 8 12    10\n"
-  "6 8 13    8\n"
-  "8 9 14    20\n"
-  "8 1 15    5\n"
-  "9 5 16    5\n"
-  "@attributes\n"
-  "source 1\n"
-  "target 8\n";
-
-void checkPreflowCompile()
-{
-  typedef int VType;
-  typedef concepts::Digraph Digraph;
-
-  typedef Digraph::Node Node;
-  typedef Digraph::Arc Arc;
-  typedef concepts::ReadMap<Arc,VType> CapMap;
-  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
-  typedef concepts::WriteMap<Node,bool> CutMap;
-
-  typedef Elevator<Digraph, Digraph::Node> Elev;
-  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
-
-  Digraph g;
-  Node n;
-  Arc e;
-  CapMap cap;
-  FlowMap flow;
-  CutMap cut;
-  VType v;
-  bool b;
-  ::lemon::ignore_unused_variable_warning(v,b);
-
-  typedef Preflow<Digraph, CapMap>
-            ::SetFlowMap<FlowMap>
-            ::SetElevator<Elev>
-            ::SetStandardElevator<LinkedElev>
-            ::Create PreflowType;
-  PreflowType preflow_test(g, cap, n, n);
-  const PreflowType& const_preflow_test = preflow_test;
-
-  const PreflowType::Elevator& elev = const_preflow_test.elevator();
-  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
-  PreflowType::Tolerance tol = const_preflow_test.tolerance();
-  preflow_test.tolerance(tol);
-
-  preflow_test
-    .capacityMap(cap)
-    .flowMap(flow)
-    .source(n)
-    .target(n);
-
-  preflow_test.init();
-  preflow_test.init(cap);
-  preflow_test.startFirstPhase();
-  preflow_test.startSecondPhase();
-  preflow_test.run();
-  preflow_test.runMinCut();
-
-  v = const_preflow_test.flowValue();
-  v = const_preflow_test.flow(e);
-  const FlowMap& fm = const_preflow_test.flowMap();
-  b = const_preflow_test.minCut(n);
-  const_preflow_test.minCutMap(cut);
-
-  ::lemon::ignore_unused_variable_warning(fm);
-}
-
-int cutValue (const SmartDigraph& g,
-              const SmartDigraph::NodeMap<bool>& cut,
-              const SmartDigraph::ArcMap<int>& cap) {
-
-  int c=0;
-  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
-    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
-  }
-  return c;
-}
-
-bool checkFlow(const SmartDigraph& g,
-               const SmartDigraph::ArcMap<int>& flow,
-               const SmartDigraph::ArcMap<int>& cap,
-               SmartDigraph::Node s, SmartDigraph::Node t) {
-
-  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
-    if (flow[e] < 0 || flow[e] > cap[e]) return false;
-  }
-
-  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
-    if (n == s || n == t) continue;
-    int sum = 0;
-    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
-      sum += flow[e];
-    }
-    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
-      sum -= flow[e];
-    }
-    if (sum != 0) return false;
-  }
-  return true;
-}
-
-void initFlowTest()
-{
-  DIGRAPH_TYPEDEFS(SmartDigraph);
-
-  SmartDigraph g;
-  SmartDigraph::ArcMap<int> cap(g),iflow(g);
-  Node s=g.addNode(); Node t=g.addNode();
-  Node n1=g.addNode(); Node n2=g.addNode();
-  Arc a;
-  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
-  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
-  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
-
-  Preflow<SmartDigraph> pre(g,cap,s,t);
-  pre.init(iflow);
-  pre.startFirstPhase();
-  check(pre.flowValue() == 10, "The incorrect max flow value.");
-  check(pre.minCut(s), "Wrong min cut (Node s).");
-  check(pre.minCut(n1), "Wrong min cut (Node n1).");
-  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
-  check(!pre.minCut(t), "Wrong min cut (Node t).");
-}
-
-
-int main() {
-
-  typedef SmartDigraph Digraph;
-
-  typedef Digraph::Node Node;
-  typedef Digraph::NodeIt NodeIt;
-  typedef Digraph::ArcIt ArcIt;
-  typedef Digraph::ArcMap<int> CapMap;
-  typedef Digraph::ArcMap<int> FlowMap;
-  typedef Digraph::NodeMap<bool> CutMap;
-
-  typedef Preflow<Digraph, CapMap> PType;
-
-  Digraph g;
-  Node s, t;
-  CapMap cap(g);
-  std::istringstream input(test_lgf);
-  DigraphReader<Digraph>(g,input).
-    arcMap("capacity", cap).
-    node("source",s).
-    node("target",t).
-    run();
-
-  PType preflow_test(g, cap, s, t);
-  preflow_test.run();
-
-  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
-        "The flow is not feasible.");
-
-  CutMap min_cut(g);
-  preflow_test.minCutMap(min_cut);
-  int min_cut_value=cutValue(g,min_cut,cap);
-
-  check(preflow_test.flowValue() == min_cut_value,
-        "The max flow value is not equal to the three min cut values.");
-
-  FlowMap flow(g);
-  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
-
-  int flow_value=preflow_test.flowValue();
-
-  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
-  preflow_test.init(flow);
-  preflow_test.startFirstPhase();
-
-  CutMap min_cut1(g);
-  preflow_test.minCutMap(min_cut1);
-  min_cut_value=cutValue(g,min_cut1,cap);
-
-  check(preflow_test.flowValue() == min_cut_value &&
-        min_cut_value == 2*flow_value,
-        "The max flow value or the min cut value is wrong.");
-
-  preflow_test.startSecondPhase();
-
-  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
-        "The flow is not feasible.");
-
-  CutMap min_cut2(g);
-  preflow_test.minCutMap(min_cut2);
-  min_cut_value=cutValue(g,min_cut2,cap);
-
-  check(preflow_test.flowValue() == min_cut_value &&
-        min_cut_value == 2*flow_value,
-        "The max flow value or the three min cut values were not doubled");
-
-
-  preflow_test.flowMap(flow);
-
-  NodeIt tmp1(g,s);
-  ++tmp1;
-  if ( tmp1 != INVALID ) s=tmp1;
-
-  NodeIt tmp2(g,t);
-  ++tmp2;
-  if ( tmp2 != INVALID ) t=tmp2;
-
-  preflow_test.source(s);
-  preflow_test.target(t);
-
-  preflow_test.run();
-
-  CutMap min_cut3(g);
-  preflow_test.minCutMap(min_cut3);
-  min_cut_value=cutValue(g,min_cut3,cap);
-
-
-  check(preflow_test.flowValue() == min_cut_value,
-        "The max flow value or the three min cut values are incorrect.");
-
-  initFlowTest();
-
-  return 0;
-}
Index: test/radix_sort_test.cc
===================================================================
--- test/radix_sort_test.cc	(revision 467)
+++ test/radix_sort_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -26,4 +26,5 @@
 
 #include <vector>
+#include <list>
 #include <algorithm>
 
@@ -40,6 +41,56 @@
 int negate(int a) { return - a; }
 
-
-void generateIntSequence(int n, std::vector<int>& data) {
+template<class T>
+bool isTheSame(T &a, T&b)
+{
+  typename T::iterator ai=a.begin();
+  typename T::iterator bi=b.begin();
+  for(;ai!=a.end()||bi!=b.end();++ai,++bi)
+    if(*ai!=*bi) return false;
+  return ai==a.end()&&bi==b.end();
+}
+
+template<class T>
+T listsort(typename T::iterator b, typename T::iterator e)
+{
+  if(b==e) return T();
+  typename T::iterator bn=b;
+  if(++bn==e) {
+    T l;
+    l.push_back(*b);
+    return l;
+  }
+  typename T::iterator m=b;
+  bool x=false;
+  for(typename T::iterator i=b;i!=e;++i,x=!x)
+    if(x) ++m;
+  T l1(listsort<T>(b,m));
+  T l2(listsort<T>(m,e));
+  T l;
+  while((!l1.empty())&&(!l2.empty()))
+    if(l1.front()<=l2.front())
+      {
+        l.push_back(l1.front());
+        l1.pop_front();
+      }
+    else {
+      l.push_back(l2.front());
+      l2.pop_front();
+    }
+  while(!l1.empty())
+    {
+      l.push_back(l1.front());
+      l1.pop_front();
+    }
+  while(!l2.empty())
+    {
+      l.push_back(l2.front());
+      l2.pop_front();
+    }
+  return l;
+}
+
+template<class T>
+void generateIntSequence(int n, T & data) {
   int prime = 9973;
   int root = 136, value = 1;
@@ -50,5 +101,6 @@
 }
 
-void generateCharSequence(int n, std::vector<unsigned char>& data) {
+template<class T>
+void generateCharSequence(int n, T & data) {
   int prime = 251;
   int root = 3, value = root;
@@ -72,14 +124,90 @@
     }
 
-    radixSort(data2.begin(), data2.end(), Negate());
+    // radixSort(data2.begin(), data2.end(), Negate());
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+    // radixSort(data2.begin(), data2.end(), negate);
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+  {
+    std::list<int> data1;
+    generateIntSequence(n, data1);
+
+    std::list<int> data2(listsort<std::list<int> >(data1.begin(), data1.end()));
+
+    radixSort(data1.begin(), data1.end());
+
+    check(isTheSame(data1,data2), "Test failed");
+
+
+    // radixSort(data2.begin(), data2.end(), Negate());
+    // check(isTheSame(data1,data2), "Test failed");
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+    // radixSort(data2.begin(), data2.end(), negate);
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+  }
+
+  {
+    std::list<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::list<unsigned char> data2(listsort<std::list<unsigned char> >
+                                   (data1.begin(),
+                                    data1.end()));
+
+    radixSort(data1.begin(), data1.end());
+    check(isTheSame(data1,data2), "Test failed");
+
+  }
+}
+
+
+void checkStableRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    stableRadixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), Negate());
     for (int i = 0; i < n; ++i) {
       check(data1[i] == data2[n - 1 - i], "Test failed");
     }
 
-    radixSort(data2.begin(), data2.end(), negate);
+    stableRadixSort(data2.begin(), data2.end(), negate);
     for (int i = 0; i < n; ++i) {
       check(data1[i] == data2[n - 1 - i], "Test failed");
     }
-
   }
 
@@ -97,42 +225,33 @@
 
   }
-}
-
-
-void checkStableRadixSort() {
-  {
-    std::vector<int> data1;
-    generateIntSequence(n, data1);
-
-    std::vector<int> data2(data1);
-    std::sort(data1.begin(), data1.end());
-
-    stableRadixSort(data2.begin(), data2.end());
-    for (int i = 0; i < n; ++i) {
-      check(data1[i] == data2[i], "Test failed");
-    }
-
-    stableRadixSort(data2.begin(), data2.end(), Negate());
-    for (int i = 0; i < n; ++i) {
-      check(data1[i] == data2[n - 1 - i], "Test failed");
-    }
-
-    stableRadixSort(data2.begin(), data2.end(), negate);
-    for (int i = 0; i < n; ++i) {
-      check(data1[i] == data2[n - 1 - i], "Test failed");
-    }
-  }
-
-  {
-    std::vector<unsigned char> data1(n);
-    generateCharSequence(n, data1);
-
-    std::vector<unsigned char> data2(data1);
-    std::sort(data1.begin(), data1.end());
-
-    radixSort(data2.begin(), data2.end());
-    for (int i = 0; i < n; ++i) {
-      check(data1[i] == data2[i], "Test failed");
-    }
+  {
+    std::list<int> data1;
+    generateIntSequence(n, data1);
+
+    std::list<int> data2(listsort<std::list<int> >(data1.begin(),
+                                                   data1.end()));
+    stableRadixSort(data1.begin(), data1.end());
+    check(isTheSame(data1,data2), "Test failed");
+
+    // stableRadixSort(data2.begin(), data2.end(), Negate());
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+
+    // stableRadixSort(data2.begin(), data2.end(), negate);
+    // for (int i = 0; i < n; ++i) {
+    //   check(data1[i] == data2[n - 1 - i], "Test failed");
+    // }
+  }
+
+  {
+    std::list<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::list<unsigned char> data2(listsort<std::list<unsigned char> >
+                                   (data1.begin(),
+                                    data1.end()));
+    radixSort(data1.begin(), data1.end());
+    check(isTheSame(data1,data2), "Test failed");
 
   }
Index: test/suurballe_test.cc
===================================================================
--- test/suurballe_test.cc	(revision 1259)
+++ test/suurballe_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/time_measure_test.cc
===================================================================
--- test/time_measure_test.cc	(revision 1257)
+++ test/time_measure_test.cc	(revision 1270)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/tsp_test.cc
===================================================================
--- test/tsp_test.cc	(revision 1303)
+++ test/tsp_test.cc	(revision 1303)
@@ -0,0 +1,287 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include <lemon/full_graph.h>
+#include <lemon/math.h>
+#include <lemon/maps.h>
+#include <lemon/random.h>
+#include <lemon/dim2.h>
+
+#include <lemon/nearest_neighbor_tsp.h>
+#include <lemon/greedy_tsp.h>
+#include <lemon/insertion_tsp.h>
+#include <lemon/christofides_tsp.h>
+#include <lemon/opt2_tsp.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+// // Tests checkMetricCost() function
+// void metricCostTest() {
+//   GRAPH_TYPEDEFS(FullGraph);
+//   FullGraph g(10);
+//   check(checkMetricCost(g, constMap<Edge>(0)), "Wrong checkMetricCost()");
+//   check(checkMetricCost(g, constMap<Edge>(1)), "Wrong checkMetricCost()");
+//   check(!checkMetricCost(g, constMap<Edge>(-1)), "Wrong checkMetricCost()");
+//
+//   FullGraph::EdgeMap<float> cost(g);
+//   for (NodeIt u(g); u != INVALID; ++u) {
+//     for (NodeIt v(g); v != INVALID; ++v) {
+//       if (u == v) continue;
+//       float x1 = g.id(u), x2 = g.id(v);
+//       float y1 = x1 * x1, y2 = x2 * x2;
+//       cost[g.edge(u, v)] = std::sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
+//     }
+//   }
+//   check(checkMetricCost(g, cost), "Wrong checkMetricCost()");
+//   float eps = Tolerance<float>::defaultEpsilon();
+//   cost[g.edge(g(0), g(9))] =
+//     cost[g.edge(g(0), g(8))] + cost[g.edge(g(8), g(9))] + eps * 2;
+//   check(!checkMetricCost(g, cost), "Wrong checkMetricCost()");
+//   check(checkMetricCost(g, cost, Tolerance<float>(eps * 4)),
+//     "Wrong checkMetricCost()");
+// }
+
+// Checks tour validity
+template <typename Container>
+bool checkTour(const FullGraph &gr, const Container &p) {
+  FullGraph::NodeMap<bool> used(gr, false);
+
+  int node_cnt = 0;
+  for (typename Container::const_iterator it = p.begin(); it != p.end(); ++it)
+    {
+      FullGraph::Node node = *it;
+      if (used[node]) return false;
+      used[node] = true;
+      ++node_cnt;
+    }
+
+  return (node_cnt == gr.nodeNum());
+}
+
+// Checks tour validity
+bool checkTourPath(const FullGraph &gr, const Path<FullGraph> &p) {
+  FullGraph::NodeMap<bool> used(gr, false);
+
+  if (!checkPath(gr, p)) return false;
+  if (gr.nodeNum() <= 1 && p.length() != 0) return false;
+  if (gr.nodeNum() > 1 && p.length() != gr.nodeNum()) return false;
+
+  for (int i = 0; i < p.length(); ++i) {
+    if (used[gr.target(p.nth(i))]) return false;
+    used[gr.target(p.nth(i))] = true;
+  }
+  return true;
+}
+
+// Checks tour cost
+template <typename CostMap>
+bool checkCost(const FullGraph &gr, const std::vector<FullGraph::Node> &p,
+               const CostMap &cost, typename CostMap::Value total)
+{
+  typedef typename CostMap::Value Cost;
+
+  Cost s = 0;
+  for (int i = 0; i < int(p.size()) - 1; ++i)
+    s += cost[gr.edge(p[i], p[i+1])];
+  if (int(p.size()) >= 2)
+    s += cost[gr.edge(p.back(), p.front())];
+
+  return !Tolerance<Cost>().different(s, total);
+}
+
+// Checks tour cost
+template <typename CostMap>
+bool checkCost(const FullGraph &, const Path<FullGraph> &p,
+               const CostMap &cost, typename CostMap::Value total)
+{
+  typedef typename CostMap::Value Cost;
+
+  Cost s = 0;
+  for (int i = 0; i < p.length(); ++i)
+    s += cost[p.nth(i)];
+
+  return !Tolerance<Cost>().different(s, total);
+}
+
+// Tests a TSP algorithm on small graphs
+template <typename TSP>
+void tspTestSmall(const std::string &alg_name) {
+  GRAPH_TYPEDEFS(FullGraph);
+
+  for (int n = 0; n <= 5; ++n) {
+    FullGraph g(n);
+    unsigned nsize = n;
+    int esize = n <= 1 ? 0 : n;
+
+    ConstMap<Edge, int> cost_map(1);
+    TSP alg(g, cost_map);
+
+    check(alg.run() == esize, alg_name + ": Wrong total cost");
+    check(alg.tourCost() == esize, alg_name + ": Wrong total cost");
+
+    std::list<Node> list1(nsize), list2;
+    std::vector<Node> vec1(nsize), vec2;
+    alg.tourNodes(list1.begin());
+    alg.tourNodes(vec1.begin());
+    alg.tourNodes(std::front_inserter(list2));
+    alg.tourNodes(std::back_inserter(vec2));
+    check(checkTour(g, alg.tourNodes()), alg_name + ": Wrong node sequence");
+    check(checkTour(g, list1), alg_name + ": Wrong node sequence");
+    check(checkTour(g, vec1), alg_name + ": Wrong node sequence");
+    check(checkTour(g, list2), alg_name + ": Wrong node sequence");
+    check(checkTour(g, vec2), alg_name + ": Wrong node sequence");
+    check(checkCost(g, vec1, constMap<Edge, int>(1), esize),
+      alg_name + ": Wrong tour cost");
+
+    SimplePath<FullGraph> path;
+    alg.tour(path);
+    check(path.length() == esize, alg_name + ": Wrong tour");
+    check(checkTourPath(g, path), alg_name + ": Wrong tour");
+    check(checkCost(g, path, constMap<Edge, int>(1), esize),
+      alg_name + ": Wrong tour cost");
+  }
+}
+
+// Tests a TSP algorithm on random graphs
+template <typename TSP>
+void tspTestRandom(const std::string &alg_name) {
+  GRAPH_TYPEDEFS(FullGraph);
+
+  FullGraph g(20);
+  FullGraph::NodeMap<dim2::Point<double> > pos(g);
+  DoubleEdgeMap cost(g);
+
+  TSP alg(g, cost);
+  Opt2Tsp<DoubleEdgeMap > opt2(g, cost);
+
+  for (int i = 1; i <= 3; i++) {
+    for (NodeIt u(g); u != INVALID; ++u) {
+      pos[u] = dim2::Point<double>(rnd(), rnd());
+    }
+    for (NodeIt u(g); u != INVALID; ++u) {
+      for (NodeIt v(g); v != INVALID; ++v) {
+        if (u == v) continue;
+        cost[g.edge(u, v)] = (pos[u] - pos[v]).normSquare();
+      }
+    }
+
+    check(alg.run() > 0, alg_name + ": Wrong total cost");
+
+    std::vector<Node> vec;
+    alg.tourNodes(std::back_inserter(vec));
+    check(checkTour(g, vec), alg_name + ": Wrong node sequence");
+    check(checkCost(g, vec, cost, alg.tourCost()),
+      alg_name + ": Wrong tour cost");
+
+    SimplePath<FullGraph> path;
+    alg.tour(path);
+    check(checkTourPath(g, path), alg_name + ": Wrong tour");
+    check(checkCost(g, path, cost, alg.tourCost()),
+      alg_name + ": Wrong tour cost");
+
+    check(!Tolerance<double>().less(alg.tourCost(), opt2.run(alg.tourNodes())),
+      "2-opt improvement: Wrong total cost");
+    check(checkTour(g, opt2.tourNodes()),
+      "2-opt improvement: Wrong node sequence");
+    check(checkCost(g, opt2.tourNodes(), cost, opt2.tourCost()),
+      "2-opt improvement: Wrong tour cost");
+
+    check(!Tolerance<double>().less(alg.tourCost(), opt2.run(path)),
+      "2-opt improvement: Wrong total cost");
+    check(checkTour(g, opt2.tourNodes()),
+      "2-opt improvement: Wrong node sequence");
+    check(checkCost(g, opt2.tourNodes(), cost, opt2.tourCost()),
+      "2-opt improvement: Wrong tour cost");
+  }
+}
+
+// Algorithm class for Nearest Insertion
+template <typename CM>
+class NearestInsertionTsp : public InsertionTsp<CM> {
+public:
+  NearestInsertionTsp(const FullGraph &gr, const CM &cost)
+    : InsertionTsp<CM>(gr, cost) {}
+  typename CM::Value run() {
+    return InsertionTsp<CM>::run(InsertionTsp<CM>::NEAREST);
+  }
+};
+
+// Algorithm class for Farthest Insertion
+template <typename CM>
+class FarthestInsertionTsp : public InsertionTsp<CM> {
+public:
+  FarthestInsertionTsp(const FullGraph &gr, const CM &cost)
+    : InsertionTsp<CM>(gr, cost) {}
+  typename CM::Value run() {
+    return InsertionTsp<CM>::run(InsertionTsp<CM>::FARTHEST);
+  }
+};
+
+// Algorithm class for Cheapest Insertion
+template <typename CM>
+class CheapestInsertionTsp : public InsertionTsp<CM> {
+public:
+  CheapestInsertionTsp(const FullGraph &gr, const CM &cost)
+    : InsertionTsp<CM>(gr, cost) {}
+  typename CM::Value run() {
+    return InsertionTsp<CM>::run(InsertionTsp<CM>::CHEAPEST);
+  }
+};
+
+// Algorithm class for Random Insertion
+template <typename CM>
+class RandomInsertionTsp : public InsertionTsp<CM> {
+public:
+  RandomInsertionTsp(const FullGraph &gr, const CM &cost)
+    : InsertionTsp<CM>(gr, cost) {}
+  typename CM::Value run() {
+    return InsertionTsp<CM>::run(InsertionTsp<CM>::RANDOM);
+  }
+};
+
+int main() {
+  GRAPH_TYPEDEFS(FullGraph);
+
+  // metricCostTest();
+
+  tspTestSmall<NearestNeighborTsp<ConstMap<Edge, int> > >("Nearest Neighbor");
+  tspTestSmall<GreedyTsp<ConstMap<Edge, int> > >("Greedy");
+  tspTestSmall<NearestInsertionTsp<ConstMap<Edge, int> > >("Nearest Insertion");
+  tspTestSmall<FarthestInsertionTsp<ConstMap<Edge, int> > >
+    ("Farthest Insertion");
+  tspTestSmall<CheapestInsertionTsp<ConstMap<Edge, int> > >
+    ("Cheapest Insertion");
+  tspTestSmall<RandomInsertionTsp<ConstMap<Edge, int> > >("Random Insertion");
+  tspTestSmall<ChristofidesTsp<ConstMap<Edge, int> > >("Christofides");
+  tspTestSmall<Opt2Tsp<ConstMap<Edge, int> > >("2-opt");
+
+  tspTestRandom<NearestNeighborTsp<DoubleEdgeMap > >("Nearest Neighbor");
+  tspTestRandom<GreedyTsp<DoubleEdgeMap > >("Greedy");
+  tspTestRandom<NearestInsertionTsp<DoubleEdgeMap > >("Nearest Insertion");
+  tspTestRandom<FarthestInsertionTsp<DoubleEdgeMap > >("Farthest Insertion");
+  tspTestRandom<CheapestInsertionTsp<DoubleEdgeMap > >("Cheapest Insertion");
+  tspTestRandom<RandomInsertionTsp<DoubleEdgeMap > >("Random Insertion");
+  tspTestRandom<ChristofidesTsp<DoubleEdgeMap > >("Christofides");
+  tspTestRandom<Opt2Tsp<DoubleEdgeMap > >("2-opt");
+
+  return 0;
+}
Index: ols/Makefile.am
===================================================================
--- tools/Makefile.am	(revision 721)
+++ 	(revision )
@@ -1,17 +1,0 @@
-EXTRA_DIST += \
-	tools/CMakeLists.txt
-
-if WANT_TOOLS
-
-bin_PROGRAMS += \
-	tools/dimacs-solver \
-	tools/dimacs-to-lgf \
-	tools/lgf-gen
-
-dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
-
-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 1169)
+++ tools/dimacs-solver.cc	(revision 1271)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2013
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -128,5 +128,6 @@
   if (report) {
     std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
-    std::cerr << "Feasible flow: " << (res == MCF::OPTIMAL ? "found" : "not found") << '\n';
+    std::cerr << "Feasible flow: " << (res == MCF::OPTIMAL ? "found" :
+                                       "not found") << '\n';
     if (res) std::cerr << "Min flow cost: "
                        << ns.template totalCost<LargeValue>() << '\n';
Index: tools/lgf-gen.cc
===================================================================
--- tools/lgf-gen.cc	(revision 701)
+++ tools/lgf-gen.cc	(revision 1308)
@@ -247,5 +247,5 @@
   struct BeachIt;
 
-  typedef std::multimap<double, BeachIt> SpikeHeap;
+  typedef std::multimap<double, BeachIt*> SpikeHeap;
 
   typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
@@ -330,4 +330,5 @@
 
       if (bit->second != spikeheap.end()) {
+        delete bit->second->second;
         spikeheap.erase(bit->second);
       }
@@ -343,6 +344,6 @@
           circle_form(points[prev], points[curr], points[site])) {
         double x = circle_point(points[prev], points[curr], points[site]);
-        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
-        pit->second.it =
+        pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        pit->second->it =
           beach.insert(std::make_pair(Part(prev, curr, site), pit));
       } else {
@@ -356,6 +357,6 @@
           circle_form(points[site], points[curr],points[next])) {
         double x = circle_point(points[site], points[curr], points[next]);
-        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
-        nit->second.it =
+        nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        nit->second->it =
           beach.insert(std::make_pair(Part(site, curr, next), nit));
       } else {
@@ -367,5 +368,5 @@
       sweep = spit->first;
 
-      Beach::iterator bit = spit->second.it;
+      Beach::iterator bit = spit->second->it;
 
       int prev = bit->first.prev;
@@ -400,8 +401,20 @@
       int nnt = nbit->first.next;
 
-      if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
-      if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
-      if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
-
+      if (bit->second != spikeheap.end())
+        {
+          delete bit->second->second;
+          spikeheap.erase(bit->second);
+        }
+      if (pbit->second != spikeheap.end())
+        {
+          delete pbit->second->second;
+          spikeheap.erase(pbit->second);
+        }
+      if (nbit->second != spikeheap.end())
+        {
+          delete nbit->second->second;
+          spikeheap.erase(nbit->second);
+        }
+      
       beach.erase(nbit);
       beach.erase(bit);
@@ -413,6 +426,6 @@
         double x = circle_point(points[ppv], points[prev], points[next]);
         if (x < sweep) x = sweep;
-        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
-        pit->second.it =
+        pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        pit->second->it =
           beach.insert(std::make_pair(Part(ppv, prev, next), pit));
       } else {
@@ -425,6 +438,6 @@
         double x = circle_point(points[prev], points[next], points[nnt]);
         if (x < sweep) x = sweep;
-        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
-        nit->second.it =
+        nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        nit->second->it =
           beach.insert(std::make_pair(Part(prev, next, nnt), nit));
       } else {
