Index: AUTHORS
===================================================================
--- AUTHORS	(revision 320)
+++ AUTHORS	(revision 992)
@@ -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>
@@ -24,3 +24,3 @@
 
 Again, please visit the history of the old LEMON repository for more
-details: http://lemon.cs.elte.hu/svn/lemon/trunk
+details: http://lemon.cs.elte.hu/hg/lemon-0.x
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 912)
+++ CMakeLists.txt	(revision 1017)
@@ -13,27 +13,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()
 
@@ -52,5 +70,5 @@
 ELSE()
   IF(CMAKE_COMPILER_IS_GNUCXX)
-    SET(CXX_WARNING "-Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas")
+    SET(CXX_WARNING "-Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas")
     SET(CMAKE_CXX_FLAGS_DEBUG CACHE STRING "-ggdb")
     SET(CMAKE_C_FLAGS_DEBUG CACHE STRING "-ggdb")
@@ -67,5 +85,5 @@
     # C4996: 'function': was declared deprecated
   ELSE()
-    SET(CXX_WARNING "-Wall -W")
+    SET(CXX_WARNING "-Wall")
   ENDIF()
 ENDIF()
@@ -74,18 +92,36 @@
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}")
 
-SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb" 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" 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
+    )
+  SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used for linking binaries during maintainer builds."
+    )
+  SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
+    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
+    "Flags used by the shared libraries linker during maintainer builds."
+    )
+ELSE()
+  SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING
+    "Flags used by the C++ compiler during maintainer builds."
+    )
+  SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING
+    "Flags used by the C compiler during maintainer builds."
+    )
+  SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
     "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
     "Flags used for linking binaries during maintainer builds."
-    FORCE )
-SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
+    )
+  SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
     "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
     "Flags used by the shared libraries linker during maintainer builds."
-    FORCE )
+    )
+ENDIF()
+
 MARK_AS_ADVANCED(
     CMAKE_CXX_FLAGS_MAINTAINER
@@ -115,4 +151,26 @@
 SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
 
+INCLUDE(FindThreads)
+
+IF(NOT LEMON_THREADING)
+  IF(CMAKE_USE_PTHREADS_INIT)
+    SET(LEMON_THREADING "Pthread")
+  ELSEIF(CMAKE_USE_WIN32_THREADS_INIT)
+    SET(LEMON_THREADING "Win32")
+  ELSE()
+    SET(LEMON_THREADING "None")
+  ENDIF()
+ENDIF()
+
+SET( LEMON_THREADING "${LEMON_THREADING}" CACHE STRING
+  "Choose the threading library, options are: Pthread Win32 None."
+  FORCE )
+
+IF(LEMON_THREADING STREQUAL "Pthread")
+  SET(LEMON_USE_PTHREAD TRUE)
+ELSEIF(LEMON_THREADING STREQUAL "Win32")
+  SET(LEMON_USE_WIN32_THREADS TRUE)
+ENDIF()
+
 ENABLE_TESTING()
 
@@ -125,4 +183,5 @@
 ADD_SUBDIRECTORY(lemon)
 IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
+  ADD_SUBDIRECTORY(contrib)
   ADD_SUBDIRECTORY(demo)
   ADD_SUBDIRECTORY(tools)
@@ -148,4 +207,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 824)
+++ INSTALL	(revision 992)
@@ -2,196 +2,120 @@
 =========================
 
-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.
+-DGLPK_ROOT_DIR=DIRECTORY
+-DCOIN_ROOT_DIR=DIRECTORY
+-DCPLEX_ROOT_DIR=DIRECTORY
 
---with-cplex-includedir=DIR
-
-   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).
-
---with-cplex-libdir=DIR
-
-   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).
-
---without-cplex
-
-   Disable CPLEX support.
-
---with-soplex[=PREFIX]
-
-   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.
-
---with-soplex-includedir=DIR
-
-   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).
-
---with-soplex-libdir=DIR
-
-   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).
-
---without-soplex
-
-   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.
-
+  Install 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 879)
+++ LICENSE	(revision 992)
@@ -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 793)
+++ 	(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: cmake/FindCOIN.cmake
===================================================================
--- cmake/FindCOIN.cmake	(revision 634)
+++ cmake/FindCOIN.cmake	(revision 973)
@@ -6,40 +6,61 @@
 FIND_LIBRARY(COIN_CBC_LIBRARY
   NAMES Cbc libCbc
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY
   NAMES CbcSolver libCbcSolver
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_CGL_LIBRARY
   NAMES Cgl libCgl
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_CLP_LIBRARY
   NAMES Clp libClp
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY
   NAMES CoinUtils libCoinUtils
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_OSI_LIBRARY
   NAMES Osi libOsi
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_OSI_CBC_LIBRARY
   NAMES OsiCbc libOsiCbc
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_OSI_CLP_LIBRARY
   NAMES OsiClp libOsiClp
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_OSI_VOL_LIBRARY
   NAMES OsiVol libOsiVol
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
 FIND_LIBRARY(COIN_VOL_LIBRARY
   NAMES Vol libVol
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+
+FIND_LIBRARY(COIN_ZLIB_LIBRARY
+  NAMES z libz
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_BZ2_LIBRARY
+  NAMES bz2 libbz2
+  HINTS ${COIN_ROOT_DIR}/lib/coin
   HINTS ${COIN_ROOT_DIR}/lib
 )
@@ -56,13 +77,19 @@
   COIN_OSI_CBC_LIBRARY
   COIN_OSI_CLP_LIBRARY
-  COIN_OSI_VOL_LIBRARY
-  COIN_VOL_LIBRARY
+  # COIN_OSI_VOL_LIBRARY
+  # COIN_VOL_LIBRARY
 )
 
 IF(COIN_FOUND)
   SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
-  SET(COIN_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_OSI_VOL_LIBRARY};${COIN_VOL_LIBRARY}")
-  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY}")
-  SET(COIN_CBC_LIBRARIES ${COIN_LIBRARIES})
+  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY}")
+  IF(COIN_ZLIB_LIBRARY)
+    SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_ZLIB_LIBRARY}")
+  ENDIF(COIN_ZLIB_LIBRARY)
+   IF(COIN_BZ2_LIBRARY)
+    SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_BZ2_LIBRARY}")
+  ENDIF(COIN_BZ2_LIBRARY)
+  SET(COIN_CBC_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY};${COIN_CLP_LIBRARIES}")
+  SET(COIN_LIBRARIES ${COIN_CBC_LIBRARIES})
 ENDIF(COIN_FOUND)
 
@@ -79,4 +106,6 @@
   COIN_OSI_VOL_LIBRARY
   COIN_VOL_LIBRARY
+  COIN_ZLIB_LIBRARY
+  COIN_BZ2_LIBRARY
 )
 
Index: cmake/FindCPLEX.cmake
===================================================================
--- cmake/FindCPLEX.cmake	(revision 636)
+++ cmake/FindCPLEX.cmake	(revision 972)
@@ -3,13 +3,14 @@
 FIND_PATH(CPLEX_INCLUDE_DIR
   ilcplex/cplex.h
-  PATHS "C:/ILOG/CPLEX91/include"
-  PATHS "/opt/ilog/cplex91/include"
+  PATHS "C:/ILOG/CPLEX/include"
+  PATHS "/opt/ilog/cplex/include"
   HINTS ${CPLEX_ROOT_DIR}/include
 )
 FIND_LIBRARY(CPLEX_LIBRARY
-  cplex91
-  PATHS "C:/ILOG/CPLEX91/lib/msvc7/stat_mda"
-  PATHS "/opt/ilog/cplex91/bin"
+  cplex
+  PATHS "C:/ILOG/CPLEX/lib/msvc7/stat_mda"
+  PATHS "/opt/ilog/cplex/bin"
   HINTS ${CPLEX_ROOT_DIR}/bin
+  HINTS ${CPLEX_ROOT_DIR}/lib
 )
 
@@ -18,6 +19,7 @@
 
 FIND_PATH(CPLEX_BIN_DIR
-  cplex91.dll
-  PATHS "C:/ILOG/CPLEX91/bin/x86_win32"
+  cplex.dll
+  PATHS "C:/ILOG/CPLEX/bin/x86_win32"
+  HINTS ${CPLEX_ROOT_DIR}/bin
 )
 
Index: cmake/version.cmake.in
===================================================================
--- cmake/version.cmake.in	(revision 678)
+++ cmake/version.cmake.in	(revision 983)
@@ -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 793)
+++ 	(revision )
@@ -1,156 +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 -Werror 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)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
-
-AC_CONFIG_FILES([
-Makefile
-demo/Makefile
-cmake/version.cmake
-doc/Doxyfile
-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 925)
+++ contrib/CMakeLists.txt	(revision 925)
@@ -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 564)
+++ 	(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 1032)
+++ doc/CMakeLists.txt	(revision 1038)
@@ -11,4 +11,19 @@
   @ONLY
 )
+
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/doc/mainpage.dox.in
+  ${PROJECT_BINARY_DIR}/doc/mainpage.dox
+  @ONLY
+)
+
+# Copy doc from source (if exists)
+IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/html AND 
+    NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html/index.html)
+  MESSAGE(STATUS "Copy doc from source tree")
+  EXECUTE_PROCESS(
+    COMMAND cmake -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/html ${CMAKE_CURRENT_BINARY_DIR}/html
+    )
+ENDIF()
 
 IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
Index: doc/Doxyfile.in
===================================================================
--- doc/Doxyfile.in	(revision 912)
+++ doc/Doxyfile.in	(revision 966)
@@ -1,3 +1,3 @@
-# Doxyfile 1.5.9
+# Doxyfile 1.7.3
 
 #---------------------------------------------------------------------------
@@ -5,6 +5,8 @@
 #---------------------------------------------------------------------------
 DOXYFILE_ENCODING      = UTF-8
-PROJECT_NAME           = @PACKAGE_NAME@
-PROJECT_NUMBER         = @PACKAGE_VERSION@
+PROJECT_NAME           = 
+PROJECT_NUMBER         = 
+PROJECT_BRIEF          =
+PROJECT_LOGO           =
 OUTPUT_DIRECTORY       = 
 CREATE_SUBDIRS         = NO
@@ -30,4 +32,5 @@
 OPTIMIZE_FOR_FORTRAN   = NO
 OPTIMIZE_OUTPUT_VHDL   = NO
+EXTENSION_MAPPING      =
 BUILTIN_STL_SUPPORT    = YES
 CPP_CLI_SUPPORT        = NO
@@ -55,9 +58,12 @@
 HIDE_SCOPE_NAMES       = YES
 SHOW_INCLUDE_FILES     = YES
+FORCE_LOCAL_INCLUDES   = NO
 INLINE_INFO            = YES
 SORT_MEMBER_DOCS       = NO
 SORT_BRIEF_DOCS        = NO
+SORT_MEMBERS_CTORS_1ST = NO
 SORT_GROUP_NAMES       = NO
 SORT_BY_SCOPE_NAME     = NO
+STRICT_PROTO_MATCHING  = NO
 GENERATE_TODOLIST      = YES
 GENERATE_TESTLIST      = YES
@@ -90,6 +96,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"
 INPUT_ENCODING         = UTF-8
@@ -112,4 +120,5 @@
 FILTER_PATTERNS        = 
 FILTER_SOURCE_FILES    = NO
+FILTER_SOURCE_PATTERNS =
 #---------------------------------------------------------------------------
 # configuration options related to source browsing
@@ -138,9 +147,15 @@
 HTML_FOOTER            = 
 HTML_STYLESHEET        = 
+HTML_COLORSTYLE_HUE    = 220
+HTML_COLORSTYLE_SAT    = 100
+HTML_COLORSTYLE_GAMMA  = 80
+HTML_TIMESTAMP         = YES
 HTML_ALIGN_MEMBERS     = YES
-HTML_DYNAMIC_SECTIONS  = NO
+HTML_DYNAMIC_SECTIONS  = YES
 GENERATE_DOCSET        = NO
 DOCSET_FEEDNAME        = "Doxygen generated docs"
 DOCSET_BUNDLE_ID       = org.doxygen.Project
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME  = Publisher
 GENERATE_HTMLHELP      = NO
 CHM_FILE               = 
@@ -154,10 +169,22 @@
 QHP_NAMESPACE          = org.doxygen.Project
 QHP_VIRTUAL_FOLDER     = doc
+QHP_CUST_FILTER_NAME   =
+QHP_CUST_FILTER_ATTRS  =
+QHP_SECT_FILTER_ATTRS  =
 QHG_LOCATION           = 
+GENERATE_ECLIPSEHELP   = NO
+ECLIPSE_DOC_ID         = org.doxygen.Project
 DISABLE_INDEX          = NO
 ENUM_VALUES_PER_LINE   = 4
 GENERATE_TREEVIEW      = NO
+USE_INLINE_TREES       = NO
 TREEVIEW_WIDTH         = 250
+EXT_LINKS_IN_WINDOW    = NO
 FORMULA_FONTSIZE       = 10
+FORMULA_TRANSPARENT    = YES
+USE_MATHJAX            = NO
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+SEARCHENGINE           = YES
+SERVER_BASED_SEARCH    = NO
 #---------------------------------------------------------------------------
 # configuration options related to the LaTeX output
@@ -176,4 +203,5 @@
 LATEX_BATCHMODE        = NO
 LATEX_HIDE_INDICES     = NO
+LATEX_SOURCE_CODE      = NO
 #---------------------------------------------------------------------------
 # configuration options related to the RTF output
@@ -224,5 +252,5 @@
 SKIP_FUNCTION_MACROS   = YES
 #---------------------------------------------------------------------------
-# Options related to the search engine   
+# Configuration::additions related to external references
 #---------------------------------------------------------------------------
 TAGFILES               = "@abs_top_builddir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
@@ -238,4 +266,5 @@
 HIDE_UNDOC_RELATIONS   = YES
 HAVE_DOT               = YES
+DOT_NUM_THREADS        = 0
 DOT_FONTNAME           = FreeSans
 DOT_FONTSIZE           = 10
@@ -255,4 +284,5 @@
 DOT_PATH               = 
 DOTFILE_DIRS           = 
+MSCFILE_DIRS           =
 DOT_GRAPH_MAX_NODES    = 50
 MAX_DOT_GRAPH_DEPTH    = 0
@@ -261,6 +291,2 @@
 GENERATE_LEGEND        = YES
 DOT_CLEANUP            = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-SEARCHENGINE           = NO
Index: doc/DoxygenLayout.xml
===================================================================
--- doc/DoxygenLayout.xml	(revision 316)
+++ doc/DoxygenLayout.xml	(revision 928)
@@ -3,22 +3,22 @@
   <navindex>
     <tab type="mainpage" visible="yes" title=""/>
-    <tab type="modules" visible="yes" title=""/>
+    <tab type="modules" visible="yes" title="" intro=""/>
     <tab type="classes" visible="yes" title="">
-      <tab type="classes" visible="yes" title=""/>
-      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> 
-      <tab type="hierarchy" visible="yes" title=""/>
-      <tab type="classmembers" visible="yes" title=""/>
+      <tab type="classes" visible="yes" title="" intro=""/>
+      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="hierarchy" visible="yes" title="" intro=""/>
+      <tab type="classmembers" visible="yes" title="" intro=""/>
     </tab>
     <tab type="namespaces" visible="yes" title="">
-      <tab type="namespaces" visible="yes" title=""/>
-      <tab type="namespacemembers" visible="yes" title=""/>
+      <tab type="namespaces" visible="yes" title="" intro=""/>
+      <tab type="namespacemembers" visible="yes" title="" intro=""/>
     </tab>
     <tab type="files" visible="yes" title="">
-      <tab type="files" visible="yes" title=""/>
-      <tab type="globals" visible="yes" title=""/>
+      <tab type="files" visible="yes" title="" intro=""/>
+      <tab type="globals" visible="yes" title="" intro=""/>
     </tab>
-    <tab type="dirs" visible="yes" title=""/>
-    <tab type="examples" visible="yes" title=""/>  
-    <tab type="pages" visible="yes" title=""/>
+    <tab type="dirs" visible="yes" title="" intro=""/>
+    <tab type="examples" visible="yes" title="" intro=""/>
+    <tab type="pages" visible="yes" title="" intro=""/>
   </navindex>
 
Index: c/Makefile.am
===================================================================
--- doc/Makefile.am	(revision 1032)
+++ 	(revision )
@@ -1,124 +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/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 \
-	tsp.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 440)
+++ doc/coding_style.dox	(revision 919)
@@ -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 440)
+++ doc/dirs.dox	(revision 925)
@@ -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 1036)
+++ doc/groups.dox	(revision 1038)
@@ -407,8 +407,18 @@
    strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
 
-In general NetworkSimplex is the most efficient implementation,
-but in special cases other algorithms could be faster.
+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).
 */
 
@@ -449,5 +459,5 @@
 
 This group contains the algorithms for finding minimum mean cycles
-\ref clrs01algorithms, \ref amo93networkflows.
+\ref amo93networkflows, \ref karp78characterization.
 
 The \e minimum \e mean \e cycle \e problem is to find a directed cycle
@@ -465,12 +475,11 @@
 
 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 \ref karp78characterization.
 - \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
-  version of Karp's algorithm \ref dasdan98minmeancycle.
+  version of Karp's algorithm \ref hartmann93finding.
 - \ref HowardMmc Howard's policy iteration algorithm
-  \ref dasdan98minmeancycle.
-
-In practice, the \ref HowardMmc "Howard" algorithm proved to be by far the
+  \ref dasdan98minmeancycle, \ref 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.
@@ -540,5 +549,5 @@
 
 /**
-@defgroup planar Planarity Embedding and Drawing
+@defgroup planar Planar Embedding and Drawing
 @ingroup algs
 \brief Algorithms for planarity checking, embedding and drawing
Index: doc/lgf.dox
===================================================================
--- doc/lgf.dox	(revision 440)
+++ doc/lgf.dox	(revision 1024)
@@ -64,4 +64,21 @@
 \endcode
 
+The \e LGF files can also contain bipartite graphs, in this case a
+\c @red_nodes and a \c @blue_nodes sections describe the node set of the
+graph. If a map is in both of these sections, then it can be used as a
+regular node map.
+
+\code
+ @red_nodes
+ label  only_red_map   name
+ 1      "cherry"       "John"
+ 2      "Santa Claus"  "Jack"
+ 3      "blood"        "Jason"
+ @blue_nodes
+ label  name
+ 4      "Elisabeth"
+ 5      "Eve"
+\endcode
+
 The \c \@arcs section is very similar to the \c \@nodes section,
 it again starts with a header line describing the names of the maps,
@@ -79,8 +96,19 @@
 \endcode
 
+If there is no map in the \c \@arcs section at all, then it must be
+indicated by a sole '-' sign in the first line.
+
+\code
+ @arcs
+         -
+ 1   2
+ 1   3
+ 2   3
+\endcode
+
 The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can
 also store the edge set of an undirected graph. In such case there is
 a conventional method for store arc maps in the file, if two columns
-has the same caption with \c '+' and \c '-' prefix, then these columns
+have the same caption with \c '+' and \c '-' prefix, then these columns
 can be regarded as the values of an arc map.
 
Index: c/mainpage.dox
===================================================================
--- doc/mainpage.dox	(revision 877)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/* -*- mode: C++; indent-tabs-mode: nil; -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library.
- *
- * Copyright (C) 2003-2010
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-/**
-\mainpage LEMON Documentation
-
-\section intro Introduction
-
-<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
-and <b>O</b>ptimization in <b>N</b>etworks</i>.
-It is a C++ template library providing efficient implementations of common
-data structures and algorithms with focus on combinatorial optimization
-tasks connected mainly with graphs and networks.
-
-<b>
-LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
-project.
-You are free to use it in your commercial or
-non-commercial applications under very permissive
-\ref license "license terms".
-</b>
-
-The project is maintained by the
-<a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
-Combinatorial Optimization</a> \ref egres
-at the Operations Research Department of the
-<a href="http://www.elte.hu/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
-Budapest, Hungary.
-LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
-initiative \ref coinor.
-
-\section howtoread How to Read the Documentation
-
-If you would like to get to know the library, see
-<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
-
-If you are interested in starting to use the library, see the <a class="el"
-href="http://lemon.cs.elte.hu/trac/lemon/wiki/InstallGuide/">Installation
-Guide</a>.
-
-If you know what you are looking for, then try to find it under the
-<a class="el" href="modules.html">Modules</a> section.
-
-If you are a user of the old (0.x) series of LEMON, please check out the
-\ref migration "Migration Guide" for the backward incompatibilities.
-*/
Index: doc/mainpage.dox.in
===================================================================
--- doc/mainpage.dox.in	(revision 930)
+++ doc/mainpage.dox.in	(revision 930)
@@ -0,0 +1,61 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+/**
+\mainpage @PACKAGE_NAME@ @PACKAGE_VERSION@ Documentation
+
+\section intro Introduction
+
+<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
+and <b>O</b>ptimization in <b>N</b>etworks</i>.
+It is a C++ template library providing efficient implementations of common
+data structures and algorithms with focus on combinatorial optimization
+tasks connected mainly with graphs and networks.
+
+<b>
+LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
+project.
+You are free to use it in your commercial or
+non-commercial applications under very permissive
+\ref license "license terms".
+</b>
+
+The project is maintained by the
+<a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
+Combinatorial Optimization</a> \ref egres
+at the Operations Research Department of the
+<a href="http://www.elte.hu/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
+Budapest, Hungary.
+LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
+initiative \ref coinor.
+
+\section howtoread How to Read the Documentation
+
+If you would like to get to know the library, see
+<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
+
+If you are interested in starting to use the library, see the <a class="el"
+href="http://lemon.cs.elte.hu/trac/lemon/wiki/InstallGuide/">Installation
+Guide</a>.
+
+If you know what you are looking for, then try to find it under the
+<a class="el" href="modules.html">Modules</a> section.
+
+If you are a user of the old (0.x) series of LEMON, please check out the
+\ref migration "Migration Guide" for the backward incompatibilities.
+*/
Index: doc/min_cost_flow.dox
===================================================================
--- doc/min_cost_flow.dox	(revision 877)
+++ doc/min_cost_flow.dox	(revision 1002)
@@ -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 904)
+++ doc/references.bib	(revision 1002)
@@ -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/}}
 }
 
@@ -212,4 +211,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 +235,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 %%%%%
Index: lemon/CMakeLists.txt
===================================================================
--- lemon/CMakeLists.txt	(revision 908)
+++ lemon/CMakeLists.txt	(revision 981)
@@ -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
@@ -58,4 +58,5 @@
   TARGETS lemon
   ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
   COMPONENT library
 )
Index: mon/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 1031)
+++ 	(revision )
@@ -1,158 +1,0 @@
-EXTRA_DIST += \
-	lemon/lemon.pc.in \
-	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/christofides_tsp.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/greedy_tsp.h \
-	lemon/grid_graph.h \
-	lemon/grosso_locatelli_pullan_mc.h \
-	lemon/hartmann_orlin_mmc.h \
-	lemon/howard_mmc.h \
-	lemon/hypercube_graph.h \
-	lemon/insertion_tsp.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/max_cardinality_search.h \
-	lemon/nagamochi_ibaraki.h \
-	lemon/nauty_reader.h \
-	lemon/nearest_neighbor_tsp.h \
-	lemon/network_simplex.h \
-	lemon/opt2_tsp.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 877)
+++ lemon/adaptors.h	(revision 998)
@@ -1372,5 +1372,5 @@
     /// and edge filter maps.
     SubGraph(GR& graph, NF& node_filter, EF& edge_filter) {
-      initialize(graph, node_filter, edge_filter);
+      this->initialize(graph, node_filter, edge_filter);
     }
 
@@ -2278,5 +2278,5 @@
     /// Creates an undirected graph from the given digraph.
     Undirector(DGR& digraph) {
-      initialize(digraph);
+      this->initialize(digraph);
     }
 
Index: lemon/bfs.h
===================================================================
--- lemon/bfs.h	(revision 877)
+++ lemon/bfs.h	(revision 976)
@@ -1252,4 +1252,5 @@
       }
       _Visitor& visitor;
+      Constraints() {}
     };
   };
Index: lemon/bits/alteration_notifier.h
===================================================================
--- lemon/bits/alteration_notifier.h	(revision 440)
+++ lemon/bits/alteration_notifier.h	(revision 979)
@@ -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/bezier.h
===================================================================
--- lemon/bits/bezier.h	(revision 440)
+++ lemon/bits/bezier.h	(revision 997)
@@ -160,5 +160,5 @@
     const Point d=(a+b)/2;
     const Point e=(b+c)/2;
-    const Point f=(d+e)/2;
+    // const Point f=(d+e)/2;
     R f1=_f(Bezier3(p1,a,d,e),_d);
     R f2=_f(Bezier3(e,d,c,p4),_d);
Index: lemon/bits/edge_set_extender.h
===================================================================
--- lemon/bits/edge_set_extender.h	(revision 884)
+++ lemon/bits/edge_set_extender.h	(revision 1000)
@@ -524,5 +524,5 @@
     // Returns the base node of the iterator
     Node baseNode(const IncEdgeIt &e) const {
-      return e.direction ? u(e) : v(e);
+      return e.direction ? this->u(e) : this->v(e);
     }
     // Running node of the iterator
@@ -530,5 +530,5 @@
     // Returns the running node of the iterator
     Node runningNode(const IncEdgeIt &e) const {
-      return e.direction ? v(e) : u(e);
+      return e.direction ? this->v(e) : this->u(e);
     }
 
Index: lemon/bits/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 778)
+++ lemon/bits/graph_extender.h	(revision 1027)
@@ -588,5 +588,5 @@
     // Returns the base node of the iterator
     Node baseNode(const IncEdgeIt &edge) const {
-      return edge._direction ? u(edge) : v(edge);
+      return edge._direction ? this->u(edge) : this->v(edge);
     }
     // Running node of the iterator
@@ -594,5 +594,5 @@
     // Returns the running node of the iterator
     Node runningNode(const IncEdgeIt &edge) const {
-      return edge._direction ? v(edge) : u(edge);
+      return edge._direction ? this->v(edge) : this->u(edge);
     }
 
@@ -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 979)
+++ lemon/bits/lock.h	(revision 979)
@@ -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-2012
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software 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/solver_bits.h
===================================================================
--- lemon/bits/solver_bits.h	(revision 877)
+++ lemon/bits/solver_bits.h	(revision 989)
@@ -45,4 +45,5 @@
       void clear() {
         first_item = -1;
+        last_item = -1;
         first_free_item = -1;
         items.clear();
Index: lemon/bits/traits.h
===================================================================
--- lemon/bits/traits.h	(revision 616)
+++ lemon/bits/traits.h	(revision 1026)
@@ -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 877)
+++ lemon/bits/windows.cc	(revision 1001)
@@ -41,5 +41,7 @@
 #include <unistd.h>
 #include <ctime>
+#ifndef WIN32
 #include <sys/times.h>
+#endif
 #include <sys/time.h>
 #endif
@@ -129,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 529)
+++ lemon/bits/windows.h	(revision 979)
@@ -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 877)
+++ lemon/capacity_scaling.h	(revision 1004)
@@ -71,4 +71,9 @@
   /// solution method.
   ///
+  /// This algorithm is typically slower than \ref CostScaling and
+  /// \ref NetworkSimplex, but in special cases, it can be more
+  /// efficient than them.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
+  ///
   /// Most of the parameters of the problem (except for the digraph)
   /// can be given using separate functions, and the algorithm can be
@@ -87,8 +92,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>
@@ -423,5 +429,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.
     ///
@@ -676,5 +682,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 +707,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
Index: lemon/cbc.cc
===================================================================
--- lemon/cbc.cc	(revision 746)
+++ lemon/cbc.cc	(revision 1000)
@@ -26,10 +26,5 @@
 #include <coin/OsiSolverInterface.hpp>
 
-#ifdef COIN_HAS_CLP
 #include "coin/OsiClpSolverInterface.hpp"
-#endif
-#ifdef COIN_HAS_OSL
-#include "coin/OsiOslSolverInterface.hpp"
-#endif
 
 #include "coin/CbcCutGenerator.hpp"
@@ -271,11 +266,5 @@
       delete _osi_solver;
     }
-#ifdef COIN_HAS_CLP
     _osi_solver = new OsiClpSolverInterface();
-#elif COIN_HAS_OSL
-    _osi_solver = new OsiOslSolverInterface();
-#else
-#error Cannot instantiate Osi solver
-#endif
 
     _osi_solver->loadFromCoinModel(*_prob);
@@ -329,5 +318,4 @@
       _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
 
-#ifdef COIN_HAS_CLP
       OsiClpSolverInterface* osiclp =
         dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
@@ -335,5 +323,4 @@
         osiclp->setupForRepeatedUse(2, 0);
       }
-#endif
 
       CbcRounding heuristic1(*_cbc_model);
@@ -449,6 +436,4 @@
 
     _prob = new CoinModel();
-    rows.clear();
-    cols.clear();
   }
 
Index: lemon/circulation.h
===================================================================
--- lemon/circulation.h	(revision 877)
+++ lemon/circulation.h	(revision 998)
@@ -573,6 +573,4 @@
 
       Node act;
-      Node bact=INVALID;
-      Node last_activated=INVALID;
       while((act=_level->highestActive())!=INVALID) {
         int actlevel=(*_level)[act];
Index: lemon/clp.cc
===================================================================
--- lemon/clp.cc	(revision 877)
+++ lemon/clp.cc	(revision 989)
@@ -438,6 +438,4 @@
     delete _prob;
     _prob = new ClpSimplex();
-    rows.clear();
-    cols.clear();
     _col_names_ref.clear();
     _clear_temporals();
Index: lemon/concept_check.h
===================================================================
--- lemon/concept_check.h	(revision 440)
+++ lemon/concept_check.h	(revision 997)
@@ -36,4 +36,20 @@
 
   template <class T> inline void ignore_unused_variable_warning(const T&) { }
+  template <class T1, class T2>
+  inline void ignore_unused_variable_warning(const T1&, const T2&) { }
+  template <class T1, class T2, class T3>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&) { }
+  template <class T1, class T2, class T3, class T4>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&) { }
+  template <class T1, class T2, class T3, class T4, class T5>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&,
+                                             const T5&) { }
+  template <class T1, class T2, class T3, class T4, class T5, class T6>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&,
+                                             const T5&, const T6&) { }
 
   ///\e
Index: lemon/concepts/bpgraph.h
===================================================================
--- lemon/concepts/bpgraph.h	(revision 1028)
+++ lemon/concepts/bpgraph.h	(revision 1028)
@@ -0,0 +1,1026 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup 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) { 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) {
+          ignore_unused_variable_warning(n);
+          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) {
+          ignore_unused_variable_warning(n);
+          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 incomming arc iterator
+      /// (i.e. the target node of the corresponding arc).
+      Node baseNode(InArcIt) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// Returns the running node of the given incomming arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node runningNode(InArcIt) const { return INVALID; }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<BaseBpGraphComponent, _BpGraph>();
+          checkConcept<IterableBpGraphComponent<>, _BpGraph>();
+          checkConcept<IDableBpGraphComponent<>, _BpGraph>();
+          checkConcept<MappableBpGraphComponent<>, _BpGraph>();
+        }
+      };
+
+    };
+
+  }
+
+}
+
+#endif
Index: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 877)
+++ lemon/concepts/graph.h	(revision 1018)
@@ -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&) {}
 
Index: lemon/concepts/graph_components.h
===================================================================
--- lemon/concepts/graph_components.h	(revision 877)
+++ lemon/concepts/graph_components.h	(revision 1028)
@@ -109,4 +109,6 @@
 
           bool b;
+          ignore_unused_variable_warning(b);
+
           b = (ia == ib) && (ia != ib);
           b = (ia == INVALID) && (ib != INVALID);
@@ -116,4 +118,5 @@
         const _GraphItem &ia;
         const _GraphItem &ib;
+        Constraints() {}
       };
     };
@@ -175,4 +178,5 @@
 
         const _Digraph& digraph;
+        Constraints() {}
       };
     };
@@ -291,4 +295,171 @@
 
         const _Graph& graph;
+      Constraints() {}
+      };
+
+    };
+
+    /// \brief Base skeleton class for undirected bipartite graphs.
+    ///
+    /// This class describes the base interface of undirected
+    /// bipartite graph types.  All bipartite graph %concepts have to
+    /// conform to this class.  It extends the interface of \ref
+    /// BaseGraphComponent with an \c Edge type and functions to get
+    /// the end nodes of edges, to convert from arcs to edges and to
+    /// get both direction of edges.
+    class BaseBpGraphComponent : public BaseGraphComponent {
+    public:
+
+      typedef BaseBpGraphComponent BpGraph;
+
+      typedef BaseDigraphComponent::Node Node;
+      typedef BaseDigraphComponent::Arc Arc;
+
+      /// \brief Class to represent red nodes.
+      ///
+      /// This class represents the red nodes of the graph. The red
+      /// nodes can also be used as normal nodes.
+      class RedNode : public Node {
+        typedef Node Parent;
+
+      public:
+        /// \brief Default constructor.
+        ///
+        /// Default constructor.
+        /// \warning The default constructor is not required to set
+        /// the item to some well-defined value. So you should consider it
+        /// as uninitialized.
+        RedNode() {}
+
+        /// \brief Copy constructor.
+        ///
+        /// Copy constructor.
+        RedNode(const RedNode &) : Parent() {}
+
+        /// \brief Constructor for conversion from \c INVALID.
+        ///
+        /// Constructor for conversion from \c INVALID.
+        /// It initializes the item to be invalid.
+        /// \sa Invalid for more details.
+        RedNode(Invalid) {}
+      };
+
+      /// \brief Class to represent blue nodes.
+      ///
+      /// This class represents the blue nodes of the graph. The blue
+      /// nodes can also be used as normal nodes.
+      class BlueNode : public Node {
+        typedef Node Parent;
+
+      public:
+        /// \brief Default constructor.
+        ///
+        /// Default constructor.
+        /// \warning The default constructor is not required to set
+        /// the item to some well-defined value. So you should consider it
+        /// as uninitialized.
+        BlueNode() {}
+
+        /// \brief Copy constructor.
+        ///
+        /// Copy constructor.
+        BlueNode(const BlueNode &) : Parent() {}
+
+        /// \brief Constructor for conversion from \c INVALID.
+        ///
+        /// Constructor for conversion from \c INVALID.
+        /// It initializes the item to be invalid.
+        /// \sa Invalid for more details.
+        BlueNode(Invalid) {}
+
+        /// \brief Constructor for conversion from a node.
+        ///
+        /// Constructor for conversion from a node. The conversion can
+        /// be invalid, since the Node can be member of the red
+        /// set.
+        BlueNode(const Node&) {}
+      };
+
+      /// \brief Gives back %true for red nodes.
+      ///
+      /// Gives back %true for red nodes.
+      bool red(const Node&) const { return true; }
+
+      /// \brief Gives back %true for blue nodes.
+      ///
+      /// Gives back %true for blue nodes.
+      bool blue(const Node&) const { return true; }
+
+      /// \brief Gives back the red end node of the edge.
+      /// 
+      /// Gives back the red end node of the edge.
+      RedNode redNode(const Edge&) const { return RedNode(); }
+
+      /// \brief Gives back the blue end node of the edge.
+      /// 
+      /// Gives back the blue end node of the edge.
+      BlueNode blueNode(const Edge&) const { return BlueNode(); }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts unsafely the node to red node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. It should be called only if the node is from the red
+      /// partition or INVALID.
+      BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); }
+
+      /// \brief Converts the node to red node object.
+      ///
+      /// This function converts safely the node to red node
+      /// object. If the node is not from the red partition, then it
+      /// returns INVALID.
+      RedNode asRedNode(const Node&) const { return RedNode(); }
+
+      /// \brief Converts the node to blue node object.
+      ///
+      /// This function converts unsafely the node to blue node
+      /// object. If the node is not from the blue partition, then it
+      /// returns INVALID.
+      BlueNode asBlueNode(const Node&) const { return BlueNode(); }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        typedef typename _BpGraph::Node Node;
+        typedef typename _BpGraph::RedNode RedNode;
+        typedef typename _BpGraph::BlueNode BlueNode;
+        typedef typename _BpGraph::Arc Arc;
+        typedef typename _BpGraph::Edge Edge;
+
+        void constraints() {
+          checkConcept<BaseGraphComponent, _BpGraph>();
+          checkConcept<GraphItem<'n'>, RedNode>();
+          checkConcept<GraphItem<'n'>, BlueNode>();
+          {
+            Node n;
+            RedNode rn;
+            BlueNode bn;
+            Node rnan = rn;
+            Node bnan = bn;
+            Edge e;
+            bool b;
+            b = bpgraph.red(rnan);
+            b = bpgraph.blue(bnan);
+            rn = bpgraph.redNode(e);
+            bn = bpgraph.blueNode(e);
+            rn = bpgraph.asRedNodeUnsafe(rnan);
+            bn = bpgraph.asBlueNodeUnsafe(bnan);
+            rn = bpgraph.asRedNode(rnan);
+            bn = bpgraph.asBlueNode(bnan);
+            ignore_unused_variable_warning(b);
+          }
+        }
+
+        const _BpGraph& bpgraph;
       };
 
@@ -370,4 +541,5 @@
 
         const _Digraph& digraph;
+        Constraints() {}
       };
     };
@@ -422,4 +594,69 @@
 
         const _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for \e idable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of \e idable undirected
+    /// bipartite graphs. It extends \ref IDableGraphComponent with
+    /// the core ID functions of undirected bipartite graphs. Beside
+    /// the regular node ids, this class also provides ids within the
+    /// the red and blue sets of the nodes. This concept is part of
+    /// the BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class IDableBpGraphComponent : public IDableGraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef IDableGraphComponent<BAS> Parent;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+
+      using Parent::id;
+
+      /// \brief Return a unique integer id for the given node in the red set.
+      ///
+      /// Return a unique integer id for the given node in the red set.
+      int id(const RedNode&) const { return -1; }
+
+      /// \brief Return a unique integer id for the given node in the blue set.
+      ///
+      /// Return a unique integer id for the given node in the blue set.
+      int id(const BlueNode&) const { return -1; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// node id in the red set.
+      ///
+      /// Return an integer greater or equal to the maximum
+      /// node id in the red set.
+      int maxRedId() const { return -1; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// node id in the blue set.
+      ///
+      /// Return an integer greater or equal to the maximum
+      /// node id in the blue set.
+      int maxBlueId() const { return -1; }
+
+      template <typename _BpGraph>
+      struct Constraints {
+
+        void constraints() {
+          checkConcept<IDableGraphComponent<Base>, _BpGraph>();
+          typename _BpGraph::Node node;
+          typename _BpGraph::RedNode red;
+          typename _BpGraph::BlueNode blue;
+          int rid = bpgraph.id(red);
+          int bid = bpgraph.id(blue);
+          rid = bpgraph.maxRedId();
+          bid = bpgraph.maxBlueId();
+          ignore_unused_variable_warning(rid);
+          ignore_unused_variable_warning(bid);
+        }
+
+        const _BpGraph& bpgraph;
       };
     };
@@ -490,4 +727,6 @@
           _GraphItemIt it3 = it1;
           _GraphItemIt it4 = INVALID;
+          ignore_unused_variable_warning(it3);
+          ignore_unused_variable_warning(it4);
 
           it2 = ++it1;
@@ -499,4 +738,5 @@
         }
         const GR& g;
+        Constraints() {}
       };
     };
@@ -578,4 +818,6 @@
           _GraphIncIt it3 = it1;
           _GraphIncIt it4 = INVALID;
+          ignore_unused_variable_warning(it3);
+          ignore_unused_variable_warning(it4);
 
           it2 = ++it1;
@@ -587,4 +829,5 @@
         const Base& node;
         const GR& graph;
+        Constraints() {}
       };
     };
@@ -763,4 +1006,5 @@
 
         const _Digraph& digraph;
+        Constraints() {}
       };
     };
@@ -887,4 +1131,96 @@
 
         const _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for iterable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of iterable undirected
+    /// bipartite graphs. It extends \ref IterableGraphComponent with
+    /// the core iterable interface of undirected bipartite graphs.
+    /// This concept is part of the BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class IterableBpGraphComponent : public IterableGraphComponent<BAS> {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+      typedef typename Base::Arc Arc;
+      typedef typename Base::Edge Edge;
+      
+      typedef IterableBpGraphComponent BpGraph;
+
+      using IterableGraphComponent<BAS>::first;
+      using IterableGraphComponent<BAS>::next;
+
+      /// \name Base Iteration
+      ///
+      /// This interface provides functions for iteration on red and blue nodes.
+      ///
+      /// @{
+
+      /// \brief Return the first red node.
+      ///
+      /// This function gives back the first red node in the iteration order.
+      void first(RedNode&) const {}
+
+      /// \brief Return the next red node.
+      ///
+      /// This function gives back the next red node in the iteration order.
+      void next(RedNode&) const {}
+
+      /// \brief Return the first blue node.
+      ///
+      /// This function gives back the first blue node in the iteration order.
+      void first(BlueNode&) const {}
+
+      /// \brief Return the next blue node.
+      ///
+      /// This function gives back the next blue node in the iteration order.
+      void next(BlueNode&) const {}
+
+
+      /// @}
+
+      /// \name Class Based Iteration
+      ///
+      /// This interface provides iterator classes for red and blue nodes.
+      ///
+      /// @{
+
+      /// \brief This iterator goes through each red node.
+      ///
+      /// This iterator goes through each red node.
+      typedef GraphItemIt<BpGraph, RedNode> RedNodeIt;
+
+      /// \brief This iterator goes through each blue node.
+      ///
+      /// This iterator goes through each blue node.
+      typedef GraphItemIt<BpGraph, BlueNode> BlueNodeIt;
+
+      /// @}
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<IterableGraphComponent<Base>, _BpGraph>();
+
+          typename _BpGraph::RedNode rn(INVALID);
+          bpgraph.first(rn);
+          bpgraph.next(rn); 
+          typename _BpGraph::BlueNode bn(INVALID);
+          bpgraph.first(bn);
+          bpgraph.next(bn);
+
+          checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::RedNode>,
+            typename _BpGraph::RedNodeIt>();
+          checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::BlueNode>,
+            typename _BpGraph::BlueNodeIt>();
+        }
+
+        const _BpGraph& bpgraph;
       };
     };
@@ -915,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;
       }
 
@@ -926,5 +1265,5 @@
       /// This function gives back the arc alteration notifier.
       ArcNotifier& notifier(Arc) const {
-        return ArcNotifier();
+        return arc_notifier;
       }
 
@@ -944,4 +1283,5 @@
 
         const _Digraph& digraph;
+        Constraints() {}
       };
     };
@@ -961,4 +1301,5 @@
 
       typedef BAS Base;
+      typedef AlterableDigraphComponent<Base> Parent;
       typedef typename Base::Edge Edge;
 
@@ -968,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;
       }
 
@@ -985,4 +1330,67 @@
 
         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());
+          ignore_unused_variable_warning(rnn);
+          ignore_unused_variable_warning(bnn);
+        }
+
+        const _BpGraph& bpgraph;
       };
     };
@@ -1062,4 +1470,5 @@
         const GR &g;
         const typename GraphMap::Value &t;
+        Constraints() {}
       };
 
@@ -1200,4 +1609,5 @@
 
         const _Digraph& digraph;
+        Constraints() {}
       };
     };
@@ -1285,4 +1695,149 @@
 
         const _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for mappable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of mappable undirected
+    /// bipartite graphs.  It extends \ref MappableGraphComponent with
+    /// the standard graph map class for red and blue nodes (\c
+    /// RedNodeMap and BlueNodeMap). This concept is part of the
+    /// BpGraph concept.
+    template <typename BAS = BaseBpGraphComponent>
+    class MappableBpGraphComponent : public MappableGraphComponent<BAS>  {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+
+      typedef MappableBpGraphComponent BpGraph;
+
+      /// \brief Standard graph map for the red nodes.
+      ///
+      /// Standard graph map for the red nodes.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class RedNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> {
+        typedef GraphMap<MappableBpGraphComponent, Node, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the graph.
+        explicit RedNodeMap(const MappableBpGraphComponent& graph)
+          : Parent(graph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the graph and initalize the values.
+        RedNodeMap(const MappableBpGraphComponent& graph, const V& value)
+          : Parent(graph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        RedNodeMap(const RedNodeMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        RedNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+      /// \brief Standard graph map for the blue nodes.
+      ///
+      /// Standard graph map for the blue nodes.
+      /// It conforms to the ReferenceMap concept.
+      template <typename V>
+      class BlueNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> {
+        typedef GraphMap<MappableBpGraphComponent, Node, V> Parent;
+
+      public:
+        /// \brief Construct a new map.
+        ///
+        /// Construct a new map for the graph.
+        explicit BlueNodeMap(const MappableBpGraphComponent& graph)
+          : Parent(graph) {}
+
+        /// \brief Construct a new map with default value.
+        ///
+        /// Construct a new map for the graph and initalize the values.
+        BlueNodeMap(const MappableBpGraphComponent& graph, const V& value)
+          : Parent(graph, value) {}
+
+      private:
+        /// \brief Copy constructor.
+        ///
+        /// Copy Constructor.
+        BlueNodeMap(const BlueNodeMap& nm) : Parent(nm) {}
+
+        /// \brief Assignment operator.
+        ///
+        /// Assignment operator.
+        template <typename CMap>
+        BlueNodeMap& operator=(const CMap&) {
+          checkConcept<ReadMap<Node, V>, CMap>();
+          return *this;
+        }
+
+      };
+
+
+      template <typename _BpGraph>
+      struct Constraints {
+
+        struct Dummy {
+          int value;
+          Dummy() : value(0) {}
+          Dummy(int _v) : value(_v) {}
+        };
+
+        void constraints() {
+          checkConcept<MappableGraphComponent<Base>, _BpGraph>();
+
+          { // int map test
+            typedef typename _BpGraph::template RedNodeMap<int>
+              IntRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, int>,
+              IntRedNodeMap >();
+          } { // bool map test
+            typedef typename _BpGraph::template RedNodeMap<bool>
+              BoolRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, bool>,
+              BoolRedNodeMap >();
+          } { // Dummy map test
+            typedef typename _BpGraph::template RedNodeMap<Dummy>
+              DummyRedNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, Dummy>,
+              DummyRedNodeMap >();
+          }
+
+          { // int map test
+            typedef typename _BpGraph::template BlueNodeMap<int>
+              IntBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, int>,
+              IntBlueNodeMap >();
+          } { // bool map test
+            typedef typename _BpGraph::template BlueNodeMap<bool>
+              BoolBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, bool>,
+              BoolBlueNodeMap >();
+          } { // Dummy map test
+            typedef typename _BpGraph::template BlueNodeMap<Dummy>
+              DummyBlueNodeMap;
+            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, Dummy>,
+              DummyBlueNodeMap >();
+          }
+        }
+
+        const _BpGraph& bpgraph;
       };
     };
@@ -1329,4 +1884,5 @@
 
         _Digraph& digraph;
+        Constraints() {}
       };
     };
@@ -1373,4 +1929,64 @@
 
         _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for extendable undirected bipartite graphs.
+    ///
+    /// This class describes the interface of extendable undirected
+    /// bipartite graphs. It extends \ref BaseGraphComponent with
+    /// functions for adding nodes and edges to the graph. This
+    /// concept requires \ref AlterableBpGraphComponent.
+    template <typename BAS = BaseBpGraphComponent>
+    class ExtendableBpGraphComponent : public BAS {
+    public:
+
+      typedef BAS Base;
+      typedef typename Base::Node Node;
+      typedef typename Base::RedNode RedNode;
+      typedef typename Base::BlueNode BlueNode;
+      typedef typename Base::Edge Edge;
+
+      /// \brief Add a new red node to the digraph.
+      ///
+      /// This function adds a red new node to the digraph.
+      RedNode addRedNode() {
+        return INVALID;
+      }
+
+      /// \brief Add a new blue node to the digraph.
+      ///
+      /// This function adds a blue new node to the digraph.
+      BlueNode addBlueNode() {
+        return INVALID;
+      }
+
+      /// \brief Add a new edge connecting the given two nodes.
+      ///
+      /// This function adds a new edge connecting the given two nodes
+      /// of the graph. The first node has to be a red node, and the
+      /// second one a blue node.
+      Edge addEdge(const RedNode&, const BlueNode&) {
+        return INVALID;
+      }
+      Edge addEdge(const BlueNode&, const RedNode&) {
+        return INVALID;
+      }
+
+      template <typename _BpGraph>
+      struct Constraints {
+        void constraints() {
+          checkConcept<Base, _BpGraph>();
+          typename _BpGraph::RedNode red_node;
+          typename _BpGraph::BlueNode blue_node;
+          red_node = bpgraph.addRedNode();
+          blue_node = bpgraph.addBlueNode();
+          typename _BpGraph::Edge edge;
+          edge = bpgraph.addEdge(red_node, blue_node);
+          edge = bpgraph.addEdge(blue_node, red_node);
+        }
+
+        _BpGraph& bpgraph;
       };
     };
@@ -1412,4 +2028,5 @@
 
         _Digraph& digraph;
+        Constraints() {}
       };
     };
@@ -1451,6 +2068,16 @@
 
         _Graph& graph;
-      };
-    };
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for erasable undirected graphs.
+    ///
+    /// This class describes the interface of erasable undirected
+    /// bipartite graphs. It extends \ref BaseBpGraphComponent with
+    /// functions for removing nodes and edges from the graph. This
+    /// concept requires \ref AlterableBpGraphComponent.
+    template <typename BAS = BaseBpGraphComponent>
+    class ErasableBpGraphComponent : public ErasableGraphComponent<BAS> {};
 
     /// \brief Skeleton class for clearable directed graphs.
@@ -1479,4 +2106,5 @@
 
         _Digraph& digraph;
+        Constraints() {}
       };
     };
@@ -1489,24 +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;
-      };
-    };
+    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 877)
+++ lemon/concepts/heap.h	(revision 976)
@@ -315,4 +315,5 @@
         _Heap& heap;
         ItemIntMap& map;
+        Constraints() {}
       };
     };
Index: lemon/concepts/maps.h
===================================================================
--- lemon/concepts/maps.h	(revision 718)
+++ lemon/concepts/maps.h	(revision 997)
@@ -50,5 +50,5 @@
       /// Returns the value associated with the given key.
       Value operator[](const Key &) const {
-        return *static_cast<Value *>(0);
+        return *(static_cast<Value *>(0)+1);
       }
 
@@ -69,4 +69,5 @@
         const typename _ReadMap::Key& own_key;
         const _ReadMap& m;
+        Constraints() {}
       };
 
@@ -110,4 +111,5 @@
         const typename _WriteMap::Value& own_val;
         _WriteMap& m;
+        Constraints() {}
       };
     };
@@ -130,5 +132,6 @@
       /// Returns the value associated with the given key.
       Value operator[](const Key &) const {
-        return *static_cast<Value *>(0);
+        Value *r = 0;
+        return *r;
       }
 
@@ -170,10 +173,12 @@
       /// Returns a reference to the value associated with the given key.
       Reference operator[](const Key &) {
-        return *static_cast<Value *>(0);
+        Value *r = 0;
+        return *r;
       }
 
       /// Returns a const reference to the value associated with the given key.
       ConstReference operator[](const Key &) const {
-        return *static_cast<Value *>(0);
+        Value *r = 0;
+        return *r;
       }
 
@@ -206,4 +211,5 @@
         typename _ReferenceMap::ConstReference own_cref;
         _ReferenceMap& m;
+        Constraints() {}
       };
     };
Index: lemon/concepts/path.h
===================================================================
--- lemon/concepts/path.h	(revision 785)
+++ lemon/concepts/path.h	(revision 976)
@@ -169,4 +169,5 @@
         }
         _Path& p;
+        PathDumperConstraints() {}
       };
 
@@ -194,4 +195,5 @@
         }
         _Path& p;
+        PathDumperConstraints() {}
       };
 
Index: mon/config.h.cmake
===================================================================
--- lemon/config.h.cmake	(revision 678)
+++ 	(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 678)
+++ lemon/config.h.in	(revision 981)
@@ -1,26 +1,10 @@
-/* The version string */
-#undef LEMON_VERSION
-
-/* Define to 1 if you have long long */
-#undef LEMON_HAVE_LONG_LONG
-
-/* Define to 1 if you have any LP solver. */
-#undef LEMON_HAVE_LP
-
-/* Define to 1 if you have any MIP solver. */
-#undef LEMON_HAVE_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
+#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
+#cmakedefine LEMON_USE_PTHREAD 1
+#cmakedefine LEMON_USE_WIN32_THREADS 1
Index: lemon/core.h
===================================================================
--- lemon/core.h	(revision 893)
+++ lemon/core.h	(revision 1027)
@@ -149,4 +149,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.
   ///
@@ -200,4 +243,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:
 
@@ -441,12 +552,50 @@
       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);
+      }
+    };
+
   }
 
-  /// Check whether a graph is undirected.
+  /// \brief Check whether a graph is undirected.
   ///
   /// This function returns \c true if the given graph is undirected.
@@ -990,4 +1139,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);
   }
 
@@ -1258,5 +1855,5 @@
     /// The Digraph type
     typedef GR Digraph;
-
+    
   protected:
 
@@ -1869,19 +2466,30 @@
     ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough.
     ///
-#ifdef DOXYGEN
-    Arc operator()(Node s, Node t, Arc prev=INVALID) const {}
-#else
-    using ArcLookUp<GR>::operator() ;
-    Arc operator()(Node s, Node t, Arc prev) const
+    Arc operator()(Node s, Node t, Arc prev=INVALID) const
     {
-      return prev==INVALID?(*this)(s,t):_next[prev];
-    }
+      if(prev==INVALID)
+        {
+          Arc f=INVALID;
+          Arc e;
+          for(e=_head[s];
+              e!=INVALID&&_g.target(e)!=t;
+              e = t < _g.target(e)?_left[e]:_right[e]) ;
+          while(e!=INVALID)
+            if(_g.target(e)==t)
+              {
+                f = e;
+                e = _left[e];
+              }
+            else e = _right[e];
+          return f;
+        }
+      else return _next[prev];
+    }
+
+  };
+
+  /// @}
+
+} //namespace lemon
+
 #endif
-
-  };
-
-  /// @}
-
-} //namespace lemon
-
-#endif
Index: lemon/cost_scaling.h
===================================================================
--- lemon/cost_scaling.h	(revision 877)
+++ lemon/cost_scaling.h	(revision 1003)
@@ -98,4 +98,8 @@
   /// "preflow push-relabel" algorithm for the maximum flow problem.
   ///
+  /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest
+  /// implementations available in LEMON for solving this problem.
+  /// (For more information, see \ref min_cost_flow_algs "the module page".)
+  ///
   /// Most of the parameters of the problem (except for the digraph)
   /// can be given using separate functions, and the algorithm can be
@@ -114,8 +118,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,
@@ -179,5 +184,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()
@@ -234,5 +239,4 @@
     };
 
-    typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
     typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
 
@@ -285,12 +289,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 +335,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() :
@@ -448,5 +443,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 +489,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 +503,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();
@@ -572,16 +568,23 @@
     }
 
-    /// \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 +611,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
@@ -706,5 +706,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 +731,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
@@ -887,12 +889,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 +896,11 @@
       _rank.resize(_res_node_num + 1);
 
-      // Execute the algorithm
+      return OPTIMAL;
+    }
+
+    // Execute the algorithm and transform the results
+    void start(Method method) {
+      const int MAX_PARTIAL_PATH_LENGTH = 4;
+
       switch (method) {
         case PUSH:
@@ -908,27 +908,68 @@
           break;
         case AUGMENT:
-          startAugment();
+          startAugment(_res_node_num - 1);
           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
@@ -948,11 +989,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 +1013,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 +1247,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 +1260,5 @@
       }
       if (total_excess == 0) return;
+      _buckets[0] = b0;
 
       // Search the buckets
@@ -1038,6 +1282,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 +1296,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;
                 }
@@ -1085,23 +1332,25 @@
 
     /// Execute the algorithm performing augment and relabel operations
-    void startAugment(int max_length = std::numeric_limits<int>::max()) {
+    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 +1369,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 +1416,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 +1426,5 @@
 
           // Augment along the found path (as much flow as possible)
+        augment:
           Value delta;
           int pa, u, v = start;
@@ -1168,4 +1433,5 @@
             u = v;
             v = _target[pa];
+            path_arc[pa] = false;
             delta = std::min(_res_cap[pa], _excess[u]);
             _res_cap[pa] -= delta;
@@ -1173,15 +1439,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 +1459,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 +1550,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 +1572,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 877)
+++ lemon/cplex.cc	(revision 1016)
@@ -41,4 +41,5 @@
     int status;
     _cnt = new int;
+    (*_cnt) = 1;
     _env = CPXopenCPLEX(&status);
     if (_env == 0) {
@@ -471,6 +472,4 @@
     int status;
     _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
-    rows.clear();
-    cols.clear();
   }
 
Index: lemon/cycle_canceling.h
===================================================================
--- lemon/cycle_canceling.h	(revision 877)
+++ lemon/cycle_canceling.h	(revision 1013)
@@ -36,4 +36,5 @@
 #include <lemon/bellman_ford.h>
 #include <lemon/howard_mmc.h>
+#include <lemon/hartmann_orlin_mmc.h>
 
 namespace lemon {
@@ -49,9 +50,10 @@
   /// \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.
+  /// 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, 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,13 +119,14 @@
     ///
     /// \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
@@ -130,11 +134,11 @@
       /// \ref goldberg89cyclecanceling. It improves along a
       /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
-      /// Its running time complexity is O(n<sup>2</sup>m<sup>3</sup>log(n)).
+      /// Its running time complexity is O(n<sup>2</sup>e<sup>3</sup>log(n)).
       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.
       /// 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 O(n<sup>2</sup>e<sup>2</sup>log(n)).
       CANCEL_AND_TIGHTEN
     };
@@ -350,5 +354,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.
     ///
@@ -611,5 +615,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 +640,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
@@ -923,17 +929,40 @@
     // 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
         Value delta = INF;
@@ -955,9 +984,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 +1168,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 907)
+++ lemon/dfs.h	(revision 1000)
@@ -1194,4 +1194,5 @@
       }
       _Visitor& visitor;
+      Constraints() {}
     };
   };
Index: lemon/euler.h
===================================================================
--- lemon/euler.h	(revision 877)
+++ lemon/euler.h	(revision 919)
@@ -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/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 877)
+++ lemon/full_graph.h	(revision 1025)
@@ -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 877)
+++ lemon/glpk.cc	(revision 989)
@@ -557,6 +557,4 @@
   void GlpkBase::_clear() {
     glp_erase_prob(lp);
-    rows.clear();
-    cols.clear();
   }
 
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 877)
+++ lemon/graph_to_eps.h	(revision 998)
@@ -223,5 +223,5 @@
   using T::_copyright;
 
-  using T::NodeTextColorType;
+  using typename T::NodeTextColorType;
   using T::CUST_COL;
   using T::DIST_COL;
Index: lemon/grosso_locatelli_pullan_mc.h
===================================================================
--- lemon/grosso_locatelli_pullan_mc.h	(revision 904)
+++ lemon/grosso_locatelli_pullan_mc.h	(revision 918)
@@ -47,6 +47,10 @@
   ///
   /// This class provides a simple but highly efficient and robust heuristic
-  /// method that quickly finds a large clique, but not necessarily the
+  /// 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.
@@ -85,4 +89,20 @@
     };
 
+    /// \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:
 
@@ -94,4 +114,5 @@
     // Note: vector<char> is used instead of vector<bool> for efficiency reasons
 
+    // The underlying graph
     const GR &_graph;
     IntNodeMap _id;
@@ -100,4 +121,13 @@
     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
@@ -381,5 +411,7 @@
     GrossoLocatelliPullanMc(const GR& graph) :
       _graph(graph), _id(_graph), _rnd(rnd)
-    {}
+    {
+      initOptions();
+    }
 
     /// \brief Constructor with random seed.
@@ -392,5 +424,7 @@
     GrossoLocatelliPullanMc(const GR& graph, int seed) :
       _graph(graph), _id(_graph), _rnd(seed)
-    {}
+    {
+      initOptions();
+    }
 
     /// \brief Constructor with random number generator.
@@ -403,36 +437,145 @@
     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 Runs the algorithm.
-    ///
-    /// This function runs the algorithm.
-    ///
-    /// \param step_num The maximum number of node selections (steps)
-    /// during the search process.
-    /// This parameter controls the running time and the success of the
-    /// algorithm. For larger values, the algorithm runs slower but it more
+    
+    /// \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 size of the found clique.
-    int run(int step_num = 100000,
-            SelectionRule rule = PENALTY_BASED)
+    /// \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>(step_num);
+          return start<RandomSelectionRule>();
         case DEGREE_BASED:
-          return start<DegreeBasedSelectionRule>(step_num);
-        case PENALTY_BASED:
-          return start<PenaltyBasedSelectionRule>(step_num);
-      }
-      return 0; // avoid warning
+          return start<DegreeBasedSelectionRule>();
+        default:
+          return start<PenaltyBasedSelectionRule>();
+      }
     }
 
@@ -440,4 +583,7 @@
 
     /// \name Query Functions
+    /// The results of the algorithm can be obtained using these functions.\n
+    /// The run() function must be called before using them. 
+
     /// @{
 
@@ -531,4 +677,16 @@
 
   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
@@ -587,28 +745,30 @@
     // Executes the algorithm
     template <typename SelectionRuleImpl>
-    int start(int max_select) {
-      // Options for the restart rule
-      const bool delta_based_restart = true;
-      const int restart_delta_limit = 4;
-
-      if (_n == 0) return 0;
+    TerminationCause start() {
+      if (_n == 0) return SIZE_LIMIT;
       if (_n == 1) {
         _best_clique[0] = true;
         _best_size = 1;
-        return _best_size;
-      }
-
-      // Iterated local search
+        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;
+      int select = 0, restart = 0;
       IntVector restart_nodes;
-
-      while (select < max_select) {
+      while (select < max_select && restart < max_restart) {
 
         // Perturbation/restart
-        if (delta_based_restart) {
+        restart++;
+        if (_delta_based_restart) {
           restart_nodes.clear();
           for (int i = 0; i != _n; i++) {
-            if (_delta[i] >= restart_delta_limit)
+            if (_delta[i] >= _restart_delta_limit)
               restart_nodes.push_back(i);
           }
@@ -664,10 +824,10 @@
           _best_clique = _clique;
           _best_size = _size;
-          if (_best_size == _n) return _best_size;
+          if (_best_size >= max_size) return SIZE_LIMIT;
         }
         sel_method.update();
       }
 
-      return _best_size;
+      return (restart >= max_restart ? ITERATION_LIMIT : STEP_LIMIT);
     }
 
Index: lemon/hartmann_orlin_mmc.h
===================================================================
--- lemon/hartmann_orlin_mmc.h	(revision 879)
+++ lemon/hartmann_orlin_mmc.h	(revision 1002)
@@ -99,5 +99,5 @@
   /// This class implements the Hartmann-Orlin algorithm for finding
   /// a directed cycle of minimum mean cost in a digraph
-  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// \ref hartmann93finding, \ref dasdan98minmeancycle.
   /// It is an improved version of \ref KarpMmc "Karp"'s original algorithm,
   /// it applies an efficient early termination scheme.
Index: lemon/howard_mmc.h
===================================================================
--- lemon/howard_mmc.h	(revision 877)
+++ lemon/howard_mmc.h	(revision 1012)
@@ -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.
+  /// \ref dasdan98minmeancycle, \ref dasdan04experimental.
   /// This class provides the most efficient algorithm for the
   /// minimum mean cycle problem, though the best known theoretical
@@ -150,4 +150,21 @@
     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:
 
@@ -325,11 +342,25 @@
     }
 
-    /// \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 +368,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 +390,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/karp_mmc.h
===================================================================
--- lemon/karp_mmc.h	(revision 877)
+++ lemon/karp_mmc.h	(revision 1002)
@@ -99,5 +99,5 @@
   /// This class implements Karp's algorithm for finding a directed
   /// cycle of minimum mean cost in a digraph
-  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// \ref karp78characterization, \ref dasdan98minmeancycle.
   /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
   ///
Index: lemon/kruskal.h
===================================================================
--- lemon/kruskal.h	(revision 584)
+++ lemon/kruskal.h	(revision 921)
@@ -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 908)
+++ 	(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 658)
+++ lemon/lemon.pc.in	(revision 981)
@@ -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 877)
+++ lemon/lgf_reader.h	(revision 1030)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2010
+ * Copyright (C) 2003-2011
  * 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());
+          }
+        }
       }
     };
@@ -965,4 +998,11 @@
         int index = 0;
         while (_reader_bits::readToken(line, map)) {
+          if(map == "-") {
+              if(index!=0)
+                throw FormatError("'-' is not allowed as a map name");
+              else if (line >> std::ws >> c)
+                throw FormatError("Extra character at the end of line");
+              else break;
+            }
           if (maps.find(map) != maps.end()) {
             std::ostringstream msg;
@@ -1835,4 +1875,11 @@
         int index = 0;
         while (_reader_bits::readToken(line, map)) {
+          if(map == "-") {
+              if(index!=0)
+                throw FormatError("'-' is not allowed as a map name");
+              else if (line >> std::ws >> c)
+                throw FormatError("Extra character at the end of line");
+              else break;
+            }
           if (maps.find(map) != maps.end()) {
             std::ostringstream msg;
@@ -2115,4 +2162,1070 @@
   }
 
+  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 BpGraphReader class
+  ///
+  /// This function just returns a \ref 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 BpGraphReader
+  /// class documentation.
+  /// \warning Don't forget to put the \ref BpGraphReader::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, const std::string& fn)
+  /// \sa bpGraphReader(TBGR& graph, const char* fn)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) {
+    BpGraphReader<TBGR> tmp(graph, is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphReader class
+  ///
+  /// This function just returns a \ref BpGraphReader class.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, std::istream& is)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) {
+    BpGraphReader<TBGR> tmp(graph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref BpGraphReader class
+  ///
+  /// This function just returns a \ref BpGraphReader class.
+  /// \relates BpGraphReader
+  /// \sa bpGraphReader(TBGR& graph, std::istream& is)
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) {
+    BpGraphReader<TBGR> tmp(graph, fn);
+    return tmp;
+  }
+
   class SectionReader;
 
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 877)
+++ lemon/lgf_writer.h	(revision 1030)
@@ -186,5 +186,5 @@
       ValueStorage(const Value& value, const Converter& converter = Converter())
         : _value(value), _converter(converter) {}
-
+      
       virtual std::string get() {
         return _converter(_value);
@@ -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");
+          }
+        }
       }
     };
@@ -987,5 +1016,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 +1072,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 +1080,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 +1093,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 +1319,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;
@@ -1606,4 +1635,822 @@
   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 BpGraphWriter class
+  ///
+  /// This function just returns a \ref 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 BpGraphWriter
+  /// class documentation.
+  /// \warning Don't forget to put the \ref 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 877)
+++ lemon/list_graph.h	(revision 1025)
@@ -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_base.h
===================================================================
--- lemon/lp_base.h	(revision 877)
+++ lemon/lp_base.h	(revision 989)
@@ -1557,5 +1557,5 @@
 
     ///Clears the problem
-    void clear() { _clear(); }
+    void clear() { _clear(); rows.clear(); cols.clear(); }
 
     /// Sets the message level of the solver
@@ -1619,5 +1619,5 @@
   inline LpBase::Constr operator<=(const LpBase::Expr &e,
                                    const LpBase::Expr &f) {
-    return LpBase::Constr(0, f - e, LpBase::INF);
+    return LpBase::Constr(0, f - e, LpBase::NaN);
   }
 
@@ -1637,5 +1637,5 @@
   inline LpBase::Constr operator<=(const LpBase::Expr &e,
                                    const LpBase::Value &f) {
-    return LpBase::Constr(- LpBase::INF, e, f);
+    return LpBase::Constr(LpBase::NaN, e, f);
   }
 
@@ -1646,5 +1646,5 @@
   inline LpBase::Constr operator>=(const LpBase::Expr &e,
                                    const LpBase::Expr &f) {
-    return LpBase::Constr(0, e - f, LpBase::INF);
+    return LpBase::Constr(0, e - f, LpBase::NaN);
   }
 
@@ -1666,5 +1666,5 @@
   inline LpBase::Constr operator>=(const LpBase::Expr &e,
                                    const LpBase::Value &f) {
-    return LpBase::Constr(f, e, LpBase::INF);
+    return LpBase::Constr(f, e, LpBase::NaN);
   }
 
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 877)
+++ lemon/maps.h	(revision 942)
@@ -3253,5 +3253,5 @@
     virtual void add(const Key& key) {
       Parent::add(key);
-      unlace(key);
+      lace(key);
     }
 
Index: lemon/max_cardinality_search.h
===================================================================
--- lemon/max_cardinality_search.h	(revision 916)
+++ lemon/max_cardinality_search.h	(revision 977)
@@ -403,15 +403,22 @@
     ///\param digraph the digraph the algorithm will run on.
     ///\param capacity the capacity map used by the algorithm.
-    ///When no capacity map given, a constant 1 capacity map will
-    ///be allocated.
-#ifdef DOXYGEN
     MaxCardinalitySearch(const Digraph& digraph,
-			 const CapacityMap& capacity=0 ) :
-#else
-    MaxCardinalitySearch(const Digraph& digraph,
-			 const CapacityMap& capacity=*static_cast<const CapacityMap*>(0) ) :
-#endif
+			 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),
Index: lemon/nagamochi_ibaraki.h
===================================================================
--- lemon/nagamochi_ibaraki.h	(revision 913)
+++ lemon/nagamochi_ibaraki.h	(revision 978)
@@ -301,5 +301,10 @@
     }
 
-  public :
+  protected:
+    //This is here to avoid a gcc-3.3 compilation error.
+    //It should never be called.
+    NagamochiIbaraki() {} 
+    
+  public:
 
     typedef NagamochiIbaraki Create;
Index: lemon/network_simplex.h
===================================================================
--- lemon/network_simplex.h	(revision 896)
+++ lemon/network_simplex.h	(revision 1004)
@@ -48,8 +48,9 @@
   /// 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
@@ -168,5 +173,5 @@
     typedef std::vector<Cost> CostVector;
     typedef std::vector<signed char> CharVector;
-    // Note: vector<signed char> is used instead of vector<ArcState> and 
+    // Note: vector<signed char> is used instead of vector<ArcState> and
     // vector<ArcDirection> for efficiency reasons
 
@@ -538,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];
         }
       };
@@ -556,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;
 
@@ -600,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;
           }
@@ -615,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;
       }
@@ -735,4 +740,6 @@
     ///
     /// \return <tt>(*this)</tt>
+    ///
+    /// \sa supplyType()
     template<typename SupplyMap>
     NetworkSimplex& supplyMap(const SupplyMap& map) {
@@ -751,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.
     ///
@@ -1004,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
@@ -1028,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
Index: lemon/path.h
===================================================================
--- lemon/path.h	(revision 877)
+++ lemon/path.h	(revision 1000)
@@ -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.
@@ -65,4 +65,10 @@
     Path() {}
 
+    /// \brief Copy constructor
+    ///
+    Path(const Path& cpath) {
+      pathCopy(cpath, *this);
+    }
+
     /// \brief Template copy constructor
     ///
@@ -72,4 +78,11 @@
     Path(const CPath& cpath) {
       pathCopy(cpath, *this);
+    }
+
+    /// \brief Copy assignment
+    ///
+    Path& operator=(const Path& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
     }
 
@@ -136,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.
@@ -144,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.
@@ -232,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.
@@ -253,4 +266,10 @@
     SimplePath() {}
 
+    /// \brief Copy constructor
+    ///
+    SimplePath(const SimplePath& cpath) {
+      pathCopy(cpath, *this);
+    }
+
     /// \brief Template copy constructor
     ///
@@ -260,4 +279,11 @@
     SimplePath(const CPath& cpath) {
       pathCopy(cpath, *this);
+    }
+
+    /// \brief Copy assignment
+    ///
+    SimplePath& operator=(const SimplePath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
     }
 
@@ -328,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.
@@ -335,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);
@@ -396,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.
@@ -432,4 +458,10 @@
     ListPath() : first(0), last(0) {}
 
+    /// \brief Copy constructor
+    ///
+    ListPath(const ListPath& cpath) : first(0), last(0) {
+      pathCopy(cpath, *this);
+    }
+
     /// \brief Template copy constructor
     ///
@@ -446,4 +478,11 @@
     ~ListPath() {
       clear();
+    }
+
+    /// \brief Copy assignment
+    ///
+    ListPath& operator=(const ListPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
     }
 
@@ -505,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 {
@@ -517,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;
@@ -736,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.
@@ -759,4 +798,10 @@
     StaticPath() : len(0), arcs(0) {}
 
+    /// \brief Copy constructor
+    ///
+    StaticPath(const StaticPath& cpath) : arcs(0) {
+      pathCopy(cpath, *this);
+    }
+
     /// \brief Template copy constructor
     ///
@@ -772,4 +817,11 @@
     ~StaticPath() {
       if (arcs) delete[] arcs;
+    }
+
+    /// \brief Copy assignment
+    ///
+    StaticPath& operator=(const StaticPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
     }
 
@@ -832,5 +884,5 @@
     };
 
-    /// \brief The nth arc.
+    /// \brief The n-th arc.
     ///
     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
@@ -839,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);
@@ -1043,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 877)
+++ lemon/planarity.h	(revision 999)
@@ -73,5 +73,4 @@
 
       void discover(const Arc& arc) {
-        Node source = _graph.source(arc);
         Node target = _graph.target(arc);
 
Index: lemon/preflow.h
===================================================================
--- lemon/preflow.h	(revision 892)
+++ lemon/preflow.h	(revision 966)
@@ -544,7 +544,4 @@
           _flow->set(e, (*_capacity)[e]);
           (*_excess)[u] += rem;
-          if (u != _target && !_level->active(u)) {
-            _level->activate(u);
-          }
         }
       }
@@ -556,9 +553,10 @@
           _flow->set(e, 0);
           (*_excess)[v] += rem;
-          if (v != _target && !_level->active(v)) {
-            _level->activate(v);
-          }
-        }
-      }
+        }
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) 
+        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
+          _level->activate(n);
+          
       return true;
     }
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 877)
+++ lemon/smart_graph.h	(revision 1025)
@@ -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: lx_check_coin.m4
===================================================================
--- m4/lx_check_coin.m4	(revision 749)
+++ 	(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 627)
+++ 	(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 627)
+++ 	(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 627)
+++ 	(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 793)
+++ 	(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/bootstrap.sh
===================================================================
--- scripts/bootstrap.sh	(revision 850)
+++ 	(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 733)
+++ 	(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 733)
+++ 	(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 1035)
+++ test/CMakeLists.txt	(revision 1038)
@@ -8,8 +8,14 @@
 )
 
+SET(TEST_WITH_VALGRIND "NO" CACHE STRING
+  "Run the test with valgrind (YES/NO).")
+SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.")
+
 SET(TESTS
   adaptors_test
+  arc_look_up_test
   bellman_ford_test
   bfs_test
+  bpgraph_test
   circulation_test
   connectivity_test
@@ -30,4 +36,6 @@
   heap_test
   kruskal_test
+  lgf_reader_writer_test
+  lgf_test
   maps_test
   matching_test
@@ -70,4 +78,5 @@
   TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
   ADD_TEST(lp_test lp_test)
+  ADD_DEPENDENCIES(check lp_test)
 
   IF(WIN32 AND LEMON_HAVE_GLPK)
@@ -85,5 +94,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}/cplex91.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
     )
   ENDIF()
@@ -111,4 +120,5 @@
   TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
   ADD_TEST(mip_test mip_test)
+  ADD_DEPENDENCIES(check mip_test)
 
   IF(WIN32 AND LEMON_HAVE_GLPK)
@@ -126,5 +136,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}/cplex91.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
     )
   ENDIF()
@@ -138,5 +148,11 @@
   ENDIF()
   TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
-  ADD_TEST(${TEST_NAME} ${TEST_NAME})
+    IF(TEST_WITH_VALGRIND)
+      ADD_TEST(${TEST_NAME}
+        valgrind --error-exitcode=1 ${VALGRIND_FLAGS}
+        ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} )
+    ELSE()
+      ADD_TEST(${TEST_NAME} ${TEST_NAME})
+    ENDIF()
   ADD_DEPENDENCIES(check ${TEST_NAME})
 ENDFOREACH()
Index: st/Makefile.am
===================================================================
--- test/Makefile.am	(revision 1035)
+++ 	(revision )
@@ -1,107 +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/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/maps_test \
-	test/matching_test \
-	test/max_cardinality_search_test \
-	test/max_clique_test \
-	test/min_cost_arborescence_test \
-	test/min_cost_flow_test \
-	test/min_mean_cycle_test \
-	test/nagamochi_ibaraki_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/tsp_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_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_heap_test_SOURCES = test/heap_test.cc
-test_kruskal_test_SOURCES = test/kruskal_test.cc
-test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
-test_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_max_cardinality_search_test_SOURCES = test/max_cardinality_search_test.cc
-test_max_clique_test_SOURCES = test/max_clique_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_nagamochi_ibaraki_test_SOURCES = test/nagamochi_ibaraki_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_tsp_test_SOURCES = test/tsp_test.cc
-test_unionfind_test_SOURCES = test/unionfind_test.cc
Index: test/adaptors_test.cc
===================================================================
--- test/adaptors_test.cc	(revision 515)
+++ test/adaptors_test.cc	(revision 998)
@@ -66,4 +66,5 @@
   Digraph::Arc a2 = digraph.addArc(n1, n3);
   Digraph::Arc a3 = digraph.addArc(n2, n3);
+  ignore_unused_variable_warning(a3);
 
   // Check the adaptor
@@ -100,4 +101,5 @@
   Adaptor::Arc a7 = adaptor.addArc(n1, n4);
   Adaptor::Arc a8 = adaptor.addArc(n1, n2);
+  ignore_unused_variable_warning(a6,a7,a8);
 
   adaptor.erase(a1);
@@ -759,4 +761,5 @@
   Digraph::Arc a2 = digraph.addArc(n1, n3);
   Digraph::Arc a3 = digraph.addArc(n2, n3);
+  ignore_unused_variable_warning(a1,a2,a3);
 
   checkGraphNodeList(adaptor, 6);
@@ -1378,11 +1381,13 @@
 
   // Apply several adaptors on the grid graph
-  typedef SplitNodes<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > >
-    SplitGridGraph;
+  typedef Orienter< const GridGraph, GridGraph::EdgeMap<bool> >
+    OrientedGridGraph;
+  typedef SplitNodes<OrientedGridGraph> SplitGridGraph;
   typedef Undirector<const SplitGridGraph> USplitGridGraph;
   checkConcept<concepts::Digraph, SplitGridGraph>();
   checkConcept<concepts::Graph, USplitGridGraph>();
 
-  SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map));
+  OrientedGridGraph oadaptor = orienter(graph, dir_map);
+  SplitGridGraph adaptor = splitNodes(oadaptor);
   USplitGridGraph uadaptor = undirector(adaptor);
 
Index: test/arc_look_up_test.cc
===================================================================
--- test/arc_look_up_test.cc	(revision 993)
+++ test/arc_look_up_test.cc	(revision 993)
@@ -0,0 +1,85 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include "lemon/list_graph.h"
+#include "lemon/lgf_reader.h"
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+const int lgfn = 4;
+const std::string lgf =
+  "@nodes\n"
+"label\n"
+"0\n"
+"1\n"
+"2\n"
+"3\n"
+"4\n"
+"5\n"
+"6\n"
+"@arcs\n"
+"label\n"
+"5 6 0\n"
+"5 4 1\n"
+"4 6 2\n"
+"3 4 3\n"
+"3 4 4\n"
+"3 2 5\n"
+"3 5 6\n"
+"3 5 7\n"
+"3 5 8\n"
+"3 5 9\n"
+"2 4 10\n"
+"2 4 11\n"
+"2 4 12\n"
+"2 4 13\n"
+"1 2 14\n"
+"1 2 15\n"
+"1 0 16\n"
+"1 3 17\n"
+"1 3 18\n"
+"1 3 19\n"
+"1 3 20\n"
+"0 2 21\n"
+"0 2 22\n"
+"0 2 23\n"
+"0 2 24\n";
+
+
+int main() {
+  ListDigraph graph;
+  std::istringstream lgfs(lgf);
+  DigraphReader<ListDigraph>(graph, lgfs).run();
+  
+  AllArcLookUp<ListDigraph> lookup(graph);
+	
+  int numArcs = countArcs(graph);
+	
+  int arcCnt = 0;
+  for(ListDigraph::NodeIt n1(graph); n1 != INVALID; ++n1)
+    for(ListDigraph::NodeIt n2(graph); n2 != INVALID; ++n2)
+      for(ListDigraph::Arc a = lookup(n1, n2); a != INVALID;
+	  a = lookup(n1, n2, a))
+	++arcCnt;
+  check(arcCnt==numArcs, "Wrong total number of arcs");
+
+  return 0;
+}
Index: test/bellman_ford_test.cc
===================================================================
--- test/bellman_ford_test.cc	(revision 880)
+++ test/bellman_ford_test.cc	(revision 1009)
@@ -66,6 +66,8 @@
   Arc e;
   Value l;
+  ignore_unused_variable_warning(l);
   int k=3;
   bool b;
+  ignore_unused_variable_warning(b);
   BF::DistMap d(gr);
   BF::PredMap p(gr);
@@ -148,4 +150,6 @@
   Digraph g;
   bool b;
+  ignore_unused_variable_warning(b);
+
   bellmanFord(g,LengthMap()).run(Node());
   b = bellmanFord(g,LengthMap()).run(Node(),Node());
@@ -191,5 +195,5 @@
 
   ListPath<Digraph> path;
-  Value dist;
+  Value dist = 0;
   bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
 
Index: test/bfs_test.cc
===================================================================
--- test/bfs_test.cc	(revision 877)
+++ test/bfs_test.cc	(revision 1008)
@@ -62,4 +62,5 @@
   Arc e;
   int l, i;
+  ignore_unused_variable_warning(l,i);
   bool b;
   BType::DistMap d(G);
@@ -151,4 +152,6 @@
   Digraph g;
   bool b;
+  ignore_unused_variable_warning(b);
+
   bfs(g).run(Node());
   b=bfs(g).run(Node(),Node());
Index: test/bpgraph_test.cc
===================================================================
--- test/bpgraph_test.cc	(revision 1026)
+++ test/bpgraph_test.cc	(revision 1026)
@@ -0,0 +1,451 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/concepts/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);
+
+  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);
+
+  // 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);
+
+  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);
+
+  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);
+
+  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 877)
+++ test/circulation_test.cc	(revision 1008)
@@ -74,4 +74,5 @@
   VType v;
   bool b;
+  ignore_unused_variable_warning(v,b);
 
   typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
Index: test/connectivity_test.cc
===================================================================
--- test/connectivity_test.cc	(revision 877)
+++ test/connectivity_test.cc	(revision 998)
@@ -69,4 +69,5 @@
     Graph g(d);
     Digraph::Node n = d.addNode();
+    ignore_unused_variable_warning(n);
 
     check(stronglyConnected(d), "This digraph is strongly connected");
@@ -246,4 +247,5 @@
     Digraph::Node watch = d.addNode();
     Digraph::Node pants = d.addNode();
+    ignore_unused_variable_warning(watch);
 
     d.addArc(socks, shoe);
Index: test/dfs_test.cc
===================================================================
--- test/dfs_test.cc	(revision 907)
+++ test/dfs_test.cc	(revision 1010)
@@ -68,4 +68,6 @@
   int l, i;
   bool b;
+  ignore_unused_variable_warning(l,i,b);
+
   DType::DistMap d(G);
   DType::PredMap p(G);
@@ -152,4 +154,6 @@
   Digraph g;
   bool b;
+  ignore_unused_variable_warning(b);
+
   dfs(g).run(Node());
   b=dfs(g).run(Node(),Node());
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 877)
+++ test/digraph_test.cc	(revision 999)
@@ -65,4 +65,5 @@
       a3 = G.addArc(n2, n3),
       a4 = G.addArc(n2, n3);
+  ignore_unused_variable_warning(a2,a3,a4);
 
   checkGraphNodeList(G, 3);
@@ -93,4 +94,5 @@
   Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
       a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+  ignore_unused_variable_warning(a1,a2,a3,a4);
 
   Node n4 = G.split(n2);
@@ -126,4 +128,5 @@
       a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
       a5 = G.addArc(n2, n4);
+  ignore_unused_variable_warning(a1,a2,a3,a5);
 
   checkGraphNodeList(G, 4);
@@ -205,4 +208,5 @@
       a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
       a5 = G.addArc(n2, n4);
+  ignore_unused_variable_warning(a2,a3,a4,a5);
 
   // Check arc deletion
@@ -252,4 +256,5 @@
   Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
       a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+  ignore_unused_variable_warning(a1,a2,a3,a4);
 
   typename Digraph::Snapshot snapshot(G);
@@ -352,4 +357,5 @@
     e1 = g.addArc(n1, n2),
     e2 = g.addArc(n2, n3);
+  ignore_unused_variable_warning(e2);
 
   check(g.valid(n1), "Wrong validity check");
@@ -437,4 +443,5 @@
     a3 = g.addArc(n2, n3),
     a4 = g.addArc(n2, n3);
+  ignore_unused_variable_warning(a2,a3,a4);
 
   digraphCopy(g, G).nodeRef(nref).run();
Index: test/dijkstra_test.cc
===================================================================
--- test/dijkstra_test.cc	(revision 877)
+++ test/dijkstra_test.cc	(revision 1008)
@@ -66,4 +66,6 @@
   int i;
   bool b;
+  ignore_unused_variable_warning(l,i,b);
+
   DType::DistMap d(G);
   DType::PredMap p(G);
@@ -163,4 +165,6 @@
   Digraph g;
   bool b;
+  ignore_unused_variable_warning(b);
+
   dijkstra(g,LengthMap()).run(Node());
   b=dijkstra(g,LengthMap()).run(Node(),Node());
Index: test/edge_set_test.cc
===================================================================
--- test/edge_set_test.cc	(revision 877)
+++ test/edge_set_test.cc	(revision 998)
@@ -45,8 +45,10 @@
 
   Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ignore_unused_variable_warning(ga1);
 
   ArcSet arc_set(digraph);
 
   Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ignore_unused_variable_warning(ga2);
 
   checkGraphNodeList(arc_set, 2);
@@ -76,4 +78,6 @@
     a3 = arc_set.addArc(n2, n3),
     a4 = arc_set.addArc(n2, n3);
+  ignore_unused_variable_warning(a2,a3,a4);
+
   checkGraphNodeList(arc_set, 3);
   checkGraphArcList(arc_set, 4);
@@ -111,8 +115,10 @@
 
   Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ignore_unused_variable_warning(ga1);
 
   ArcSet arc_set(digraph);
 
   Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ignore_unused_variable_warning(ga2);
 
   checkGraphNodeList(arc_set, 2);
@@ -142,4 +148,6 @@
     a3 = arc_set.addArc(n2, n3),
     a4 = arc_set.addArc(n2, n3);
+  ignore_unused_variable_warning(a2,a3,a4);
+
   checkGraphNodeList(arc_set, 3);
   checkGraphArcList(arc_set, 4);
@@ -191,8 +199,10 @@
 
   Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ignore_unused_variable_warning(ga1);
 
   EdgeSet edge_set(digraph);
 
   Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ignore_unused_variable_warning(ga2);
 
   checkGraphNodeList(edge_set, 2);
@@ -231,4 +241,6 @@
     e3 = edge_set.addEdge(n2, n3),
     e4 = edge_set.addEdge(n2, n3);
+  ignore_unused_variable_warning(e2,e3,e4);
+
   checkGraphNodeList(edge_set, 3);
   checkGraphEdgeList(edge_set, 4);
@@ -275,8 +287,10 @@
 
   Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ignore_unused_variable_warning(ga1);
 
   EdgeSet edge_set(digraph);
 
   Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ignore_unused_variable_warning(ga2);
 
   checkGraphNodeList(edge_set, 2);
@@ -315,4 +329,6 @@
     e3 = edge_set.addEdge(n2, n3),
     e4 = edge_set.addEdge(n2, n3);
+  ignore_unused_variable_warning(e2,e3,e4);
+
   checkGraphNodeList(edge_set, 3);
   checkGraphEdgeList(edge_set, 4);
Index: test/euler_test.cc
===================================================================
--- test/euler_test.cc	(revision 877)
+++ test/euler_test.cc	(revision 998)
@@ -102,5 +102,6 @@
     Graph g(d);
     Digraph::Node n = d.addNode();
-
+    ignore_unused_variable_warning(n);
+  
     checkDiEulerIt(d);
     checkDiEulerIt(g);
@@ -190,4 +191,5 @@
     Digraph::Node n4 = d.addNode();
     Digraph::Node n5 = d.addNode();
+    ignore_unused_variable_warning(n0,n4,n5);
 
     d.addArc(n1, n2);
Index: test/fractional_matching_test.cc
===================================================================
--- test/fractional_matching_test.cc	(revision 877)
+++ test/fractional_matching_test.cc	(revision 999)
@@ -343,4 +343,5 @@
       pv += weight[mwfm.matching(n)];
       SmartGraph::Node o = graph.target(mwfm.matching(n));
+      ignore_unused_variable_warning(o);
     } else {
       check(mwfm.nodeValue(n) == 0, "Invalid matching");
@@ -407,4 +408,5 @@
     pv += weight[mwpfm.matching(n)];
     SmartGraph::Node o = graph.target(mwpfm.matching(n));
+    ignore_unused_variable_warning(o);
   }
 
Index: test/gomory_hu_test.cc
===================================================================
--- test/gomory_hu_test.cc	(revision 877)
+++ test/gomory_hu_test.cc	(revision 1008)
@@ -69,4 +69,5 @@
   Value v;
   int d;
+  ignore_unused_variable_warning(v,d);
 
   GomoryHu<Graph, CapMap> gh_test(g, cap);
Index: test/graph_copy_test.cc
===================================================================
--- test/graph_copy_test.cc	(revision 894)
+++ test/graph_copy_test.cc	(revision 1026)
@@ -210,4 +210,169 @@
 }
 
+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() {
@@ -217,4 +382,6 @@
   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 877)
+++ test/graph_test.cc	(revision 998)
@@ -67,4 +67,5 @@
   Edge e2 = G.addEdge(n2, n1),
        e3 = G.addEdge(n2, n3);
+  ignore_unused_variable_warning(e2,e3);
 
   checkGraphNodeList(G, 3);
@@ -99,4 +100,5 @@
        e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
        e5 = G.addEdge(n4, n3);
+  ignore_unused_variable_warning(e1,e3,e4,e5);
 
   checkGraphNodeList(G, 4);
@@ -178,4 +180,5 @@
        e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
        e5 = G.addEdge(n4, n3);
+  ignore_unused_variable_warning(e1,e3,e4,e5);
 
   // Check edge deletion
@@ -218,4 +221,5 @@
   Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
        e3 = G.addEdge(n2, n3);
+  ignore_unused_variable_warning(e1,e2,e3);
 
   checkGraphNodeList(G, 3);
@@ -382,4 +386,5 @@
     e1 = g.addEdge(n1, n2),
     e2 = g.addEdge(n2, n3);
+  ignore_unused_variable_warning(e2);
 
   check(g.valid(n1), "Wrong validity check");
@@ -520,4 +525,5 @@
 
   Node n = G.nodeFromId(dim);
+  ignore_unused_variable_warning(n);
 
   for (NodeIt n(G); n != INVALID; ++n) {
Index: test/graph_test.h
===================================================================
--- test/graph_test.h	(revision 440)
+++ test/graph_test.h	(revision 1027)
@@ -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 877)
+++ test/hao_orlin_test.cc	(revision 1008)
@@ -67,4 +67,5 @@
   CutMap cut;
   Value v;
+  ignore_unused_variable_warning(v);
 
   HaoOrlin<Digraph, CapMap> ho_test(g, cap);
Index: test/heap_test.cc
===================================================================
--- test/heap_test.cc	(revision 855)
+++ test/heap_test.cc	(revision 948)
@@ -273,4 +273,38 @@
   }
 
+  {
+    typedef FibHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  {
+    typedef RadixHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef RadixHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  {
+    typedef BucketHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BucketHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+
   return 0;
 }
Index: test/lgf_reader_writer_test.cc
===================================================================
--- test/lgf_reader_writer_test.cc	(revision 1030)
+++ test/lgf_reader_writer_test.cc	(revision 1030)
@@ -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-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <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 954)
+++ test/lgf_test.cc	(revision 954)
@@ -0,0 +1,169 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     label\n"
+  "0 1  0\n"
+  "1 0  1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 1\n";
+
+char test_lgf_nomap[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     -\n"
+  "0 1\n";
+
+char test_lgf_bad1[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     - another\n"
+  "0 1\n";
+
+char test_lgf_bad2[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     label -\n"
+  "0 1\n";
+
+
+int main() 
+{
+  {
+    ListDigraph d; 
+    ListDigraph::Node s,t;
+    ListDigraph::ArcMap<int> label(d);
+    std::istringstream input(test_lgf);
+    digraphReader(d, input).
+      node("source", s).
+      node("target", t).
+      arcMap("label", label).
+      run();
+    check(countNodes(d) == 2,"There should be 2 nodes");
+    check(countArcs(d) == 2,"There should be 2 arcs");
+  }
+  {
+    ListGraph g;
+    ListGraph::Node s,t;
+    ListGraph::EdgeMap<int> label(g);
+    std::istringstream input(test_lgf);
+    graphReader(g, input).
+      node("source", s).
+      node("target", t).
+      edgeMap("label", label).
+      run();
+    check(countNodes(g) == 2,"There should be 2 nodes");
+    check(countEdges(g) == 2,"There should be 2 arcs");
+  }
+
+  {
+    ListDigraph d; 
+    std::istringstream input(test_lgf_nomap);
+    digraphReader(d, input).
+      run();
+    check(countNodes(d) == 2,"There should be 2 nodes");
+    check(countArcs(d) == 1,"There should be 1 arc");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_nomap);
+    graphReader(g, input).
+      run();
+    check(countNodes(g) == 2,"There should be 2 nodes");
+    check(countEdges(g) == 1,"There should be 1 edge");
+  }
+
+  {
+    ListDigraph d; 
+    std::istringstream input(test_lgf_bad1);
+    bool ok=false;
+    try {
+      digraphReader(d, input).
+        run();
+    }
+    catch (FormatError&) 
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_bad1);
+    bool ok=false;
+    try {
+      graphReader(g, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+
+  {
+    ListDigraph d; 
+    std::istringstream input(test_lgf_bad2);
+    bool ok=false;
+    try {
+      digraphReader(d, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_bad2);
+    bool ok=false;
+    try {
+      graphReader(g, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+}
Index: test/lp_test.cc
===================================================================
--- test/lp_test.cc	(revision 631)
+++ test/lp_test.cc	(revision 988)
@@ -42,8 +42,35 @@
 using namespace lemon;
 
+int countCols(LpBase & lp) {
+  int count=0;
+  for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
+  return count;
+}
+
+int countRows(LpBase & lp) {
+  int count=0;
+  for (LpBase::RowIt r(lp); r!=INVALID; ++r) ++count;
+  return count;
+}
+
+
 void lpTest(LpSolver& lp)
 {
 
   typedef LpSolver LP;
+
+  // Test LpBase::clear()
+  check(countRows(lp)==0, "Wrong number of rows");
+  check(countCols(lp)==0, "Wrong number of cols");
+  lp.addCol(); lp.addRow(); lp.addRow();
+  check(countRows(lp)==2, "Wrong number of rows");
+  check(countCols(lp)==1, "Wrong number of cols");
+  lp.clear();
+  check(countRows(lp)==0, "Wrong number of rows");
+  check(countCols(lp)==0, "Wrong number of cols");
+  lp.addCol(); lp.addCol(); lp.addCol(); lp.addRow();
+  check(countRows(lp)==1, "Wrong number of rows");
+  check(countCols(lp)==3, "Wrong number of cols");
+  lp.clear();
 
   std::vector<LP::Col> x(10);
@@ -166,4 +193,12 @@
     c = ((2 >= e) >= 3);
     c = ((2 >= p1) >= 3);
+
+    { //Tests for #430
+      LP::Col v=lp.addCol();
+      LP::Constr c = v >= -3;
+      c = c <= 4;
+      LP::Constr c2;
+      c2 = -3 <= v <= 4;
+    }
 
     e[x[3]]=2;
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 877)
+++ test/maps_test.cc	(revision 998)
@@ -104,4 +104,5 @@
     NullMap<A,B> map1;
     NullMap<A,B> map2 = map1;
+    ignore_unused_variable_warning(map2);
     map1 = nullMap<A,B>();
   }
@@ -114,4 +115,6 @@
     ConstMap<A,B> map2 = B();
     ConstMap<A,B> map3 = map1;
+    ignore_unused_variable_warning(map2,map3);
+
     map1 = constMap<A>(B());
     map1 = constMap<A,B>();
@@ -119,4 +122,6 @@
     ConstMap<A,C> map4(C(1));
     ConstMap<A,C> map5 = map4;
+    ignore_unused_variable_warning(map5);
+
     map4 = constMap<A>(C(2));
     map4.setAll(C(3));
@@ -139,4 +144,6 @@
     IdentityMap<A> map1;
     IdentityMap<A> map2 = map1;
+    ignore_unused_variable_warning(map2);
+
     map1 = identityMap<A>();
 
@@ -198,5 +205,7 @@
     checkConcept<ReadMap<B,double>, CompMap>();
     CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
+    ignore_unused_variable_warning(map1);
     CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
+    ignore_unused_variable_warning(map2);
 
     SparseMap<double, bool> m1(false); m1[3.14] = true;
@@ -211,5 +220,7 @@
     checkConcept<ReadMap<A,double>, CombMap>();
     CombMap map1 = CombMap(DoubleMap(), DoubleMap());
+    ignore_unused_variable_warning(map1);
     CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
+    ignore_unused_variable_warning(map2);
 
     check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
@@ -223,9 +234,13 @@
     FunctorToMap<F> map1;
     FunctorToMap<F> map2 = FunctorToMap<F>(F());
+    ignore_unused_variable_warning(map2);
+
     B b = functorToMap(F())[A()];
+    ignore_unused_variable_warning(b);
 
     checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
     MapToFunctor<ReadMap<A,B> > map =
       MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
+    ignore_unused_variable_warning(map);
 
     check(functorToMap(&func)[A()] == 3,
@@ -245,5 +260,8 @@
       ConvertMap<ReadMap<double, int>, double> >();
     ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
+    ignore_unused_variable_warning(map1);
     ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
+    ignore_unused_variable_warning(map2);
+
   }
 
@@ -642,4 +660,5 @@
     const int num = 10;
     Graph g;
+    Ibm map0(g, true);
     std::vector<Item> items;
     for (int i = 0; i < num; ++i) {
@@ -723,4 +742,5 @@
     const int num = 10;
     Graph g;
+    Iim map0(g, 0);
     std::vector<Item> items;
     for (int i = 0; i < num; ++i) {
@@ -773,4 +793,5 @@
     const int num = 10;
     Graph g;
+    Ivm map0(g, 0.0);
     std::vector<Item> items;
     for (int i = 0; i < num; ++i) {
Index: test/matching_test.cc
===================================================================
--- test/matching_test.cc	(revision 877)
+++ test/matching_test.cc	(revision 1008)
@@ -146,4 +146,5 @@
   MaxMatching<Graph>::Status stat =
     const_mat_test.status(n);
+  ignore_unused_variable_warning(stat);
   const MaxMatching<Graph>::StatusMap& smap =
     const_mat_test.statusMap();
Index: test/max_cardinality_search_test.cc
===================================================================
--- test/max_cardinality_search_test.cc	(revision 916)
+++ test/max_cardinality_search_test.cc	(revision 955)
@@ -118,5 +118,5 @@
    maxcard.start(x);
 
-   check(maxcard.processed(s) and !maxcard.processed(x) and
+   check(maxcard.processed(s) && !maxcard.processed(x) &&
          !maxcard.processed(y), "Wrong processed()!");
 
@@ -128,5 +128,5 @@
 
    maxcard.start();
-   check(maxcard.cardinality(x)==2 and maxcard.cardinality(y)>=4,
+   check(maxcard.cardinality(x)==2 && maxcard.cardinality(y)>=4,
          "Wrong cardinalities!");
  }
Index: test/max_clique_test.cc
===================================================================
--- test/max_clique_test.cc	(revision 904)
+++ test/max_clique_test.cc	(revision 918)
@@ -59,5 +59,5 @@
 // Check with general graphs
 template <typename Param>
-void checkMaxCliqueGeneral(int max_sel, Param rule) {
+void checkMaxCliqueGeneral(Param rule) {
   typedef ListGraph GR;
   typedef GrossoLocatelliPullanMc<GR> McAlg;
@@ -69,10 +69,11 @@
     GR::NodeMap<bool> map(g);
     McAlg mc(g);
-    check(mc.run(max_sel, rule) == 0, "Wrong clique size");
+    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(max_sel, rule) == 1, "Wrong clique size");
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
     check(mc.cliqueSize() == 1, "Wrong clique size");
     mc.cliqueMap(map);
@@ -83,5 +84,5 @@
     
     GR::Node v = g.addNode();
-    check(mc.run(max_sel, rule) == 1, "Wrong clique size");
+    check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
     check(mc.cliqueSize() == 1, "Wrong clique size");
     mc.cliqueMap(map);
@@ -91,5 +92,5 @@
 
     g.addEdge(u, v);
-    check(mc.run(max_sel, rule) == 2, "Wrong clique size");
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
     check(mc.cliqueSize() == 2, "Wrong clique size");
     mc.cliqueMap(map);
@@ -111,5 +112,6 @@
     
     McAlg mc(g);
-    check(mc.run(max_sel, rule) == 4, "Wrong clique size");
+    mc.iterationLimit(50);
+    check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
     check(mc.cliqueSize() == 4, "Wrong clique size");
     mc.cliqueMap(map);
@@ -128,5 +130,5 @@
 // Check with full graphs
 template <typename Param>
-void checkMaxCliqueFullGraph(int max_sel, Param rule) {
+void checkMaxCliqueFullGraph(Param rule) {
   typedef FullGraph GR;
   typedef GrossoLocatelliPullanMc<FullGraph> McAlg;
@@ -137,5 +139,5 @@
     GR::NodeMap<bool> map(g);
     McAlg mc(g);
-    check(mc.run(max_sel, rule) == size, "Wrong clique size");
+    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
     check(mc.cliqueSize() == size, "Wrong clique size");
     mc.cliqueMap(map);
@@ -151,9 +153,19 @@
 // Check with grid graphs
 template <typename Param>
-void checkMaxCliqueGridGraph(int max_sel, Param rule) {
+void checkMaxCliqueGridGraph(Param rule) {
   GridGraph g(5, 7);
   GridGraph::NodeMap<char> map(g);
   GrossoLocatelliPullanMc<GridGraph> mc(g);
-  check(mc.run(max_sel, rule) == 2, "Wrong clique size");
+  
+  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");
 }
@@ -161,15 +173,15 @@
 
 int main() {
-  checkMaxCliqueGeneral(50, GrossoLocatelliPullanMc<ListGraph>::RANDOM);
-  checkMaxCliqueGeneral(50, GrossoLocatelliPullanMc<ListGraph>::DEGREE_BASED);
-  checkMaxCliqueGeneral(50, GrossoLocatelliPullanMc<ListGraph>::PENALTY_BASED);
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::RANDOM);
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::DEGREE_BASED);
+  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::PENALTY_BASED);
 
-  checkMaxCliqueFullGraph(50, GrossoLocatelliPullanMc<FullGraph>::RANDOM);
-  checkMaxCliqueFullGraph(50, GrossoLocatelliPullanMc<FullGraph>::DEGREE_BASED);
-  checkMaxCliqueFullGraph(50, GrossoLocatelliPullanMc<FullGraph>::PENALTY_BASED);
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::RANDOM);
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::DEGREE_BASED);
+  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::PENALTY_BASED);
                        
-  checkMaxCliqueGridGraph(50, GrossoLocatelliPullanMc<GridGraph>::RANDOM);
-  checkMaxCliqueGridGraph(50, GrossoLocatelliPullanMc<GridGraph>::DEGREE_BASED);
-  checkMaxCliqueGridGraph(50, GrossoLocatelliPullanMc<GridGraph>::PENALTY_BASED);
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::RANDOM);
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::DEGREE_BASED);
+  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::PENALTY_BASED);
                        
   return 0;
Index: test/min_cost_arborescence_test.cc
===================================================================
--- test/min_cost_arborescence_test.cc	(revision 877)
+++ test/min_cost_arborescence_test.cc	(revision 1008)
@@ -92,4 +92,5 @@
   VType c;
   bool b;
+  ignore_unused_variable_warning(c,b);
   int i;
   CostMap cost;
Index: test/min_mean_cycle_test.cc
===================================================================
--- test/min_mean_cycle_test.cc	(revision 877)
+++ test/min_mean_cycle_test.cc	(revision 1012)
@@ -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/nagamochi_ibaraki_test.cc
===================================================================
--- test/nagamochi_ibaraki_test.cc	(revision 913)
+++ test/nagamochi_ibaraki_test.cc	(revision 1011)
@@ -66,4 +66,5 @@
   Value v;
   bool b;
+  ignore_unused_variable_warning(v,b);
 
   NagamochiIbaraki<Graph, CapMap> ni_test(g, cap);
Index: test/path_test.cc
===================================================================
--- test/path_test.cc	(revision 440)
+++ test/path_test.cc	(revision 990)
@@ -39,6 +39,35 @@
 }
 
+// Check if proper copy consructor is called (use valgrind for testing)
+template<class _Path>
+void checkCopy()
+{
+  ListDigraph g;
+  ListDigraph::Arc a  = g.addArc(g.addNode(), g.addNode());
+  
+  _Path p,q;
+  p.addBack(a);
+  q=p;
+  _Path r(p);
+  StaticPath<ListDigraph> s(r);
+}
+  
 int main() {
   check_concepts();
+
+  checkCopy<Path<ListDigraph> >();
+  checkCopy<SimplePath<ListDigraph> >();
+  checkCopy<ListPath<ListDigraph> >();
+
+  ListDigraph g;
+  ListDigraph::Arc a  = g.addArc(g.addNode(), g.addNode());
+  
+  Path<ListDigraph> p;
+  StaticPath<ListDigraph> q,r;
+  p.addBack(a);
+  q=p;
+  r=q;
+  StaticPath<ListDigraph> s(q);
+
   return 0;
 }
Index: test/preflow_test.cc
===================================================================
--- test/preflow_test.cc	(revision 877)
+++ test/preflow_test.cc	(revision 1008)
@@ -87,4 +87,5 @@
   VType v;
   bool b;
+  ignore_unused_variable_warning(v,b);
 
   typedef Preflow<Digraph, CapMap>
@@ -157,4 +158,28 @@
 }
 
+void initFlowTest()
+{
+  DIGRAPH_TYPEDEFS(SmartDigraph);
+  
+  SmartDigraph g;
+  SmartDigraph::ArcMap<int> cap(g),iflow(g);
+  Node s=g.addNode(); Node t=g.addNode();
+  Node n1=g.addNode(); Node n2=g.addNode();
+  Arc a;
+  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
+  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
+  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
+
+  Preflow<SmartDigraph> pre(g,cap,s,t);
+  pre.init(iflow);
+  pre.startFirstPhase();
+  check(pre.flowValue() == 10, "The incorrect max flow value.");
+  check(pre.minCut(s), "Wrong min cut (Node s).");
+  check(pre.minCut(n1), "Wrong min cut (Node n1).");
+  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
+  check(!pre.minCut(t), "Wrong min cut (Node t).");
+}
+
+
 int main() {
 
@@ -247,4 +272,6 @@
         "The max flow value or the three min cut values are incorrect.");
 
+  initFlowTest();
+  
   return 0;
 }
Index: test/suurballe_test.cc
===================================================================
--- test/suurballe_test.cc	(revision 877)
+++ test/suurballe_test.cc	(revision 1008)
@@ -118,4 +118,6 @@
   int f;
   VType c;
+  ignore_unused_variable_warning(f,c);
+
   c = const_suurb_test.totalLength();
   f = const_suurb_test.flow(e);
Index: test/time_measure_test.cc
===================================================================
--- test/time_measure_test.cc	(revision 558)
+++ test/time_measure_test.cc	(revision 997)
@@ -18,4 +18,5 @@
 
 #include <lemon/time_measure.h>
+#include <lemon/concept_check.h>
 
 using namespace lemon;
@@ -33,5 +34,8 @@
 
   for(int i=0;i<1000;i++)
-    TimeStamp x(T);
+    {
+      TimeStamp x(T);
+      ignore_unused_variable_warning(x);
+    }
 }
 
Index: ols/Makefile.am
===================================================================
--- tools/Makefile.am	(revision 674)
+++ 	(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 877)
+++ tools/dimacs-solver.cc	(revision 1006)
@@ -118,14 +118,15 @@
   if (report) std::cerr << "Read the file: " << ti << '\n';
 
-  ti.restart();
-  NetworkSimplex<Digraph, Value> ns(g);
+  typedef NetworkSimplex<Digraph, Value> MCF;
+  ti.restart();
+  MCF ns(g);
   ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
   if (sum_sup > 0) ns.supplyType(ns.LEQ);
   if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
   ti.restart();
-  bool res = ns.run();
+  typename MCF::ProblemType res = ns.run();
   if (report) {
     std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
-    std::cerr << "Feasible flow: " << (res ? "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';
@@ -188,7 +189,4 @@
 
 int main(int argc, const char *argv[]) {
-  typedef SmartDigraph Digraph;
-
-  typedef Digraph::Arc Arc;
 
   std::string inputName;
