Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 1067)
+++ test/CMakeLists.txt	(revision 1069)
@@ -1,11 +1,20 @@
 INCLUDE_DIRECTORIES(
-  ${CMAKE_SOURCE_DIR}
+  ${PROJECT_SOURCE_DIR}
   ${PROJECT_BINARY_DIR}
 )
 
-LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
+
+SET(TEST_WITH_VALGRIND "NO" CACHE STRING
+  "Run the test with valgrind (YES/NO).")
+SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.")
 
 SET(TESTS
+  adaptors_test
   bfs_test
+  circulation_test
+  connectivity_test
   counter_test
   dfs_test
@@ -13,20 +22,126 @@
   dijkstra_test
   dim_test
+  edge_set_test
   error_test
+  euler_test
+  gomory_hu_test
   graph_copy_test
   graph_test
   graph_utils_test
+  hao_orlin_test
   heap_test
   kruskal_test
   lgf_test
   maps_test
+  matching_test
+  min_cost_arborescence_test
+  min_cost_flow_test
+  path_test
+  preflow_test
+  radix_sort_test
   random_test
-  path_test
+  suurballe_test
   time_measure_test
-  unionfind_test)
+  unionfind_test
+)
+
+IF(LEMON_HAVE_LP)
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(lp_test lp_test.cc)
+  ELSE()
+    ADD_EXECUTABLE(lp_test EXCLUDE_FROM_ALL lp_test.cc)
+  ENDIF()
+
+  SET(LP_TEST_LIBS lemon)
+
+  IF(LEMON_HAVE_GLPK)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CPLEX)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CLP)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
+  ENDIF()
+
+  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
+  ADD_TEST(lp_test lp_test)
+  ADD_DEPENDENCIES(check lp_test)
+
+  IF(WIN32 AND LEMON_HAVE_GLPK)
+    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
+    )
+  ENDIF()
+
+  IF(WIN32 AND LEMON_HAVE_CPLEX)
+    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
+    )
+  ENDIF()
+ENDIF()
+
+IF(LEMON_HAVE_MIP)
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(mip_test mip_test.cc)
+  ELSE()
+    ADD_EXECUTABLE(mip_test EXCLUDE_FROM_ALL mip_test.cc)
+  ENDIF()
+
+  SET(MIP_TEST_LIBS lemon)
+
+  IF(LEMON_HAVE_GLPK)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CPLEX)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CBC)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
+  ENDIF()
+
+  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
+  ADD_TEST(mip_test mip_test)
+  ADD_DEPENDENCIES(check mip_test)
+
+  IF(WIN32 AND LEMON_HAVE_GLPK)
+    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
+    )
+  ENDIF()
+
+  IF(WIN32 AND LEMON_HAVE_CPLEX)
+    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
+    )
+  ENDIF()
+ENDIF()
 
 FOREACH(TEST_NAME ${TESTS})
-  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
+  ELSE()
+    ADD_EXECUTABLE(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_NAME}.cc)
+  ENDIF()
   TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
-  ADD_TEST(${TEST_NAME} ${TEST_NAME})
-ENDFOREACH(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: test/Makefile.am
===================================================================
--- test/Makefile.am	(revision 1067)
+++ test/Makefile.am	(revision 1069)
@@ -4,46 +4,83 @@
 noinst_HEADERS += \
 	test/graph_test.h \
-        test/test_tools.h
+	test/test_tools.h
 
 check_PROGRAMS += \
+	test/adaptors_test \
 	test/bfs_test \
-        test/counter_test \
+	test/circulation_test \
+	test/connectivity_test \
+	test/counter_test \
 	test/dfs_test \
 	test/digraph_test \
 	test/dijkstra_test \
-        test/dim_test \
+	test/dim_test \
+	test/edge_set_test \
 	test/error_test \
+	test/euler_test \
+	test/gomory_hu_test \
 	test/graph_copy_test \
 	test/graph_test \
 	test/graph_utils_test \
+	test/hao_orlin_test \
 	test/heap_test \
 	test/kruskal_test \
 	test/lgf_test \
-        test/maps_test \
-        test/random_test \
-        test/path_test \
-        test/test_tools_fail \
-        test/test_tools_pass \
-        test/time_measure_test \
+	test/maps_test \
+	test/matching_test \
+	test/min_cost_arborescence_test \
+	test/min_cost_flow_test \
+	test/path_test \
+	test/preflow_test \
+	test/radix_sort_test \
+	test/random_test \
+	test/suurballe_test \
+	test/test_tools_fail \
+	test/test_tools_pass \
+	test/time_measure_test \
 	test/unionfind_test
+
+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_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_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
 test_graph_copy_test_SOURCES = test/graph_copy_test.cc
 test_graph_test_SOURCES = test/graph_test.cc
 test_graph_utils_test_SOURCES = test/graph_utils_test.cc
+test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
 test_heap_test_SOURCES = test/heap_test.cc
 test_kruskal_test_SOURCES = test/kruskal_test.cc
 test_lgf_test_SOURCES = test/lgf_test.cc
+test_lp_test_SOURCES = test/lp_test.cc
 test_maps_test_SOURCES = test/maps_test.cc
+test_mip_test_SOURCES = test/mip_test.cc
+test_matching_test_SOURCES = test/matching_test.cc
+test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
+test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
 test_path_test_SOURCES = test/path_test.cc
+test_preflow_test_SOURCES = test/preflow_test.cc
+test_radix_sort_test_SOURCES = test/radix_sort_test.cc
+test_suurballe_test_SOURCES = test/suurballe_test.cc
 test_random_test_SOURCES = test/random_test.cc
 test_test_tools_fail_SOURCES = test/test_tools_fail.cc
Index: test/adaptors_test.cc
===================================================================
--- test/adaptors_test.cc	(revision 488)
+++ test/adaptors_test.cc	(revision 488)
@@ -0,0 +1,1486 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <limits>
+
+#include <lemon/list_graph.h>
+#include <lemon/grid_graph.h>
+#include <lemon/bfs.h>
+#include <lemon/path.h>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/graph_components.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concept_check.h>
+
+#include <lemon/adaptors.h>
+
+#include "test/test_tools.h"
+#include "test/graph_test.h"
+
+using namespace lemon;
+
+void checkReverseDigraph() {
+  // Check concepts
+  checkConcept<concepts::Digraph, ReverseDigraph<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, ReverseDigraph<ListDigraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               ReverseDigraph<ListDigraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               ReverseDigraph<ListDigraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               ReverseDigraph<ListDigraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               ReverseDigraph<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef ReverseDigraph<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  // Add nodes and arcs to the original digraph
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+
+  // Check the adaptor
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 0);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 2);
+
+  checkGraphInArcList(adaptor, n1, 2);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the orientation of the arcs
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    check(adaptor.source(a) == digraph.target(a), "Wrong reverse");
+    check(adaptor.target(a) == digraph.source(a), "Wrong reverse");
+  }
+
+  // Add and erase nodes and arcs in the digraph through the adaptor
+  Adaptor::Node n4 = adaptor.addNode();
+
+  Adaptor::Arc a4 = adaptor.addArc(n4, n3);
+  Adaptor::Arc a5 = adaptor.addArc(n2, n4);
+  Adaptor::Arc a6 = adaptor.addArc(n2, n4);
+  Adaptor::Arc a7 = adaptor.addArc(n1, n4);
+  Adaptor::Arc a8 = adaptor.addArc(n1, n2);
+
+  adaptor.erase(a1);
+  adaptor.erase(n3);
+
+  // Check the adaptor
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 4);
+  checkGraphConArcList(adaptor, 4);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n4, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the digraph
+  checkGraphNodeList(digraph, 3);
+  checkGraphArcList(digraph, 4);
+  checkGraphConArcList(digraph, 4);
+
+  checkGraphOutArcList(digraph, n1, 0);
+  checkGraphOutArcList(digraph, n2, 1);
+  checkGraphOutArcList(digraph, n4, 3);
+
+  checkGraphInArcList(digraph, n1, 2);
+  checkGraphInArcList(digraph, n2, 2);
+  checkGraphInArcList(digraph, n4, 0);
+
+  checkNodeIds(digraph);
+  checkArcIds(digraph);
+
+  checkGraphNodeMap(digraph);
+  checkGraphArcMap(digraph);
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = n4;
+  nd = n4;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = a4;
+  ad = a5;
+  Adaptor::Arc aa = a1;
+  aa = a2;
+}
+
+void checkSubDigraph() {
+  // Check concepts
+  checkConcept<concepts::Digraph, SubDigraph<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, SubDigraph<ListDigraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               SubDigraph<ListDigraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               SubDigraph<ListDigraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               SubDigraph<ListDigraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               SubDigraph<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Digraph::NodeMap<bool> NodeFilter;
+  typedef Digraph::ArcMap<bool> ArcFilter;
+  typedef SubDigraph<Digraph, NodeFilter, ArcFilter> Adaptor;
+
+  Digraph digraph;
+  NodeFilter node_filter(digraph);
+  ArcFilter arc_filter(digraph);
+  Adaptor adaptor(digraph, node_filter, arc_filter);
+
+  // Add nodes and arcs to the original digraph and the adaptor
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
+
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide an arc
+  adaptor.status(a2, false);
+  adaptor.disable(a3);
+  if (!adaptor.status(a3)) adaptor.enable(a3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 2);
+  checkGraphConArcList(adaptor, 2);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide a node
+  adaptor.status(n1, false);
+  adaptor.disable(n3);
+  if (!adaptor.status(n3)) adaptor.enable(n3);
+
+  checkGraphNodeList(adaptor, 2);
+  checkGraphArcList(adaptor, 1);
+  checkGraphConArcList(adaptor, 1);
+
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n2, 0);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide all nodes and arcs
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = n3;
+  nd = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = a3;
+  ad = a3;
+  Adaptor::Arc aa = a1;
+  aa = a2;
+}
+
+void checkFilterNodes1() {
+  // Check concepts
+  checkConcept<concepts::Digraph, FilterNodes<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, FilterNodes<ListDigraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               FilterNodes<ListDigraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               FilterNodes<ListDigraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               FilterNodes<ListDigraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               FilterNodes<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Digraph::NodeMap<bool> NodeFilter;
+  typedef FilterNodes<Digraph, NodeFilter> Adaptor;
+
+  Digraph digraph;
+  NodeFilter node_filter(digraph);
+  Adaptor adaptor(digraph, node_filter);
+
+  // Add nodes and arcs to the original digraph and the adaptor
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide a node
+  adaptor.status(n1, false);
+  adaptor.disable(n3);
+  if (!adaptor.status(n3)) adaptor.enable(n3);
+
+  checkGraphNodeList(adaptor, 2);
+  checkGraphArcList(adaptor, 1);
+  checkGraphConArcList(adaptor, 1);
+
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n2, 0);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide all nodes
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = n3;
+  nd = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = a3;
+  ad = a3;
+  Adaptor::Arc aa = a1;
+  aa = a2;
+}
+
+void checkFilterArcs() {
+  // Check concepts
+  checkConcept<concepts::Digraph, FilterArcs<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, FilterArcs<ListDigraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               FilterArcs<ListDigraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               FilterArcs<ListDigraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               FilterArcs<ListDigraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               FilterArcs<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Digraph::ArcMap<bool> ArcFilter;
+  typedef FilterArcs<Digraph, ArcFilter> Adaptor;
+
+  Digraph digraph;
+  ArcFilter arc_filter(digraph);
+  Adaptor adaptor(digraph, arc_filter);
+
+  // Add nodes and arcs to the original digraph and the adaptor
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
+
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide an arc
+  adaptor.status(a2, false);
+  adaptor.disable(a3);
+  if (!adaptor.status(a3)) adaptor.enable(a3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 2);
+  checkGraphConArcList(adaptor, 2);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Hide all arcs
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = n3;
+  nd = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = a3;
+  ad = a3;
+  Adaptor::Arc aa = a1;
+  aa = a2;
+}
+
+void checkUndirector() {
+  // Check concepts
+  checkConcept<concepts::Graph, Undirector<concepts::Digraph> >();
+  checkConcept<concepts::Graph, Undirector<ListDigraph> >();
+  checkConcept<concepts::AlterableGraphComponent<>,
+               Undirector<ListDigraph> >();
+  checkConcept<concepts::ExtendableGraphComponent<>,
+               Undirector<ListDigraph> >();
+  checkConcept<concepts::ErasableGraphComponent<>,
+               Undirector<ListDigraph> >();
+  checkConcept<concepts::ClearableGraphComponent<>,
+               Undirector<ListDigraph> >();
+
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Undirector<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  // Add nodes and arcs/edges to the original digraph and the adaptor
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
+
+  // Check the original digraph
+  checkGraphNodeList(digraph, 3);
+  checkGraphArcList(digraph, 3);
+  checkGraphConArcList(digraph, 3);
+
+  checkGraphOutArcList(digraph, n1, 2);
+  checkGraphOutArcList(digraph, n2, 1);
+  checkGraphOutArcList(digraph, n3, 0);
+
+  checkGraphInArcList(digraph, n1, 0);
+  checkGraphInArcList(digraph, n2, 1);
+  checkGraphInArcList(digraph, n3, 2);
+
+  checkNodeIds(digraph);
+  checkArcIds(digraph);
+
+  checkGraphNodeMap(digraph);
+  checkGraphArcMap(digraph);
+
+  // Check the adaptor
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 2);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Check the edges of the adaptor
+  for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) {
+    check(adaptor.u(e) == digraph.source(e), "Wrong undir");
+    check(adaptor.v(e) == digraph.target(e), "Wrong undir");
+  }
+
+  // Check CombinedArcMap
+  typedef Adaptor::CombinedArcMap
+    <Digraph::ArcMap<int>, Digraph::ArcMap<int> > IntCombinedMap;
+  typedef Adaptor::CombinedArcMap
+    <Digraph::ArcMap<bool>, Digraph::ArcMap<bool> > BoolCombinedMap;
+  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
+    IntCombinedMap>();
+  checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
+    BoolCombinedMap>();
+
+  Digraph::ArcMap<int> fw_map(digraph), bk_map(digraph);
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    fw_map[a] = digraph.id(a);
+    bk_map[a] = -digraph.id(a);
+  }
+
+  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::ArcMap<int> >
+    comb_map(fw_map, bk_map);
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    if (adaptor.source(a) == digraph.source(a)) {
+      check(comb_map[a] == fw_map[a], "Wrong combined map");
+    } else {
+      check(comb_map[a] == bk_map[a], "Wrong combined map");
+    }
+  }
+
+  // Check the conversion of nodes and arcs/edges
+  Digraph::Node nd = n3;
+  nd = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = e3;
+  ad = e3;
+  Adaptor::Edge ea = a1;
+  ea = a2;
+}
+
+void checkResidualDigraph() {
+  // Check concepts
+  checkConcept<concepts::Digraph, ResidualDigraph<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, ResidualDigraph<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef Digraph::ArcMap<int> IntArcMap;
+  typedef ResidualDigraph<Digraph, IntArcMap> Adaptor;
+
+  Digraph digraph;
+  IntArcMap capacity(digraph), flow(digraph);
+  Adaptor adaptor(digraph, capacity, flow);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+  Digraph::Node n4 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n1, n4);
+  Digraph::Arc a4 = digraph.addArc(n2, n3);
+  Digraph::Arc a5 = digraph.addArc(n2, n4);
+  Digraph::Arc a6 = digraph.addArc(n3, n4);
+
+  capacity[a1] = 8;
+  capacity[a2] = 6;
+  capacity[a3] = 4;
+  capacity[a4] = 4;
+  capacity[a5] = 6;
+  capacity[a6] = 10;
+
+  // Check the adaptor with various flow values
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    flow[a] = 0;
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, n1, 3);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 1);
+  checkGraphOutArcList(adaptor, n4, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    flow[a] = capacity[a] / 2;
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 12);
+  checkGraphConArcList(adaptor, 12);
+
+  checkGraphOutArcList(adaptor, n1, 3);
+  checkGraphOutArcList(adaptor, n2, 3);
+  checkGraphOutArcList(adaptor, n3, 3);
+  checkGraphOutArcList(adaptor, n4, 3);
+
+  checkGraphInArcList(adaptor, n1, 3);
+  checkGraphInArcList(adaptor, n2, 3);
+  checkGraphInArcList(adaptor, n3, 3);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    flow[a] = capacity[a];
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, n1, 0);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 2);
+  checkGraphOutArcList(adaptor, n4, 3);
+
+  checkGraphInArcList(adaptor, n1, 3);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 1);
+  checkGraphInArcList(adaptor, n4, 0);
+
+  // Saturate all backward arcs
+  // (set the flow to zero on all forward arcs)
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    if (adaptor.backward(a))
+      adaptor.augment(a, adaptor.residualCapacity(a));
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, n1, 3);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 1);
+  checkGraphOutArcList(adaptor, n4, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  // Find maximum flow by augmenting along shortest paths
+  int flow_value = 0;
+  Adaptor::ResidualCapacity res_cap(adaptor);
+  while (true) {
+
+    Bfs<Adaptor> bfs(adaptor);
+    bfs.run(n1, n4);
+
+    if (!bfs.reached(n4)) break;
+
+    Path<Adaptor> p = bfs.path(n4);
+
+    int min = std::numeric_limits<int>::max();
+    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
+      if (res_cap[a] < min) min = res_cap[a];
+    }
+
+    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
+      adaptor.augment(a, min);
+    }
+    flow_value += min;
+  }
+
+  check(flow_value == 18, "Wrong flow with res graph adaptor");
+
+  // Check forward() and backward()
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    check(adaptor.forward(a) != adaptor.backward(a),
+          "Wrong forward() or backward()");
+    check((adaptor.forward(a) && adaptor.forward(Digraph::Arc(a)) == a) ||
+          (adaptor.backward(a) && adaptor.backward(Digraph::Arc(a)) == a),
+          "Wrong forward() or backward()");
+  }
+
+  // Check the conversion of nodes and arcs
+  Digraph::Node nd = Adaptor::NodeIt(adaptor);
+  nd = ++Adaptor::NodeIt(adaptor);
+  Adaptor::Node na = n1;
+  na = n2;
+  Digraph::Arc ad = Adaptor::ArcIt(adaptor);
+  ad = ++Adaptor::ArcIt(adaptor);
+}
+
+void checkSplitNodes() {
+  // Check concepts
+  checkConcept<concepts::Digraph, SplitNodes<concepts::Digraph> >();
+  checkConcept<concepts::Digraph, SplitNodes<ListDigraph> >();
+
+  // Create a digraph and an adaptor
+  typedef ListDigraph Digraph;
+  typedef SplitNodes<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+
+  checkGraphNodeList(adaptor, 6);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0);
+
+  checkGraphInArcList(adaptor, adaptor.inNode(n1), 0);
+  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n2), 1);
+  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n3), 2);
+  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check split
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    if (adaptor.origArc(a)) {
+      Digraph::Arc oa = a;
+      check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)),
+            "Wrong split");
+      check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)),
+            "Wrong split");
+    } else {
+      Digraph::Node on = a;
+      check(adaptor.source(a) == adaptor.inNode(on), "Wrong split");
+      check(adaptor.target(a) == adaptor.outNode(on), "Wrong split");
+    }
+  }
+
+  // Check combined node map
+  typedef Adaptor::CombinedNodeMap
+    <Digraph::NodeMap<int>, Digraph::NodeMap<int> > IntCombinedNodeMap;
+  typedef Adaptor::CombinedNodeMap
+    <Digraph::NodeMap<bool>, Digraph::NodeMap<bool> > BoolCombinedNodeMap;
+  checkConcept<concepts::ReferenceMap<Adaptor::Node, int, int&, const int&>,
+    IntCombinedNodeMap>();
+//checkConcept<concepts::ReferenceMap<Adaptor::Node, bool, bool&, const bool&>,
+//  BoolCombinedNodeMap>();
+  checkConcept<concepts::ReadWriteMap<Adaptor::Node, bool>,
+    BoolCombinedNodeMap>();
+
+  Digraph::NodeMap<int> in_map(digraph), out_map(digraph);
+  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+    in_map[n] = digraph.id(n);
+    out_map[n] = -digraph.id(n);
+  }
+
+  Adaptor::CombinedNodeMap<Digraph::NodeMap<int>, Digraph::NodeMap<int> >
+    node_map(in_map, out_map);
+  for (Adaptor::NodeIt n(adaptor); n != INVALID; ++n) {
+    if (adaptor.inNode(n)) {
+      check(node_map[n] == in_map[n], "Wrong combined node map");
+    } else {
+      check(node_map[n] == out_map[n], "Wrong combined node map");
+    }
+  }
+
+  // Check combined arc map
+  typedef Adaptor::CombinedArcMap
+    <Digraph::ArcMap<int>, Digraph::NodeMap<int> > IntCombinedArcMap;
+  typedef Adaptor::CombinedArcMap
+    <Digraph::ArcMap<bool>, Digraph::NodeMap<bool> > BoolCombinedArcMap;
+  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
+    IntCombinedArcMap>();
+//checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
+//  BoolCombinedArcMap>();
+  checkConcept<concepts::ReadWriteMap<Adaptor::Arc, bool>,
+    BoolCombinedArcMap>();
+
+  Digraph::ArcMap<int> a_map(digraph);
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    a_map[a] = digraph.id(a);
+  }
+
+  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::NodeMap<int> >
+    arc_map(a_map, out_map);
+  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
+    check(arc_map[adaptor.arc(a)] == a_map[a],  "Wrong combined arc map");
+  }
+  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+    check(arc_map[adaptor.arc(n)] == out_map[n],  "Wrong combined arc map");
+  }
+
+  // Check the conversion of nodes
+  Digraph::Node nd = adaptor.inNode(n1);
+  check (nd == n1, "Wrong node conversion");
+  nd = adaptor.outNode(n2);
+  check (nd == n2, "Wrong node conversion");
+}
+
+void checkSubGraph() {
+  // Check concepts
+  checkConcept<concepts::Graph, SubGraph<concepts::Graph> >();
+  checkConcept<concepts::Graph, SubGraph<ListGraph> >();
+  checkConcept<concepts::AlterableGraphComponent<>,
+               SubGraph<ListGraph> >();
+  checkConcept<concepts::ExtendableGraphComponent<>,
+               SubGraph<ListGraph> >();
+  checkConcept<concepts::ErasableGraphComponent<>,
+               SubGraph<ListGraph> >();
+  checkConcept<concepts::ClearableGraphComponent<>,
+               SubGraph<ListGraph> >();
+
+  // Create a graph and an adaptor
+  typedef ListGraph Graph;
+  typedef Graph::NodeMap<bool> NodeFilter;
+  typedef Graph::EdgeMap<bool> EdgeFilter;
+  typedef SubGraph<Graph, NodeFilter, EdgeFilter> Adaptor;
+
+  Graph graph;
+  NodeFilter node_filter(graph);
+  EdgeFilter edge_filter(graph);
+  Adaptor adaptor(graph, node_filter, edge_filter);
+
+  // Add nodes and edges to the original graph and the adaptor
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+  Adaptor::Node n4 = adaptor.addNode();
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
+  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
+
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 2);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 3);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide an edge
+  adaptor.status(e2, false);
+  adaptor.disable(e3);
+  if (!adaptor.status(e3)) adaptor.enable(e3);
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 1);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide a node
+  adaptor.status(n1, false);
+  adaptor.disable(n3);
+  if (!adaptor.status(n3)) adaptor.enable(n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 4);
+  checkGraphEdgeList(adaptor, 2);
+  checkGraphConArcList(adaptor, 4);
+  checkGraphConEdgeList(adaptor, 2);
+
+  checkGraphIncEdgeArcLists(adaptor, n2, 1);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide all nodes and edges
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Check the conversion of nodes and edges
+  Graph::Node ng = n3;
+  ng = n4;
+  Adaptor::Node na = n1;
+  na = n2;
+  Graph::Edge eg = e3;
+  eg = e4;
+  Adaptor::Edge ea = e1;
+  ea = e2;
+}
+
+void checkFilterNodes2() {
+  // Check concepts
+  checkConcept<concepts::Graph, FilterNodes<concepts::Graph> >();
+  checkConcept<concepts::Graph, FilterNodes<ListGraph> >();
+  checkConcept<concepts::AlterableGraphComponent<>,
+               FilterNodes<ListGraph> >();
+  checkConcept<concepts::ExtendableGraphComponent<>,
+               FilterNodes<ListGraph> >();
+  checkConcept<concepts::ErasableGraphComponent<>,
+               FilterNodes<ListGraph> >();
+  checkConcept<concepts::ClearableGraphComponent<>,
+               FilterNodes<ListGraph> >();
+
+  // Create a graph and an adaptor
+  typedef ListGraph Graph;
+  typedef Graph::NodeMap<bool> NodeFilter;
+  typedef FilterNodes<Graph, NodeFilter> Adaptor;
+
+  // Add nodes and edges to the original graph and the adaptor
+  Graph graph;
+  NodeFilter node_filter(graph);
+  Adaptor adaptor(graph, node_filter);
+
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+  Adaptor::Node n4 = adaptor.addNode();
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
+  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 2);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 3);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide a node
+  adaptor.status(n1, false);
+  adaptor.disable(n3);
+  if (!adaptor.status(n3)) adaptor.enable(n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 4);
+  checkGraphEdgeList(adaptor, 2);
+  checkGraphConArcList(adaptor, 4);
+  checkGraphConEdgeList(adaptor, 2);
+
+  checkGraphIncEdgeArcLists(adaptor, n2, 1);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide all nodes
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Check the conversion of nodes and edges
+  Graph::Node ng = n3;
+  ng = n4;
+  Adaptor::Node na = n1;
+  na = n2;
+  Graph::Edge eg = e3;
+  eg = e4;
+  Adaptor::Edge ea = e1;
+  ea = e2;
+}
+
+void checkFilterEdges() {
+  // Check concepts
+  checkConcept<concepts::Graph, FilterEdges<concepts::Graph> >();
+  checkConcept<concepts::Graph, FilterEdges<ListGraph> >();
+  checkConcept<concepts::AlterableGraphComponent<>,
+               FilterEdges<ListGraph> >();
+  checkConcept<concepts::ExtendableGraphComponent<>,
+               FilterEdges<ListGraph> >();
+  checkConcept<concepts::ErasableGraphComponent<>,
+               FilterEdges<ListGraph> >();
+  checkConcept<concepts::ClearableGraphComponent<>,
+               FilterEdges<ListGraph> >();
+
+  // Create a graph and an adaptor
+  typedef ListGraph Graph;
+  typedef Graph::EdgeMap<bool> EdgeFilter;
+  typedef FilterEdges<Graph, EdgeFilter> Adaptor;
+
+  Graph graph;
+  EdgeFilter edge_filter(graph);
+  Adaptor adaptor(graph, edge_filter);
+
+  // Add nodes and edges to the original graph and the adaptor
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+  Adaptor::Node n4 = adaptor.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
+  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
+
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 2);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 3);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide an edge
+  adaptor.status(e2, false);
+  adaptor.disable(e3);
+  if (!adaptor.status(e3)) adaptor.enable(e3);
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphIncEdgeArcLists(adaptor, n1, 1);
+  checkGraphIncEdgeArcLists(adaptor, n2, 2);
+  checkGraphIncEdgeArcLists(adaptor, n3, 2);
+  checkGraphIncEdgeArcLists(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Hide all edges
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  // Check the conversion of nodes and edges
+  Graph::Node ng = n3;
+  ng = n4;
+  Adaptor::Node na = n1;
+  na = n2;
+  Graph::Edge eg = e3;
+  eg = e4;
+  Adaptor::Edge ea = e1;
+  ea = e2;
+}
+
+void checkOrienter() {
+  // Check concepts
+  checkConcept<concepts::Digraph, Orienter<concepts::Graph> >();
+  checkConcept<concepts::Digraph, Orienter<ListGraph> >();
+  checkConcept<concepts::AlterableDigraphComponent<>,
+               Orienter<ListGraph> >();
+  checkConcept<concepts::ExtendableDigraphComponent<>,
+               Orienter<ListGraph> >();
+  checkConcept<concepts::ErasableDigraphComponent<>,
+               Orienter<ListGraph> >();
+  checkConcept<concepts::ClearableDigraphComponent<>,
+               Orienter<ListGraph> >();
+
+  // Create a graph and an adaptor
+  typedef ListGraph Graph;
+  typedef ListGraph::EdgeMap<bool> DirMap;
+  typedef Orienter<Graph> Adaptor;
+
+  Graph graph;
+  DirMap dir(graph);
+  Adaptor adaptor(graph, dir);
+
+  // Add nodes and edges to the original graph and the adaptor
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Adaptor::Node n3 = adaptor.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Adaptor::Arc e3 = adaptor.addArc(n2, n3);
+
+  dir[e1] = dir[e2] = dir[e3] = true;
+
+  // Check the original graph
+  checkGraphNodeList(graph, 3);
+  checkGraphArcList(graph, 6);
+  checkGraphConArcList(graph, 6);
+  checkGraphEdgeList(graph, 3);
+  checkGraphConEdgeList(graph, 3);
+
+  checkGraphIncEdgeArcLists(graph, n1, 2);
+  checkGraphIncEdgeArcLists(graph, n2, 2);
+  checkGraphIncEdgeArcLists(graph, n3, 2);
+
+  checkNodeIds(graph);
+  checkArcIds(graph);
+  checkEdgeIds(graph);
+
+  checkGraphNodeMap(graph);
+  checkGraphArcMap(graph);
+  checkGraphEdgeMap(graph);
+
+  // Check the adaptor
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check direction changing
+  {
+    dir[e1] = true;
+    Adaptor::Node u = adaptor.source(e1);
+    Adaptor::Node v = adaptor.target(e1);
+
+    dir[e1] = false;
+    check (u == adaptor.target(e1), "Wrong dir");
+    check (v == adaptor.source(e1), "Wrong dir");
+
+    check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir");
+    dir[e1] = n1 == u;
+  }
+
+  {
+    dir[e2] = true;
+    Adaptor::Node u = adaptor.source(e2);
+    Adaptor::Node v = adaptor.target(e2);
+
+    dir[e2] = false;
+    check (u == adaptor.target(e2), "Wrong dir");
+    check (v == adaptor.source(e2), "Wrong dir");
+
+    check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir");
+    dir[e2] = n3 == u;
+  }
+
+  {
+    dir[e3] = true;
+    Adaptor::Node u = adaptor.source(e3);
+    Adaptor::Node v = adaptor.target(e3);
+
+    dir[e3] = false;
+    check (u == adaptor.target(e3), "Wrong dir");
+    check (v == adaptor.source(e3), "Wrong dir");
+
+    check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir");
+    dir[e3] = n2 == u;
+  }
+
+  // Check the adaptor again
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 1);
+
+  checkGraphInArcList(adaptor, n1, 1);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check reverseArc()
+  adaptor.reverseArc(e2);
+  adaptor.reverseArc(e3);
+  adaptor.reverseArc(e2);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 0);
+  checkGraphOutArcList(adaptor, n3, 2);
+
+  checkGraphInArcList(adaptor, n1, 1);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 0);
+
+  // Check the conversion of nodes and arcs/edges
+  Graph::Node ng = n3;
+  ng = n3;
+  Adaptor::Node na = n1;
+  na = n2;
+  Graph::Edge eg = e3;
+  eg = e3;
+  Adaptor::Arc aa = e1;
+  aa = e2;
+}
+
+void checkCombiningAdaptors() {
+  // Create a grid graph
+  GridGraph graph(2,2);
+  GridGraph::Node n1 = graph(0,0);
+  GridGraph::Node n2 = graph(0,1);
+  GridGraph::Node n3 = graph(1,0);
+  GridGraph::Node n4 = graph(1,1);
+
+  GridGraph::EdgeMap<bool> dir_map(graph);
+  dir_map[graph.right(n1)] = graph.u(graph.right(n1)) == n1;
+  dir_map[graph.up(n1)] = graph.u(graph.up(n1)) != n1;
+  dir_map[graph.left(n4)] = graph.u(graph.left(n4)) != n4;
+  dir_map[graph.down(n4)] = graph.u(graph.down(n4)) != n4;
+
+  // Apply several adaptors on the grid graph
+  typedef SplitNodes< ReverseDigraph< const Orienter<
+            const GridGraph, GridGraph::EdgeMap<bool> > > >
+    RevSplitGridGraph;
+  typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
+  typedef Undirector<const SplitGridGraph> USplitGridGraph;
+  typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
+  checkConcept<concepts::Digraph, RevSplitGridGraph>();
+  checkConcept<concepts::Digraph, SplitGridGraph>();
+  checkConcept<concepts::Graph, USplitGridGraph>();
+  checkConcept<concepts::Graph, UUSplitGridGraph>();
+
+  RevSplitGridGraph rev_adaptor =
+    splitNodes(reverseDigraph(orienter(graph, dir_map)));
+  SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
+  USplitGridGraph uadaptor = undirector(adaptor);
+  UUSplitGridGraph uuadaptor = undirector(uadaptor);
+
+  // Check adaptor
+  checkGraphNodeList(adaptor, 8);
+  checkGraphArcList(adaptor, 8);
+  checkGraphConArcList(adaptor, 8);
+
+  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
+  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
+  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
+  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
+
+  checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
+  checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
+  checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  // Check uadaptor
+  checkGraphNodeList(uadaptor, 8);
+  checkGraphEdgeList(uadaptor, 8);
+  checkGraphArcList(uadaptor, 16);
+  checkGraphConEdgeList(uadaptor, 8);
+  checkGraphConArcList(uadaptor, 16);
+
+  checkNodeIds(uadaptor);
+  checkEdgeIds(uadaptor);
+  checkArcIds(uadaptor);
+
+  checkGraphNodeMap(uadaptor);
+  checkGraphEdgeMap(uadaptor);
+  checkGraphArcMap(uadaptor);
+
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n1), 2);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
+  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
+
+  // Check uuadaptor
+  checkGraphNodeList(uuadaptor, 8);
+  checkGraphEdgeList(uuadaptor, 16);
+  checkGraphArcList(uuadaptor, 32);
+  checkGraphConEdgeList(uuadaptor, 16);
+  checkGraphConArcList(uuadaptor, 32);
+
+  checkNodeIds(uuadaptor);
+  checkEdgeIds(uuadaptor);
+  checkArcIds(uuadaptor);
+
+  checkGraphNodeMap(uuadaptor);
+  checkGraphEdgeMap(uuadaptor);
+  checkGraphArcMap(uuadaptor);
+}
+
+int main(int, const char **) {
+  // Check the digraph adaptors (using ListDigraph)
+  checkReverseDigraph();
+  checkSubDigraph();
+  checkFilterNodes1();
+  checkFilterArcs();
+  checkUndirector();
+  checkResidualDigraph();
+  checkSplitNodes();
+
+  // Check the graph adaptors (using ListGraph)
+  checkSubGraph();
+  checkFilterNodes2();
+  checkFilterEdges();
+  checkOrienter();
+
+  // Combine adaptors (using GridGraph)
+  checkCombiningAdaptors();
+
+  return 0;
+}
Index: test/bfs_test.cc
===================================================================
--- test/bfs_test.cc	(revision 293)
+++ test/bfs_test.cc	(revision 1081)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -59,14 +59,16 @@
 
   Digraph G;
-  Node s, t;
+  Node s, t, n;
   Arc e;
-  int l;
+  int l, i;
   bool b;
   BType::DistMap d(G);
   BType::PredMap p(G);
   Path<Digraph> pp;
+  concepts::ReadMap<Node,bool> nm;
 
   {
     BType bfs_test(G);
+    const BType& const_bfs_test = bfs_test;
 
     bfs_test.run(s);
@@ -74,11 +76,24 @@
     bfs_test.run();
 
-    l  = bfs_test.dist(t);
-    e  = bfs_test.predArc(t);
-    s  = bfs_test.predNode(t);
-    b  = bfs_test.reached(t);
-    d  = bfs_test.distMap();
-    p  = bfs_test.predMap();
-    pp = bfs_test.path(t);
+    bfs_test.init();
+    bfs_test.addSource(s);
+    n = bfs_test.processNextNode();
+    n = bfs_test.processNextNode(t, b);
+    n = bfs_test.processNextNode(nm, n);
+    n = const_bfs_test.nextNode();
+    b = const_bfs_test.emptyQueue();
+    i = const_bfs_test.queueSize();
+
+    bfs_test.start();
+    bfs_test.start(t);
+    bfs_test.start(nm);
+
+    l  = const_bfs_test.dist(t);
+    e  = const_bfs_test.predArc(t);
+    s  = const_bfs_test.predNode(t);
+    b  = const_bfs_test.reached(t);
+    d  = const_bfs_test.distMap();
+    p  = const_bfs_test.predMap();
+    pp = const_bfs_test.path(t);
   }
   {
@@ -87,11 +102,35 @@
       ::SetDistMap<concepts::ReadWriteMap<Node,int> >
       ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
+      ::SetStandardProcessedMap
       ::SetProcessedMap<concepts::WriteMap<Node,bool> >
-      ::SetStandardProcessedMap
       ::Create bfs_test(G);
+
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,int> dist_map;
+    concepts::ReadWriteMap<Node,bool> reached_map;
+    concepts::WriteMap<Node,bool> processed_map;
+
+    bfs_test
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .reachedMap(reached_map)
+      .processedMap(processed_map);
 
     bfs_test.run(s);
     bfs_test.run(s,t);
     bfs_test.run();
+
+    bfs_test.init();
+    bfs_test.addSource(s);
+    n = bfs_test.processNextNode();
+    n = bfs_test.processNextNode(t, b);
+    n = bfs_test.processNextNode(nm, n);
+    n = bfs_test.nextNode();
+    b = bfs_test.emptyQueue();
+    i = bfs_test.queueSize();
+
+    bfs_test.start();
+    bfs_test.start(t);
+    bfs_test.start(nm);
 
     l  = bfs_test.dist(t);
Index: test/circulation_test.cc
===================================================================
--- test/circulation_test.cc	(revision 1081)
+++ test/circulation_test.cc	(revision 1081)
@@ -0,0 +1,163 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/list_graph.h>
+#include <lemon/circulation.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@arcs\n"
+  "     lcap  ucap\n"
+  "0 1  2  10\n"
+  "0 2  2  6\n"
+  "1 3  4  7\n"
+  "1 4  0  5\n"
+  "2 4  1  3\n"
+  "3 5  3  8\n"
+  "4 5  3  7\n"
+  "@attributes\n"
+  "source 0\n"
+  "sink   5\n";
+
+void checkCirculationCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc,VType> CapMap;
+  typedef concepts::ReadMap<Node,VType> SupplyMap;
+  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
+  typedef concepts::WriteMap<Node,bool> BarrierMap;
+
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Node n;
+  Arc a;
+  CapMap lcap, ucap;
+  SupplyMap supply;
+  FlowMap flow;
+  BarrierMap bar;
+  VType v;
+  bool b;
+
+  typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
+            ::SetFlowMap<FlowMap>
+            ::SetElevator<Elev>
+            ::SetStandardElevator<LinkedElev>
+            ::Create CirculationType;
+  CirculationType circ_test(g, lcap, ucap, supply);
+  const CirculationType& const_circ_test = circ_test;
+
+  circ_test
+    .lowerMap(lcap)
+    .upperMap(ucap)
+    .supplyMap(supply)
+    .flowMap(flow);
+
+  circ_test.init();
+  circ_test.greedyInit();
+  circ_test.start();
+  circ_test.run();
+
+  v = const_circ_test.flow(a);
+  const FlowMap& fm = const_circ_test.flowMap();
+  b = const_circ_test.barrier(n);
+  const_circ_test.barrierMap(bar);
+
+  ignore_unused_variable_warning(fm);
+}
+
+template <class G, class LM, class UM, class DM>
+void checkCirculation(const G& g, const LM& lm, const UM& um,
+                      const DM& dm, bool find)
+{
+  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
+  bool ret = circ.run();
+  if (find) {
+    check(ret, "A feasible solution should have been found.");
+    check(circ.checkFlow(), "The found flow is corrupt.");
+    check(!circ.checkBarrier(), "A barrier should not have been found.");
+  } else {
+    check(!ret, "A feasible solution should not have been found.");
+    check(circ.checkBarrier(), "The found barrier is corrupt.");
+  }
+}
+
+int main (int, char*[])
+{
+  typedef ListDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph g;
+  IntArcMap lo(g), up(g);
+  IntNodeMap delta(g, 0);
+  Node s, t;
+
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(g,input).
+    arcMap("lcap", lo).
+    arcMap("ucap", up).
+    node("source",s).
+    node("sink",t).
+    run();
+
+  delta[s] = 7; delta[t] = -7;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 13; delta[t] = -13;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 6; delta[t] = -6;
+  checkCirculation(g, lo, up, delta, false);
+
+  delta[s] = 14; delta[t] = -14;
+  checkCirculation(g, lo, up, delta, false);
+
+  delta[s] = 7; delta[t] = -13;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 5; delta[t] = -15;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 10; delta[t] = -11;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 11; delta[t] = -10;
+  checkCirculation(g, lo, up, delta, false);
+
+  return 0;
+}
Index: test/connectivity_test.cc
===================================================================
--- test/connectivity_test.cc	(revision 1081)
+++ test/connectivity_test.cc	(revision 1081)
@@ -0,0 +1,297 @@
+/* -*- 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/connectivity.h>
+#include <lemon/list_graph.h>
+#include <lemon/adaptors.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+
+int main()
+{
+  typedef ListDigraph Digraph;
+  typedef Undirector<Digraph> Graph;
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+
+    check(stronglyConnected(d), "The empty digraph is strongly connected");
+    check(countStronglyConnectedComponents(d) == 0,
+          "The empty digraph has 0 strongly connected component");
+    check(connected(g), "The empty graph is connected");
+    check(countConnectedComponents(g) == 0,
+          "The empty graph has 0 connected component");
+
+    check(biNodeConnected(g), "The empty graph is bi-node-connected");
+    check(countBiNodeConnectedComponents(g) == 0,
+          "The empty graph has 0 bi-node-connected component");
+    check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
+    check(countBiEdgeConnectedComponents(g) == 0,
+          "The empty graph has 0 bi-edge-connected component");
+
+    check(dag(d), "The empty digraph is DAG.");
+    check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
+    check(loopFree(d), "The empty digraph is loop-free.");
+    check(parallelFree(d), "The empty digraph is parallel-free.");
+    check(simpleGraph(d), "The empty digraph is simple.");
+
+    check(acyclic(g), "The empty graph is acyclic.");
+    check(tree(g), "The empty graph is tree.");
+    check(bipartite(g), "The empty graph is bipartite.");
+    check(loopFree(g), "The empty graph is loop-free.");
+    check(parallelFree(g), "The empty graph is parallel-free.");
+    check(simpleGraph(g), "The empty graph is simple.");
+  }
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+
+    check(stronglyConnected(d), "This digraph is strongly connected");
+    check(countStronglyConnectedComponents(d) == 1,
+          "This digraph has 1 strongly connected component");
+    check(connected(g), "This graph is connected");
+    check(countConnectedComponents(g) == 1,
+          "This graph has 1 connected component");
+
+    check(biNodeConnected(g), "This graph is bi-node-connected");
+    check(countBiNodeConnectedComponents(g) == 0,
+          "This graph has 0 bi-node-connected component");
+    check(biEdgeConnected(g), "This graph is bi-edge-connected");
+    check(countBiEdgeConnectedComponents(g) == 1,
+          "This graph has 1 bi-edge-connected component");
+
+    check(dag(d), "This digraph is DAG.");
+    check(checkedTopologicalSort(d, order), "This digraph is DAG.");
+    check(loopFree(d), "This digraph is loop-free.");
+    check(parallelFree(d), "This digraph is parallel-free.");
+    check(simpleGraph(d), "This digraph is simple.");
+
+    check(acyclic(g), "This graph is acyclic.");
+    check(tree(g), "This graph is tree.");
+    check(bipartite(g), "This graph is bipartite.");
+    check(loopFree(g), "This graph is loop-free.");
+    check(parallelFree(g), "This graph is parallel-free.");
+    check(simpleGraph(g), "This graph is simple.");
+  }
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+
+    d.addArc(n1, n3);
+    d.addArc(n3, n2);
+    d.addArc(n2, n1);
+    d.addArc(n4, n2);
+    d.addArc(n4, n3);
+    d.addArc(n5, n6);
+    d.addArc(n6, n5);
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    check(!connected(g), "This graph is not connected");
+    check(countConnectedComponents(g) == 2,
+          "This graph has 2 connected components");
+
+    check(!dag(d), "This digraph is not DAG.");
+    check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
+    check(loopFree(d), "This digraph is loop-free.");
+    check(parallelFree(d), "This digraph is parallel-free.");
+    check(simpleGraph(d), "This digraph is simple.");
+
+    check(!acyclic(g), "This graph is not acyclic.");
+    check(!tree(g), "This graph is not tree.");
+    check(!bipartite(g), "This graph is not bipartite.");
+    check(loopFree(g), "This graph is loop-free.");
+    check(!parallelFree(g), "This graph is not parallel-free.");
+    check(!simpleGraph(g), "This graph is not simple.");
+
+    d.addArc(n3, n3);
+
+    check(!loopFree(d), "This digraph is not loop-free.");
+    check(!loopFree(g), "This graph is not loop-free.");
+    check(!simpleGraph(d), "This digraph is not simple.");
+
+    d.addArc(n3, n2);
+
+    check(!parallelFree(d), "This digraph is not parallel-free.");
+  }
+
+  {
+    Digraph d;
+    Digraph::ArcMap<bool> cutarcs(d, false);
+    Graph g(d);
+
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+    Digraph::Node n7 = d.addNode();
+    Digraph::Node n8 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n5, n1);
+    d.addArc(n2, n8);
+    d.addArc(n8, n5);
+    d.addArc(n6, n4);
+    d.addArc(n4, n6);
+    d.addArc(n2, n5);
+    d.addArc(n1, n8);
+    d.addArc(n6, n7);
+    d.addArc(n7, n6);
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    Digraph::NodeMap<int> scomp1(d);
+    check(stronglyConnectedComponents(d, scomp1) == 3,
+          "This digraph has 3 strongly connected components");
+    check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
+          scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
+    check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
+          scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
+    check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
+          "Wrong stronglyConnectedComponents()");
+    Digraph::ArcMap<bool> scut1(d, false);
+    check(stronglyConnectedCutArcs(d, scut1) == 0,
+          "This digraph has 0 strongly connected cut arc.");
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
+    }
+
+    check(!connected(g), "This graph is not connected");
+    check(countConnectedComponents(g) == 3,
+          "This graph has 3 connected components");
+    Graph::NodeMap<int> comp(g);
+    check(connectedComponents(g, comp) == 3,
+          "This graph has 3 connected components");
+    check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
+          comp[n3] != comp[n4], "Wrong connectedComponents()");
+    check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
+          comp[n1] == comp[n8], "Wrong connectedComponents()");
+    check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
+          "Wrong connectedComponents()");
+
+    cutarcs[d.addArc(n3, n1)] = true;
+    cutarcs[d.addArc(n3, n5)] = true;
+    cutarcs[d.addArc(n3, n8)] = true;
+    cutarcs[d.addArc(n8, n6)] = true;
+    cutarcs[d.addArc(n8, n7)] = true;
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    Digraph::NodeMap<int> scomp2(d);
+    check(stronglyConnectedComponents(d, scomp2) == 3,
+          "This digraph has 3 strongly connected components");
+    check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
+    check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
+          scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
+    check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
+          "Wrong stronglyConnectedComponents()");
+    Digraph::ArcMap<bool> scut2(d, false);
+    check(stronglyConnectedCutArcs(d, scut2) == 5,
+          "This digraph has 5 strongly connected cut arcs.");
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
+    }
+  }
+
+  {
+    // DAG example for topological sort from the book New Algorithms
+    // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+
+    Digraph::Node belt = d.addNode();
+    Digraph::Node trousers = d.addNode();
+    Digraph::Node necktie = d.addNode();
+    Digraph::Node coat = d.addNode();
+    Digraph::Node socks = d.addNode();
+    Digraph::Node shirt = d.addNode();
+    Digraph::Node shoe = d.addNode();
+    Digraph::Node watch = d.addNode();
+    Digraph::Node pants = d.addNode();
+
+    d.addArc(socks, shoe);
+    d.addArc(pants, shoe);
+    d.addArc(pants, trousers);
+    d.addArc(trousers, shoe);
+    d.addArc(trousers, belt);
+    d.addArc(belt, coat);
+    d.addArc(shirt, belt);
+    d.addArc(shirt, necktie);
+    d.addArc(necktie, coat);
+
+    check(dag(d), "This digraph is DAG.");
+    topologicalSort(d, order);
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(order[d.source(a)] < order[d.target(a)],
+            "Wrong topologicalSort()");
+    }
+  }
+
+  {
+    ListGraph g;
+    ListGraph::NodeMap<bool> map(g);
+
+    ListGraph::Node n1 = g.addNode();
+    ListGraph::Node n2 = g.addNode();
+    ListGraph::Node n3 = g.addNode();
+    ListGraph::Node n4 = g.addNode();
+    ListGraph::Node n5 = g.addNode();
+    ListGraph::Node n6 = g.addNode();
+    ListGraph::Node n7 = g.addNode();
+
+    g.addEdge(n1, n3);
+    g.addEdge(n1, n4);
+    g.addEdge(n2, n5);
+    g.addEdge(n3, n6);
+    g.addEdge(n4, n6);
+    g.addEdge(n4, n7);
+    g.addEdge(n5, n7);
+
+    check(bipartite(g), "This graph is bipartite");
+    check(bipartitePartitions(g, map), "This graph is bipartite");
+
+    check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
+          "Wrong bipartitePartitions()");
+    check(map[n3] == map[n4] && map[n3] == map[n5],
+          "Wrong bipartitePartitions()");
+  }
+
+  return 0;
+}
Index: test/counter_test.cc
===================================================================
--- test/counter_test.cc	(revision 209)
+++ test/counter_test.cc	(revision 605)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -19,4 +19,7 @@
 #include <lemon/counter.h>
 #include <vector>
+#include <sstream>
+
+#include "test/test_tools.h"
 
 using namespace lemon;
@@ -24,52 +27,76 @@
 template <typename T>
 void bubbleSort(std::vector<T>& v) {
-  Counter op("Bubble Sort - Operations: ");
-  Counter::NoSubCounter as(op, "Assignments: ");
-  Counter::NoSubCounter co(op, "Comparisons: ");
-  for (int i = v.size()-1; i > 0; --i) {
-    for (int j = 0; j < i; ++j) {
-      if (v[j] > v[j+1]) {
-        T tmp = v[j];
-        v[j] = v[j+1];
-        v[j+1] = tmp;
-        as += 3;
+  std::stringstream s1, s2, s3;
+  {
+    Counter op("Bubble Sort - Operations: ", s1);
+    Counter::SubCounter as(op, "Assignments: ", s2);
+    Counter::SubCounter co(op, "Comparisons: ", s3);
+    for (int i = v.size()-1; i > 0; --i) {
+      for (int j = 0; j < i; ++j) {
+        if (v[j] > v[j+1]) {
+          T tmp = v[j];
+          v[j] = v[j+1];
+          v[j+1] = tmp;
+          as += 3;
+        }
+        ++co;
       }
-      ++co;
     }
   }
+  check(s1.str() == "Bubble Sort - Operations: 102\n", "Wrong counter");
+  check(s2.str() == "Assignments: 57\n", "Wrong subcounter");
+  check(s3.str() == "Comparisons: 45\n", "Wrong subcounter");
 }
 
 template <typename T>
 void insertionSort(std::vector<T>& v) {
-  Counter op("Insertion Sort - Operations: ");
-  Counter::NoSubCounter as(op, "Assignments: ");
-  Counter::NoSubCounter co(op, "Comparisons: ");
-  for (int i = 1; i < int(v.size()); ++i) {
-    T value = v[i];
-    ++as;
-    int j = i;
-    while (j > 0 && v[j-1] > value) {
-      v[j] = v[j-1];
-      --j;
-      ++co; ++as;
+  std::stringstream s1, s2, s3;
+  {
+    Counter op("Insertion Sort - Operations: ", s1);
+    Counter::SubCounter as(op, "Assignments: ", s2);
+    Counter::SubCounter co(op, "Comparisons: ", s3);
+    for (int i = 1; i < int(v.size()); ++i) {
+      T value = v[i];
+      ++as;
+      int j = i;
+      while (j > 0 && v[j-1] > value) {
+        v[j] = v[j-1];
+        --j;
+        ++co; ++as;
+      }
+      v[j] = value;
+      ++as;
     }
-    v[j] = value;
-    ++as;
   }
+  check(s1.str() == "Insertion Sort - Operations: 56\n", "Wrong counter");
+  check(s2.str() == "Assignments: 37\n", "Wrong subcounter");
+  check(s3.str() == "Comparisons: 19\n", "Wrong subcounter");
 }
 
 template <typename MyCounter>
-void counterTest() {
-  MyCounter c("Main Counter: ");
-  c++;
-  typename MyCounter::SubCounter d(c, "SubCounter: ");
-  d++;
-  typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ");
-  e++;
-  d+=3;
-  c-=4;
-  e-=2;
-  c.reset(2);
-  c.reset();
+void counterTest(bool output) {
+  std::stringstream s1, s2, s3;
+  {
+    MyCounter c("Main Counter: ", s1);
+    c++;
+    typename MyCounter::SubCounter d(c, "SubCounter: ", s2);
+    d++;
+    typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ", s3);
+    e++;
+    d+=3;
+    c-=4;
+    e-=2;
+    c.reset(2);
+    c.reset();
+  }
+  if (output) {
+    check(s1.str() == "Main Counter: 3\n", "Wrong Counter");
+    check(s2.str() == "SubCounter: 3\n", "Wrong SubCounter");
+    check(s3.str() == "", "Wrong NoSubCounter");
+  } else {
+    check(s1.str() == "", "Wrong NoCounter");
+    check(s2.str() == "", "Wrong SubCounter");
+    check(s3.str() == "", "Wrong NoSubCounter");
+  }
 }
 
@@ -81,6 +108,6 @@
 int main()
 {
-  counterTest<Counter>();
-  counterTest<NoCounter>();
+  counterTest<Counter>(true);
+  counterTest<NoCounter>(false);
 
   std::vector<int> x(10);
Index: test/dfs_test.cc
===================================================================
--- test/dfs_test.cc	(revision 1078)
+++ test/dfs_test.cc	(revision 1081)
@@ -66,12 +66,14 @@
   Node s, t;
   Arc e;
-  int l;
+  int l, i;
   bool b;
   DType::DistMap d(G);
   DType::PredMap p(G);
   Path<Digraph> pp;
+  concepts::ReadMap<Arc,bool> am;
 
   {
     DType dfs_test(G);
+    const DType& const_dfs_test = dfs_test;
 
     dfs_test.run(s);
@@ -79,11 +81,22 @@
     dfs_test.run();
 
-    l  = dfs_test.dist(t);
-    e  = dfs_test.predArc(t);
-    s  = dfs_test.predNode(t);
-    b  = dfs_test.reached(t);
-    d  = dfs_test.distMap();
-    p  = dfs_test.predMap();
-    pp = dfs_test.path(t);
+    dfs_test.init();
+    dfs_test.addSource(s);
+    e = dfs_test.processNextArc();
+    e = const_dfs_test.nextArc();
+    b = const_dfs_test.emptyQueue();
+    i = const_dfs_test.queueSize();
+
+    dfs_test.start();
+    dfs_test.start(t);
+    dfs_test.start(am);
+
+    l  = const_dfs_test.dist(t);
+    e  = const_dfs_test.predArc(t);
+    s  = const_dfs_test.predNode(t);
+    b  = const_dfs_test.reached(t);
+    d  = const_dfs_test.distMap();
+    p  = const_dfs_test.predMap();
+    pp = const_dfs_test.path(t);
   }
   {
@@ -92,11 +105,33 @@
       ::SetDistMap<concepts::ReadWriteMap<Node,int> >
       ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
+      ::SetStandardProcessedMap
       ::SetProcessedMap<concepts::WriteMap<Node,bool> >
-      ::SetStandardProcessedMap
       ::Create dfs_test(G);
+
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,int> dist_map;
+    concepts::ReadWriteMap<Node,bool> reached_map;
+    concepts::WriteMap<Node,bool> processed_map;
+
+    dfs_test
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .reachedMap(reached_map)
+      .processedMap(processed_map);
 
     dfs_test.run(s);
     dfs_test.run(s,t);
     dfs_test.run();
+    dfs_test.init();
+
+    dfs_test.addSource(s);
+    e = dfs_test.processNextArc();
+    e = dfs_test.nextArc();
+    b = dfs_test.emptyQueue();
+    i = dfs_test.queueSize();
+
+    dfs_test.start();
+    dfs_test.start(t);
+    dfs_test.start(am);
 
     l  = dfs_test.dist(t);
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 387)
+++ test/digraph_test.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -20,6 +20,5 @@
 #include <lemon/list_graph.h>
 #include <lemon/smart_graph.h>
-//#include <lemon/full_graph.h>
-//#include <lemon/hypercube_graph.h>
+#include <lemon/full_graph.h>
 
 #include "test_tools.h"
@@ -319,10 +318,7 @@
     checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
   }
-//  { // Checking FullDigraph
-//    checkConcept<Digraph, FullDigraph>();
-//  }
-//  { // Checking HyperCubeDigraph
-//    checkConcept<Digraph, HyperCubeDigraph>();
-//  }
+  { // Checking FullDigraph
+    checkConcept<Digraph, FullDigraph>();
+  }
 }
 
@@ -375,4 +371,36 @@
   check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
   check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
+}
+
+void checkFullDigraph(int num) {
+  typedef FullDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+  Digraph G(num);
+
+  checkGraphNodeList(G, num);
+  checkGraphArcList(G, num * num);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, num);
+    checkGraphInArcList(G, n, num);
+  }
+
+  checkGraphConArcList(G, num * num);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+
+  for (int i = 0; i < G.nodeNum(); ++i) {
+    check(G.index(G(i)) == i, "Wrong index");
+  }
+
+  for (NodeIt s(G); s != INVALID; ++s) {
+    for (NodeIt t(G); t != INVALID; ++t) {
+      Arc a = G.arc(s, t);
+      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
+    }
+  }
 }
 
@@ -392,4 +420,7 @@
     checkDigraphValidity<SmartDigraph>();
   }
+  { // Checking FullDigraph
+    checkFullDigraph(8);
+  }
 }
 
Index: test/dijkstra_test.cc
===================================================================
--- test/dijkstra_test.cc	(revision 412)
+++ test/dijkstra_test.cc	(revision 1081)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -61,7 +61,8 @@
 
   Digraph G;
-  Node s, t;
+  Node s, t, n;
   Arc e;
   VType l;
+  int i;
   bool b;
   DType::DistMap d(G);
@@ -69,10 +70,75 @@
   LengthMap length;
   Path<Digraph> pp;
+  concepts::ReadMap<Node,bool> nm;
 
   {
     DType dijkstra_test(G,length);
+    const DType& const_dijkstra_test = dijkstra_test;
 
     dijkstra_test.run(s);
     dijkstra_test.run(s,t);
+
+    dijkstra_test.init();
+    dijkstra_test.addSource(s);
+    dijkstra_test.addSource(s, 1);
+    n = dijkstra_test.processNextNode();
+    n = const_dijkstra_test.nextNode();
+    b = const_dijkstra_test.emptyQueue();
+    i = const_dijkstra_test.queueSize();
+
+    dijkstra_test.start();
+    dijkstra_test.start(t);
+    dijkstra_test.start(nm);
+
+    l  = const_dijkstra_test.dist(t);
+    e  = const_dijkstra_test.predArc(t);
+    s  = const_dijkstra_test.predNode(t);
+    b  = const_dijkstra_test.reached(t);
+    b  = const_dijkstra_test.processed(t);
+    d  = const_dijkstra_test.distMap();
+    p  = const_dijkstra_test.predMap();
+    pp = const_dijkstra_test.path(t);
+    l  = const_dijkstra_test.currentDist(t);
+  }
+  {
+    DType
+      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
+      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
+      ::SetStandardProcessedMap
+      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
+      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
+      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
+      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
+      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
+                concepts::ReadWriteMap<Node,int> >
+      ::Create dijkstra_test(G,length);
+
+    LengthMap length_map;
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,VType> dist_map;
+    concepts::WriteMap<Node,bool> processed_map;
+    concepts::ReadWriteMap<Node,int> heap_cross_ref;
+    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
+
+    dijkstra_test
+      .lengthMap(length_map)
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .processedMap(processed_map)
+      .heap(heap, heap_cross_ref);
+
+    dijkstra_test.run(s);
+    dijkstra_test.run(s,t);
+
+    dijkstra_test.addSource(s);
+    dijkstra_test.addSource(s, 1);
+    n = dijkstra_test.processNextNode();
+    n = dijkstra_test.nextNode();
+    b = dijkstra_test.emptyQueue();
+    i = dijkstra_test.queueSize();
+
+    dijkstra_test.start();
+    dijkstra_test.start(t);
+    dijkstra_test.start(nm);
 
     l  = dijkstra_test.dist(t);
@@ -80,27 +146,7 @@
     s  = dijkstra_test.predNode(t);
     b  = dijkstra_test.reached(t);
-    d  = dijkstra_test.distMap();
-    p  = dijkstra_test.predMap();
+    b  = dijkstra_test.processed(t);
     pp = dijkstra_test.path(t);
-  }
-  {
-    DType
-      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
-      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
-      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
-      ::SetStandardProcessedMap
-      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
-      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
-      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
-      ::Create dijkstra_test(G,length);
-
-    dijkstra_test.run(s);
-    dijkstra_test.run(s,t);
-
-    l  = dijkstra_test.dist(t);
-    e  = dijkstra_test.predArc(t);
-    s  = dijkstra_test.predNode(t);
-    b  = dijkstra_test.reached(t);
-    pp = dijkstra_test.path(t);
+    l  = dijkstra_test.currentDist(t);
   }
 
Index: test/dim_test.cc
===================================================================
--- test/dim_test.cc	(revision 253)
+++ test/dim_test.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/edge_set_test.cc
===================================================================
--- test/edge_set_test.cc	(revision 1081)
+++ test/edge_set_test.cc	(revision 1081)
@@ -0,0 +1,380 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <vector>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concept_check.h>
+
+#include <lemon/list_graph.h>
+
+#include <lemon/edge_set.h>
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+using namespace lemon;
+
+void checkSmartArcSet() {
+  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef SmartArcSet<Digraph> ArcSet;
+
+  Digraph digraph;
+  Digraph::Node
+    n1 = digraph.addNode(),
+    n2 = digraph.addNode();
+
+  Digraph::Arc ga1 = digraph.addArc(n1, n2);
+
+  ArcSet arc_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+
+  checkGraphNodeList(arc_set, 2);
+  checkGraphArcList(arc_set, 0);
+
+  Digraph::Node
+    n3 = digraph.addNode();
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 0);
+
+  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
+  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 1);
+
+  checkGraphOutArcList(arc_set, n1, 1);
+  checkGraphOutArcList(arc_set, n2, 0);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n1, 0);
+  checkGraphInArcList(arc_set, n2, 1);
+  checkGraphInArcList(arc_set, n3, 0);
+
+  checkGraphConArcList(arc_set, 1);
+
+  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
+    a3 = arc_set.addArc(n2, n3),
+    a4 = arc_set.addArc(n2, n3);
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 4);
+
+  checkGraphOutArcList(arc_set, n1, 1);
+  checkGraphOutArcList(arc_set, n2, 3);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n1, 1);
+  checkGraphInArcList(arc_set, n2, 1);
+  checkGraphInArcList(arc_set, n3, 2);
+
+  checkGraphConArcList(arc_set, 4);
+
+  checkNodeIds(arc_set);
+  checkArcIds(arc_set);
+  checkGraphNodeMap(arc_set);
+  checkGraphArcMap(arc_set);
+
+  check(arc_set.valid(), "Wrong validity");
+  digraph.erase(n1);
+  check(!arc_set.valid(), "Wrong validity");
+}
+
+void checkListArcSet() {
+  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef ListArcSet<Digraph> ArcSet;
+
+  Digraph digraph;
+  Digraph::Node
+    n1 = digraph.addNode(),
+    n2 = digraph.addNode();
+
+  Digraph::Arc ga1 = digraph.addArc(n1, n2);
+
+  ArcSet arc_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+
+  checkGraphNodeList(arc_set, 2);
+  checkGraphArcList(arc_set, 0);
+
+  Digraph::Node
+    n3 = digraph.addNode();
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 0);
+
+  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
+  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 1);
+
+  checkGraphOutArcList(arc_set, n1, 1);
+  checkGraphOutArcList(arc_set, n2, 0);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n1, 0);
+  checkGraphInArcList(arc_set, n2, 1);
+  checkGraphInArcList(arc_set, n3, 0);
+
+  checkGraphConArcList(arc_set, 1);
+
+  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
+    a3 = arc_set.addArc(n2, n3),
+    a4 = arc_set.addArc(n2, n3);
+  checkGraphNodeList(arc_set, 3);
+  checkGraphArcList(arc_set, 4);
+
+  checkGraphOutArcList(arc_set, n1, 1);
+  checkGraphOutArcList(arc_set, n2, 3);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n1, 1);
+  checkGraphInArcList(arc_set, n2, 1);
+  checkGraphInArcList(arc_set, n3, 2);
+
+  checkGraphConArcList(arc_set, 4);
+
+  checkNodeIds(arc_set);
+  checkArcIds(arc_set);
+  checkGraphNodeMap(arc_set);
+  checkGraphArcMap(arc_set);
+
+  digraph.erase(n1);
+
+  checkGraphNodeList(arc_set, 2);
+  checkGraphArcList(arc_set, 2);
+
+  checkGraphOutArcList(arc_set, n2, 2);
+  checkGraphOutArcList(arc_set, n3, 0);
+
+  checkGraphInArcList(arc_set, n2, 0);
+  checkGraphInArcList(arc_set, n3, 2);
+
+  checkNodeIds(arc_set);
+  checkArcIds(arc_set);
+  checkGraphNodeMap(arc_set);
+  checkGraphArcMap(arc_set);
+
+  checkGraphConArcList(arc_set, 2);
+}
+
+void checkSmartEdgeSet() {
+  checkConcept<concepts::Digraph, SmartEdgeSet<ListDigraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef SmartEdgeSet<Digraph> EdgeSet;
+
+  Digraph digraph;
+  Digraph::Node
+    n1 = digraph.addNode(),
+    n2 = digraph.addNode();
+
+  Digraph::Arc ga1 = digraph.addArc(n1, n2);
+
+  EdgeSet edge_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+
+  checkGraphNodeList(edge_set, 2);
+  checkGraphArcList(edge_set, 0);
+  checkGraphEdgeList(edge_set, 0);
+
+  Digraph::Node
+    n3 = digraph.addNode();
+  checkGraphNodeList(edge_set, 3);
+  checkGraphArcList(edge_set, 0);
+  checkGraphEdgeList(edge_set, 0);
+
+  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
+  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
+        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
+  checkGraphNodeList(edge_set, 3);
+  checkGraphArcList(edge_set, 2);
+  checkGraphEdgeList(edge_set, 1);
+
+  checkGraphOutArcList(edge_set, n1, 1);
+  checkGraphOutArcList(edge_set, n2, 1);
+  checkGraphOutArcList(edge_set, n3, 0);
+
+  checkGraphInArcList(edge_set, n1, 1);
+  checkGraphInArcList(edge_set, n2, 1);
+  checkGraphInArcList(edge_set, n3, 0);
+
+  checkGraphIncEdgeList(edge_set, n1, 1);
+  checkGraphIncEdgeList(edge_set, n2, 1);
+  checkGraphIncEdgeList(edge_set, n3, 0);
+
+  checkGraphConEdgeList(edge_set, 1);
+  checkGraphConArcList(edge_set, 2);
+
+  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
+    e3 = edge_set.addEdge(n2, n3),
+    e4 = edge_set.addEdge(n2, n3);
+  checkGraphNodeList(edge_set, 3);
+  checkGraphEdgeList(edge_set, 4);
+
+  checkGraphOutArcList(edge_set, n1, 2);
+  checkGraphOutArcList(edge_set, n2, 4);
+  checkGraphOutArcList(edge_set, n3, 2);
+
+  checkGraphInArcList(edge_set, n1, 2);
+  checkGraphInArcList(edge_set, n2, 4);
+  checkGraphInArcList(edge_set, n3, 2);
+
+  checkGraphIncEdgeList(edge_set, n1, 2);
+  checkGraphIncEdgeList(edge_set, n2, 4);
+  checkGraphIncEdgeList(edge_set, n3, 2);
+
+  checkGraphConEdgeList(edge_set, 4);
+  checkGraphConArcList(edge_set, 8);
+
+  checkArcDirections(edge_set);
+
+  checkNodeIds(edge_set);
+  checkArcIds(edge_set);
+  checkEdgeIds(edge_set);
+  checkGraphNodeMap(edge_set);
+  checkGraphArcMap(edge_set);
+  checkGraphEdgeMap(edge_set);
+
+  check(edge_set.valid(), "Wrong validity");
+  digraph.erase(n1);
+  check(!edge_set.valid(), "Wrong validity");
+}
+
+void checkListEdgeSet() {
+  checkConcept<concepts::Digraph, ListEdgeSet<ListDigraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef ListEdgeSet<Digraph> EdgeSet;
+
+  Digraph digraph;
+  Digraph::Node
+    n1 = digraph.addNode(),
+    n2 = digraph.addNode();
+
+  Digraph::Arc ga1 = digraph.addArc(n1, n2);
+
+  EdgeSet edge_set(digraph);
+
+  Digraph::Arc ga2 = digraph.addArc(n2, n1);
+
+  checkGraphNodeList(edge_set, 2);
+  checkGraphArcList(edge_set, 0);
+  checkGraphEdgeList(edge_set, 0);
+
+  Digraph::Node
+    n3 = digraph.addNode();
+  checkGraphNodeList(edge_set, 3);
+  checkGraphArcList(edge_set, 0);
+  checkGraphEdgeList(edge_set, 0);
+
+  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
+  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
+        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
+  checkGraphNodeList(edge_set, 3);
+  checkGraphArcList(edge_set, 2);
+  checkGraphEdgeList(edge_set, 1);
+
+  checkGraphOutArcList(edge_set, n1, 1);
+  checkGraphOutArcList(edge_set, n2, 1);
+  checkGraphOutArcList(edge_set, n3, 0);
+
+  checkGraphInArcList(edge_set, n1, 1);
+  checkGraphInArcList(edge_set, n2, 1);
+  checkGraphInArcList(edge_set, n3, 0);
+
+  checkGraphIncEdgeList(edge_set, n1, 1);
+  checkGraphIncEdgeList(edge_set, n2, 1);
+  checkGraphIncEdgeList(edge_set, n3, 0);
+
+  checkGraphConEdgeList(edge_set, 1);
+  checkGraphConArcList(edge_set, 2);
+
+  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
+    e3 = edge_set.addEdge(n2, n3),
+    e4 = edge_set.addEdge(n2, n3);
+  checkGraphNodeList(edge_set, 3);
+  checkGraphEdgeList(edge_set, 4);
+
+  checkGraphOutArcList(edge_set, n1, 2);
+  checkGraphOutArcList(edge_set, n2, 4);
+  checkGraphOutArcList(edge_set, n3, 2);
+
+  checkGraphInArcList(edge_set, n1, 2);
+  checkGraphInArcList(edge_set, n2, 4);
+  checkGraphInArcList(edge_set, n3, 2);
+
+  checkGraphIncEdgeList(edge_set, n1, 2);
+  checkGraphIncEdgeList(edge_set, n2, 4);
+  checkGraphIncEdgeList(edge_set, n3, 2);
+
+  checkGraphConEdgeList(edge_set, 4);
+  checkGraphConArcList(edge_set, 8);
+
+  checkArcDirections(edge_set);
+
+  checkNodeIds(edge_set);
+  checkArcIds(edge_set);
+  checkEdgeIds(edge_set);
+  checkGraphNodeMap(edge_set);
+  checkGraphArcMap(edge_set);
+  checkGraphEdgeMap(edge_set);
+
+  digraph.erase(n1);
+
+  checkGraphNodeList(edge_set, 2);
+  checkGraphArcList(edge_set, 4);
+  checkGraphEdgeList(edge_set, 2);
+
+  checkGraphOutArcList(edge_set, n2, 2);
+  checkGraphOutArcList(edge_set, n3, 2);
+
+  checkGraphInArcList(edge_set, n2, 2);
+  checkGraphInArcList(edge_set, n3, 2);
+
+  checkGraphIncEdgeList(edge_set, n2, 2);
+  checkGraphIncEdgeList(edge_set, n3, 2);
+
+  checkNodeIds(edge_set);
+  checkArcIds(edge_set);
+  checkEdgeIds(edge_set);
+  checkGraphNodeMap(edge_set);
+  checkGraphArcMap(edge_set);
+  checkGraphEdgeMap(edge_set);
+
+  checkGraphConEdgeList(edge_set, 2);
+  checkGraphConArcList(edge_set, 4);
+
+}
+
+
+int main() {
+
+  checkSmartArcSet();
+  checkListArcSet();
+  checkSmartEdgeSet();
+  checkListEdgeSet();
+
+  return 0;
+}
Index: test/error_test.cc
===================================================================
--- test/error_test.cc	(revision 277)
+++ test/error_test.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/euler_test.cc
===================================================================
--- test/euler_test.cc	(revision 1081)
+++ test/euler_test.cc	(revision 1081)
@@ -0,0 +1,223 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-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/euler.h>
+#include <lemon/list_graph.h>
+#include <lemon/adaptors.h>
+#include "test_tools.h"
+
+using namespace lemon;
+
+template <typename Digraph>
+void checkDiEulerIt(const Digraph& g,
+                    const typename Digraph::Node& start = INVALID)
+{
+  typename Digraph::template ArcMap<int> visitationNumber(g, 0);
+
+  DiEulerIt<Digraph> e(g, start);
+  if (e == INVALID) return;
+  typename Digraph::Node firstNode = g.source(e);
+  typename Digraph::Node lastNode = g.target(e);
+  if (start != INVALID) {
+    check(firstNode == start, "checkDiEulerIt: Wrong first node");
+  }
+
+  for (; e != INVALID; ++e) {
+    if (e != INVALID) lastNode = g.target(e);
+    ++visitationNumber[e];
+  }
+
+  check(firstNode == lastNode,
+      "checkDiEulerIt: First and last nodes are not the same");
+
+  for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
+  {
+    check(visitationNumber[a] == 1,
+        "checkDiEulerIt: Not visited or multiple times visited arc found");
+  }
+}
+
+template <typename Graph>
+void checkEulerIt(const Graph& g,
+                  const typename Graph::Node& start = INVALID)
+{
+  typename Graph::template EdgeMap<int> visitationNumber(g, 0);
+
+  EulerIt<Graph> e(g, start);
+  if (e == INVALID) return;
+  typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
+  typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
+  if (start != INVALID) {
+    check(firstNode == start, "checkEulerIt: Wrong first node");
+  }
+
+  for (; e != INVALID; ++e) {
+    if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
+    ++visitationNumber[e];
+  }
+
+  check(firstNode == lastNode,
+      "checkEulerIt: First and last nodes are not the same");
+
+  for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
+  {
+    check(visitationNumber[e] == 1,
+        "checkEulerIt: Not visited or multiple times visited edge found");
+  }
+}
+
+int main()
+{
+  typedef ListDigraph Digraph;
+  typedef Undirector<Digraph> Graph;
+
+  {
+    Digraph d;
+    Graph g(d);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+    d.addArc(n, n);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n1);
+    d.addArc(n2, n3);
+    d.addArc(n3, n2);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n2);
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n2);
+    checkEulerIt(g);
+    checkEulerIt(g, n2);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n4);
+    d.addArc(n1, n3);
+    d.addArc(n3, n4);
+    d.addArc(n4, n1);
+    d.addArc(n3, n5);
+    d.addArc(n5, n2);
+    d.addArc(n4, n6);
+    d.addArc(n2, n6);
+    d.addArc(n6, n1);
+    d.addArc(n6, n3);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n1);
+    checkDiEulerIt(d, n5);
+
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n1);
+    checkDiEulerIt(g, n5);
+    checkEulerIt(g);
+    checkEulerIt(g, n1);
+    checkEulerIt(g, n5);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n0 = d.addNode();
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n3);
+    d.addArc(n3, n1);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n2);
+
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n2);
+    checkEulerIt(g);
+    checkEulerIt(g, n2);
+
+    check(!eulerian(d), "This graph is not Eulerian");
+    check(!eulerian(g), "This graph is not Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n3);
+
+    check(!eulerian(d), "This graph is not Eulerian");
+    check(!eulerian(g), "This graph is not Eulerian");
+  }
+
+  return 0;
+}
Index: test/gomory_hu_test.cc
===================================================================
--- test/gomory_hu_test.cc	(revision 1081)
+++ test/gomory_hu_test.cc	(revision 1081)
@@ -0,0 +1,141 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/gomory_hu.h>
+#include <cstdlib>
+
+using namespace std;
+using namespace lemon;
+
+typedef SmartGraph Graph;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "@arcs\n"
+  "     label capacity\n"
+  "0 1  0     1\n"
+  "1 2  1     1\n"
+  "2 3  2     1\n"
+  "0 3  4     5\n"
+  "0 3  5     10\n"
+  "0 3  6     7\n"
+  "4 2  7     1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 3\n";
+
+void checkGomoryHuCompile()
+{
+  typedef int Value;
+  typedef concepts::Graph Graph;
+
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef concepts::ReadMap<Edge, Value> CapMap;
+  typedef concepts::ReadWriteMap<Node, bool> CutMap;
+
+  Graph g;
+  Node n;
+  CapMap cap;
+  CutMap cut;
+  Value v;
+  int d;
+
+  GomoryHu<Graph, CapMap> gh_test(g, cap);
+  const GomoryHu<Graph, CapMap>&
+    const_gh_test = gh_test;
+
+  gh_test.run();
+
+  n = const_gh_test.predNode(n);
+  v = const_gh_test.predValue(n);
+  d = const_gh_test.rootDist(n);
+  v = const_gh_test.minCutValue(n, n);
+  v = const_gh_test.minCutMap(n, n, cut);
+}
+
+GRAPH_TYPEDEFS(Graph);
+typedef Graph::EdgeMap<int> IntEdgeMap;
+typedef Graph::NodeMap<bool> BoolNodeMap;
+
+int cutValue(const Graph& graph, const BoolNodeMap& cut,
+             const IntEdgeMap& capacity) {
+
+  int sum = 0;
+  for (EdgeIt e(graph); e != INVALID; ++e) {
+    Node s = graph.u(e);
+    Node t = graph.v(e);
+
+    if (cut[s] != cut[t]) {
+      sum += capacity[e];
+    }
+  }
+  return sum;
+}
+
+
+int main() {
+  Graph graph;
+  IntEdgeMap capacity(graph);
+
+  std::istringstream input(test_lgf);
+  GraphReader<Graph>(graph, input).
+    edgeMap("capacity", capacity).run();
+
+  GomoryHu<Graph> ght(graph, capacity);
+  ght.run();
+
+  for (NodeIt u(graph); u != INVALID; ++u) {
+    for (NodeIt v(graph); v != u; ++v) {
+      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
+      pf.runMinCut();
+      BoolNodeMap cm(graph);
+      ght.minCutMap(u, v, cm);
+      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
+      check(cm[u] != cm[v], "Wrong cut 2");
+      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
+
+      int sum=0;
+      for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
+        sum+=capacity[a];
+      check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
+
+      sum=0;
+      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
+        sum++;
+      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
+        sum++;
+      check(sum == countNodes(graph), "Problem with MinCutNodeIt");
+    }
+  }
+
+  return 0;
+}
Index: test/graph_test.cc
===================================================================
--- test/graph_test.cc	(revision 387)
+++ test/graph_test.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -20,6 +20,7 @@
 #include <lemon/list_graph.h>
 #include <lemon/smart_graph.h>
-// #include <lemon/full_graph.h>
-// #include <lemon/grid_graph.h>
+#include <lemon/full_graph.h>
+#include <lemon/grid_graph.h>
+#include <lemon/hypercube_graph.h>
 
 #include "test_tools.h"
@@ -262,4 +263,51 @@
 }
 
+void checkFullGraph(int num) {
+  typedef FullGraph Graph;
+  GRAPH_TYPEDEFS(Graph);
+
+  Graph G(num);
+  checkGraphNodeList(G, num);
+  checkGraphEdgeList(G, num * (num - 1) / 2);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, num - 1);
+    checkGraphInArcList(G, n, num - 1);
+    checkGraphIncEdgeList(G, n, num - 1);
+  }
+
+  checkGraphConArcList(G, num * (num - 1));
+  checkGraphConEdgeList(G, num * (num - 1) / 2);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+
+  for (int i = 0; i < G.nodeNum(); ++i) {
+    check(G.index(G(i)) == i, "Wrong index");
+  }
+
+  for (NodeIt u(G); u != INVALID; ++u) {
+    for (NodeIt v(G); v != INVALID; ++v) {
+      Edge e = G.edge(u, v);
+      Arc a = G.arc(u, v);
+      if (u == v) {
+        check(e == INVALID, "Wrong edge lookup");
+        check(a == INVALID, "Wrong arc lookup");
+      } else {
+        check((G.u(e) == u && G.v(e) == v) ||
+              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
+        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
+      }
+    }
+  }
+}
+
 void checkConcepts() {
   { // Checking graph components
@@ -291,12 +339,13 @@
     checkConcept<ClearableGraphComponent<>, SmartGraph>();
   }
-//  { // Checking FullGraph
-//    checkConcept<Graph, FullGraph>();
-//    checkGraphIterators<FullGraph>();
-//  }
-//  { // Checking GridGraph
-//    checkConcept<Graph, GridGraph>();
-//    checkGraphIterators<GridGraph>();
-//  }
+  { // Checking FullGraph
+    checkConcept<Graph, FullGraph>();
+  }
+  { // Checking GridGraph
+    checkConcept<Graph, GridGraph>();
+  }
+  { // Checking HypercubeGraph
+    checkConcept<Graph, HypercubeGraph>();
+  }
 }
 
@@ -355,47 +404,130 @@
 }
 
-// void checkGridGraph(const GridGraph& g, int w, int h) {
-//   check(g.width() == w, "Wrong width");
-//   check(g.height() == h, "Wrong height");
-
-//   for (int i = 0; i < w; ++i) {
-//     for (int j = 0; j < h; ++j) {
-//       check(g.col(g(i, j)) == i, "Wrong col");
-//       check(g.row(g(i, j)) == j, "Wrong row");
-//     }
-//   }
-
-//   for (int i = 0; i < w; ++i) {
-//     for (int j = 0; j < h - 1; ++j) {
-//       check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
-//       check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
-//     }
-//     check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
-//   }
-
-//   for (int i = 0; i < w; ++i) {
-//     for (int j = 1; j < h; ++j) {
-//       check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
-//       check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
-//     }
-//     check(g.up(g(i, 0)) == INVALID, "Wrong up");
-//   }
-
-//   for (int j = 0; j < h; ++j) {
-//     for (int i = 0; i < w - 1; ++i) {
-//       check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
-//       check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");
-//     }
-//     check(g.right(g(w - 1, j)) == INVALID, "Wrong right");
-//   }
-
-//   for (int j = 0; j < h; ++j) {
-//     for (int i = 1; i < w; ++i) {
-//       check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
-//       check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");
-//     }
-//     check(g.left(g(0, j)) == INVALID, "Wrong left");
-//   }
-// }
+void checkGridGraph(int width, int height) {
+  typedef GridGraph Graph;
+  GRAPH_TYPEDEFS(Graph);
+  Graph G(width, height);
+
+  check(G.width() == width, "Wrong column number");
+  check(G.height() == height, "Wrong row number");
+
+  for (int i = 0; i < width; ++i) {
+    for (int j = 0; j < height; ++j) {
+      check(G.col(G(i, j)) == i, "Wrong column");
+      check(G.row(G(i, j)) == j, "Wrong row");
+      check(G.pos(G(i, j)).x == i, "Wrong column");
+      check(G.pos(G(i, j)).y == j, "Wrong row");
+    }
+  }
+
+  for (int j = 0; j < height; ++j) {
+    for (int i = 0; i < width - 1; ++i) {
+      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
+      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
+    }
+    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
+  }
+
+  for (int j = 0; j < height; ++j) {
+    for (int i = 1; i < width; ++i) {
+      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
+      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
+    }
+    check(G.left(G(0, j)) == INVALID, "Wrong left");
+  }
+
+  for (int i = 0; i < width; ++i) {
+    for (int j = 0; j < height - 1; ++j) {
+      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
+      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
+    }
+    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
+  }
+
+  for (int i = 0; i < width; ++i) {
+    for (int j = 1; j < height; ++j) {
+      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
+      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
+    }
+    check(G.down(G(i, 0)) == INVALID, "Wrong down");
+  }
+
+  checkGraphNodeList(G, width * height);
+  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
+  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    int nb = 4;
+    if (G.col(n) == 0) --nb;
+    if (G.col(n) == width - 1) --nb;
+    if (G.row(n) == 0) --nb;
+    if (G.row(n) == height - 1) --nb;
+
+    checkGraphOutArcList(G, n, nb);
+    checkGraphInArcList(G, n, nb);
+    checkGraphIncEdgeList(G, n, nb);
+  }
+
+  checkArcDirections(G);
+
+  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
+  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+}
+
+void checkHypercubeGraph(int dim) {
+  GRAPH_TYPEDEFS(HypercubeGraph);
+
+  HypercubeGraph G(dim);
+  checkGraphNodeList(G, 1 << dim);
+  checkGraphEdgeList(G, dim * (1 << (dim-1)));
+  checkGraphArcList(G, dim * (1 << dim));
+
+  Node n = G.nodeFromId(dim);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphIncEdgeList(G, n, dim);
+    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
+      check( (G.u(e) == n &&
+              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
+             (G.v(e) == n &&
+              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
+             "Wrong edge or wrong dimension");
+    }
+
+    checkGraphOutArcList(G, n, dim);
+    for (OutArcIt a(G, n); a != INVALID; ++a) {
+      check(G.source(a) == n &&
+            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
+            "Wrong arc or wrong dimension");
+    }
+
+    checkGraphInArcList(G, n, dim);
+    for (InArcIt a(G, n); a != INVALID; ++a) {
+      check(G.target(a) == n &&
+            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
+            "Wrong arc or wrong dimension");
+    }
+  }
+
+  checkGraphConArcList(G, (1 << dim) * dim);
+  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+}
 
 void checkGraphs() {
@@ -412,15 +544,21 @@
     checkGraphValidity<SmartGraph>();
   }
-//   { // Checking FullGraph
-//     FullGraph g(5);
-//     checkGraphNodeList(g, 5);
-//     checkGraphEdgeList(g, 10);
-//   }
-//   { // Checking GridGraph
-//     GridGraph g(5, 6);
-//     checkGraphNodeList(g, 30);
-//     checkGraphEdgeList(g, 49);
-//     checkGridGraph(g, 5, 6);
-//   }
+  { // Checking FullGraph
+    checkFullGraph(7);
+    checkFullGraph(8);
+  }
+  { // Checking GridGraph
+    checkGridGraph(5, 8);
+    checkGridGraph(8, 5);
+    checkGridGraph(5, 5);
+    checkGridGraph(0, 0);
+    checkGridGraph(1, 1);
+  }
+  { // Checking HypercubeGraph
+    checkHypercubeGraph(1);
+    checkHypercubeGraph(2);
+    checkHypercubeGraph(3);
+    checkHypercubeGraph(4);
+  }
 }
 
Index: test/graph_test.h
===================================================================
--- test/graph_test.h	(revision 387)
+++ test/graph_test.h	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/graph_utils_test.cc
===================================================================
--- test/graph_utils_test.cc	(revision 324)
+++ test/graph_utils_test.cc	(revision 619)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -36,10 +36,9 @@
   {
     Digraph digraph;
-    typename Digraph::template NodeMap<int> nodes(digraph);
-    std::vector<Node> invNodes;
     for (int i = 0; i < 10; ++i) {
-      invNodes.push_back(digraph.addNode());
-      nodes[invNodes.back()]=invNodes.size()-1;
-    }
+      digraph.addNode();
+    }
+    RangeIdMap<Digraph, Node> nodes(digraph);
+    typename RangeIdMap<Digraph, Node>::InverseMap invNodes(nodes);
     for (int i = 0; i < 100; ++i) {
       int src = rnd[invNodes.size()];
@@ -48,4 +47,5 @@
     }
     typename Digraph::template ArcMap<bool> found(digraph, false);
+    RangeIdMap<Digraph, Arc> arcs(digraph);
     for (NodeIt src(digraph); src != INVALID; ++src) {
       for (NodeIt trg(digraph); trg != INVALID; ++trg) {
@@ -111,10 +111,9 @@
   TEMPLATE_GRAPH_TYPEDEFS(Graph);
   Graph graph;
-  typename Graph::template NodeMap<int> nodes(graph);
-  std::vector<Node> invNodes;
   for (int i = 0; i < 10; ++i) {
-    invNodes.push_back(graph.addNode());
-    nodes[invNodes.back()]=invNodes.size()-1;
-  }
+    graph.addNode();
+  }
+  RangeIdMap<Graph, Node> nodes(graph);
+  typename RangeIdMap<Graph, Node>::InverseMap invNodes(nodes);
   for (int i = 0; i < 100; ++i) {
     int src = rnd[invNodes.size()];
@@ -123,4 +122,5 @@
   }
   typename Graph::template EdgeMap<int> found(graph, 0);
+  RangeIdMap<Graph, Edge> edges(graph);
   for (NodeIt src(graph); src != INVALID; ++src) {
     for (NodeIt trg(graph); trg != INVALID; ++trg) {
Index: test/hao_orlin_test.cc
===================================================================
--- test/hao_orlin_test.cc	(revision 1081)
+++ test/hao_orlin_test.cc	(revision 1081)
@@ -0,0 +1,163 @@
+/* -*- 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 <sstream>
+
+#include <lemon/smart_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/hao_orlin.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace std;
+
+const std::string lgf =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@edges\n"
+  "     cap1 cap2 cap3\n"
+  "0 1  1    1    1   \n"
+  "0 2  2    2    4   \n"
+  "1 2  4    4    4   \n"
+  "3 4  1    1    1   \n"
+  "3 5  2    2    4   \n"
+  "4 5  4    4    4   \n"
+  "5 4  4    4    4   \n"
+  "2 3  1    6    6   \n"
+  "4 0  1    6    6   \n";
+
+void checkHaoOrlinCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc, Value> CapMap;
+  typedef concepts::WriteMap<Node, bool> CutMap;
+
+  Digraph g;
+  Node n;
+  CapMap cap;
+  CutMap cut;
+  Value v;
+
+  HaoOrlin<Digraph, CapMap> ho_test(g, cap);
+  const HaoOrlin<Digraph, CapMap>&
+    const_ho_test = ho_test;
+
+  ho_test.init();
+  ho_test.init(n);
+  ho_test.calculateOut();
+  ho_test.calculateIn();
+  ho_test.run();
+  ho_test.run(n);
+
+  v = const_ho_test.minCutValue();
+  v = const_ho_test.minCutMap(cut);
+}
+
+template <typename Graph, typename CapMap, typename CutMap>
+typename CapMap::Value
+  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
+{
+  typename CapMap::Value sum = 0;
+  for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
+    if (cut[graph.source(a)] && !cut[graph.target(a)])
+      sum += cap[a];
+  }
+  return sum;
+}
+
+int main() {
+  SmartDigraph graph;
+  SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
+  SmartDigraph::NodeMap<bool> cut(graph);
+
+  istringstream input(lgf);
+  digraphReader(graph, input)
+    .arcMap("cap1", cap1)
+    .arcMap("cap2", cap2)
+    .arcMap("cap3", cap3)
+    .run();
+
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap1);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap2);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap3);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
+  }
+
+  typedef Undirector<SmartDigraph> UGraph;
+  UGraph ugraph(graph);
+
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 2, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 5, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 5, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
+  }
+
+  return 0;
+}
Index: test/heap_test.cc
===================================================================
--- test/heap_test.cc	(revision 293)
+++ test/heap_test.cc	(revision 1081)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -32,4 +32,7 @@
 
 #include <lemon/bin_heap.h>
+#include <lemon/fib_heap.h>
+#include <lemon/radix_heap.h>
+#include <lemon/bucket_heap.h>
 
 #include "test_tools.h"
@@ -184,4 +187,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/kruskal_test.cc
===================================================================
--- test/kruskal_test.cc	(revision 209)
+++ test/kruskal_test.cc	(revision 628)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -100,14 +100,14 @@
         "Total cost should be 10");
 
-  edge_cost_map.set(e1, -10);
-  edge_cost_map.set(e2, -9);
-  edge_cost_map.set(e3, -8);
-  edge_cost_map.set(e4, -7);
-  edge_cost_map.set(e5, -6);
-  edge_cost_map.set(e6, -5);
-  edge_cost_map.set(e7, -4);
-  edge_cost_map.set(e8, -3);
-  edge_cost_map.set(e9, -2);
-  edge_cost_map.set(e10, -1);
+  edge_cost_map[e1] = -10;
+  edge_cost_map[e2] = -9;
+  edge_cost_map[e3] = -8;
+  edge_cost_map[e4] = -7;
+  edge_cost_map[e5] = -6;
+  edge_cost_map[e6] = -5;
+  edge_cost_map[e7] = -4;
+  edge_cost_map[e8] = -3;
+  edge_cost_map[e9] = -2;
+  edge_cost_map[e10] = -1;
 
   vector<Edge> tree_edge_vec(5);
Index: test/lp_test.cc
===================================================================
--- test/lp_test.cc	(revision 678)
+++ test/lp_test.cc	(revision 678)
@@ -0,0 +1,419 @@
+/* -*- 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 <sstream>
+#include <lemon/lp_skeleton.h>
+#include "test_tools.h"
+#include <lemon/tolerance.h>
+
+#include <lemon/config.h>
+
+#ifdef LEMON_HAVE_GLPK
+#include <lemon/glpk.h>
+#endif
+
+#ifdef LEMON_HAVE_CPLEX
+#include <lemon/cplex.h>
+#endif
+
+#ifdef LEMON_HAVE_SOPLEX
+#include <lemon/soplex.h>
+#endif
+
+#ifdef LEMON_HAVE_CLP
+#include <lemon/clp.h>
+#endif
+
+using namespace lemon;
+
+void lpTest(LpSolver& lp)
+{
+
+  typedef LpSolver LP;
+
+  std::vector<LP::Col> x(10);
+  //  for(int i=0;i<10;i++) x.push_back(lp.addCol());
+  lp.addColSet(x);
+  lp.colLowerBound(x,1);
+  lp.colUpperBound(x,1);
+  lp.colBounds(x,1,2);
+
+  std::vector<LP::Col> y(10);
+  lp.addColSet(y);
+
+  lp.colLowerBound(y,1);
+  lp.colUpperBound(y,1);
+  lp.colBounds(y,1,2);
+
+  std::map<int,LP::Col> z;
+
+  z.insert(std::make_pair(12,INVALID));
+  z.insert(std::make_pair(2,INVALID));
+  z.insert(std::make_pair(7,INVALID));
+  z.insert(std::make_pair(5,INVALID));
+
+  lp.addColSet(z);
+
+  lp.colLowerBound(z,1);
+  lp.colUpperBound(z,1);
+  lp.colBounds(z,1,2);
+
+  {
+    LP::Expr e,f,g;
+    LP::Col p1,p2,p3,p4,p5;
+    LP::Constr c;
+
+    p1=lp.addCol();
+    p2=lp.addCol();
+    p3=lp.addCol();
+    p4=lp.addCol();
+    p5=lp.addCol();
+
+    e[p1]=2;
+    *e=12;
+    e[p1]+=2;
+    *e+=12;
+    e[p1]-=2;
+    *e-=12;
+
+    e=2;
+    e=2.2;
+    e=p1;
+    e=f;
+
+    e+=2;
+    e+=2.2;
+    e+=p1;
+    e+=f;
+
+    e-=2;
+    e-=2.2;
+    e-=p1;
+    e-=f;
+
+    e*=2;
+    e*=2.2;
+    e/=2;
+    e/=2.2;
+
+    e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
+       (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
+       (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
+       2.2*f+f*2.2+f/2.2+
+       2*f+f*2+f/2+
+       2.2*p1+p1*2.2+p1/2.2+
+       2*p1+p1*2+p1/2
+       );
+
+
+    c = (e  <= f  );
+    c = (e  <= 2.2);
+    c = (e  <= 2  );
+    c = (e  <= p1 );
+    c = (2.2<= f  );
+    c = (2  <= f  );
+    c = (p1 <= f  );
+    c = (p1 <= p2 );
+    c = (p1 <= 2.2);
+    c = (p1 <= 2  );
+    c = (2.2<= p2 );
+    c = (2  <= p2 );
+
+    c = (e  >= f  );
+    c = (e  >= 2.2);
+    c = (e  >= 2  );
+    c = (e  >= p1 );
+    c = (2.2>= f  );
+    c = (2  >= f  );
+    c = (p1 >= f  );
+    c = (p1 >= p2 );
+    c = (p1 >= 2.2);
+    c = (p1 >= 2  );
+    c = (2.2>= p2 );
+    c = (2  >= p2 );
+
+    c = (e  == f  );
+    c = (e  == 2.2);
+    c = (e  == 2  );
+    c = (e  == p1 );
+    c = (2.2== f  );
+    c = (2  == f  );
+    c = (p1 == f  );
+    //c = (p1 == p2 );
+    c = (p1 == 2.2);
+    c = (p1 == 2  );
+    c = (2.2== p2 );
+    c = (2  == p2 );
+
+    c = ((2 <= e) <= 3);
+    c = ((2 <= p1) <= 3);
+
+    c = ((2 >= e) >= 3);
+    c = ((2 >= p1) >= 3);
+
+    e[x[3]]=2;
+    e[x[3]]=4;
+    e[x[3]]=1;
+    *e=12;
+
+    lp.addRow(-LP::INF,e,23);
+    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
+    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
+
+    lp.addRow(x[1]+x[3]<=x[5]-3);
+    lp.addRow((-7<=x[1]+x[3]-12)<=3);
+    lp.addRow(x[1]<=x[5]);
+
+    std::ostringstream buf;
+
+
+    e=((p1+p2)+(p1-0.99*p2));
+    //e.prettyPrint(std::cout);
+    //(e<=2).prettyPrint(std::cout);
+    double tolerance=0.001;
+    e.simplify(tolerance);
+    buf << "Coeff. of p2 should be 0.01";
+    check(e[p2]>0, buf.str());
+
+    tolerance=0.02;
+    e.simplify(tolerance);
+    buf << "Coeff. of p2 should be 0";
+    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
+
+    //Test for clone/new
+    LP* lpnew = lp.newSolver();
+    LP* lpclone = lp.cloneSolver();
+    delete lpnew;
+    delete lpclone;
+
+  }
+
+  {
+    LP::DualExpr e,f,g;
+    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
+      p4 = INVALID, p5 = INVALID;
+
+    e[p1]=2;
+    e[p1]+=2;
+    e[p1]-=2;
+
+    e=p1;
+    e=f;
+
+    e+=p1;
+    e+=f;
+
+    e-=p1;
+    e-=f;
+
+    e*=2;
+    e*=2.2;
+    e/=2;
+    e/=2.2;
+
+    e=((p1+p2)+(p1-p2)+
+       (p1+f)+(f+p1)+(f+g)+
+       (p1-f)+(f-p1)+(f-g)+
+       2.2*f+f*2.2+f/2.2+
+       2*f+f*2+f/2+
+       2.2*p1+p1*2.2+p1/2.2+
+       2*p1+p1*2+p1/2
+       );
+  }
+
+}
+
+void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
+                   double exp_opt) {
+  using std::string;
+  lp.solve();
+
+  std::ostringstream buf;
+  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
+
+  check(lp.primalType()==stat, buf.str());
+
+  if (stat ==  LpSolver::OPTIMAL) {
+    std::ostringstream sbuf;
+    sbuf << "Wrong optimal value (" << lp.primal() <<") with "
+         << lp.solverName() <<"\n     the right optimum is " << exp_opt;
+    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
+  }
+}
+
+void aTest(LpSolver & lp)
+{
+  typedef LpSolver LP;
+
+ //The following example is very simple
+
+  typedef LpSolver::Row Row;
+  typedef LpSolver::Col Col;
+
+
+  Col x1 = lp.addCol();
+  Col x2 = lp.addCol();
+
+
+  //Constraints
+  Row upright=lp.addRow(x1+2*x2 <=1);
+  lp.addRow(x1+x2 >=-1);
+  lp.addRow(x1-x2 <=1);
+  lp.addRow(x1-x2 >=-1);
+  //Nonnegativity of the variables
+  lp.colLowerBound(x1, 0);
+  lp.colLowerBound(x2, 0);
+  //Objective function
+  lp.obj(x1+x2);
+
+  lp.sense(lp.MAX);
+
+  //Testing the problem retrieving routines
+  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(lp.sense() == lp.MAX,"This is a maximization!");
+  check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
+  check(lp.colLowerBound(x1)==0,
+        "The lower bound for variable x1 should be 0.");
+  check(lp.colUpperBound(x1)==LpSolver::INF,
+        "The upper bound for variable x1 should be infty.");
+  check(lp.rowLowerBound(upright) == -LpSolver::INF,
+        "The lower bound for the first row should be -infty.");
+  check(lp.rowUpperBound(upright)==1,
+        "The upper bound for the first row should be 1.");
+  LpSolver::Expr e = lp.row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 2, "The second coefficient should 1.");
+
+  lp.row(upright, x1+x2 <=1);
+  e = lp.row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 1, "The second coefficient should 1.");
+
+  LpSolver::DualExpr de = lp.col(x1);
+  check(  de[upright] == 1, "The first coefficient should 1.");
+
+  LpSolver* clp = lp.cloneSolver();
+
+  //Testing the problem retrieving routines
+  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(clp->sense() == clp->MAX,"This is a maximization!");
+  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
+  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
+  check(clp->colLowerBound(x1)==0,
+        "The lower bound for variable x1 should be 0.");
+  check(clp->colUpperBound(x1)==LpSolver::INF,
+        "The upper bound for variable x1 should be infty.");
+
+  check(lp.rowLowerBound(upright)==-LpSolver::INF,
+        "The lower bound for the first row should be -infty.");
+  check(lp.rowUpperBound(upright)==1,
+        "The upper bound for the first row should be 1.");
+  e = clp->row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 1, "The second coefficient should 1.");
+
+  de = clp->col(x1);
+  check(de[upright] == 1, "The first coefficient should 1.");
+
+  delete clp;
+
+  //Maximization of x1+x2
+  //over the triangle with vertices (0,0) (0,1) (1,0)
+  double expected_opt=1;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Minimization
+  lp.sense(lp.MIN);
+  expected_opt=0;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Vertex (-1,0) instead of (0,0)
+  lp.colLowerBound(x1, -LpSolver::INF);
+  expected_opt=-1;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Erase one constraint and return to maximization
+  lp.erase(upright);
+  lp.sense(lp.MAX);
+  expected_opt=LpSolver::INF;
+  solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
+
+  //Infeasibilty
+  lp.addRow(x1+x2 <=-2);
+  solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
+
+}
+
+template<class LP>
+void cloneTest()
+{
+  //Test for clone/new
+
+  LP* lp = new LP();
+  LP* lpnew = lp->newSolver();
+  LP* lpclone = lp->cloneSolver();
+  delete lp;
+  delete lpnew;
+  delete lpclone;
+}
+
+int main()
+{
+  LpSkeleton lp_skel;
+  lpTest(lp_skel);
+
+#ifdef LEMON_HAVE_GLPK
+  {
+    GlpkLp lp_glpk1,lp_glpk2;
+    lpTest(lp_glpk1);
+    aTest(lp_glpk2);
+    cloneTest<GlpkLp>();
+  }
+#endif
+
+#ifdef LEMON_HAVE_CPLEX
+  try {
+    CplexLp lp_cplex1,lp_cplex2;
+    lpTest(lp_cplex1);
+    aTest(lp_cplex2);
+    cloneTest<CplexLp>();
+  } catch (CplexEnv::LicenseError& error) {
+    check(false, error.what());
+  }
+#endif
+
+#ifdef LEMON_HAVE_SOPLEX
+  {
+    SoplexLp lp_soplex1,lp_soplex2;
+    lpTest(lp_soplex1);
+    aTest(lp_soplex2);
+    cloneTest<SoplexLp>();
+  }
+#endif
+
+#ifdef LEMON_HAVE_CLP
+  {
+    ClpLp lp_clp1,lp_clp2;
+    lpTest(lp_clp1);
+    aTest(lp_clp2);
+    cloneTest<ClpLp>();
+  }
+#endif
+
+  return 0;
+}
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 1078)
+++ test/maps_test.cc	(revision 1081)
@@ -23,4 +23,5 @@
 #include <lemon/concepts/maps.h>
 #include <lemon/maps.h>
+#include <lemon/list_graph.h>
 
 #include "test_tools.h"
@@ -353,4 +354,38 @@
   }
 
+  // CrossRefMap
+  {
+    typedef ListDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadWriteMap<Node, int>,
+                 CrossRefMap<Graph, Node, int> >();
+
+    Graph gr;
+    typedef CrossRefMap<Graph, Node, char> CRMap;
+    typedef CRMap::ValueIterator ValueIt;
+    CRMap map(gr);
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    map.set(n0, 'A');
+    map.set(n1, 'B');
+    map.set(n2, 'C');
+    map.set(n2, 'A');
+    map.set(n0, 'C');
+
+    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
+          "Wrong CrossRefMap");
+    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
+    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
+    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
+
+    ValueIt it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
+          it == map.endValue(), "Wrong value iterator");
+  }
+
   return 0;
 }
Index: test/matching_test.cc
===================================================================
--- test/matching_test.cc	(revision 1081)
+++ test/matching_test.cc	(revision 1081)
@@ -0,0 +1,424 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <queue>
+#include <cstdlib>
+
+#include <lemon/matching.h>
+#include <lemon/smart_graph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+GRAPH_TYPEDEFS(SmartGraph);
+
+
+const int lgfn = 3;
+const std::string lgf[lgfn] = {
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "7 4  0      984\n"
+  "0 7  1      73\n"
+  "7 1  2      204\n"
+  "2 3  3      583\n"
+  "2 7  4      565\n"
+  "2 1  5      582\n"
+  "0 4  6      551\n"
+  "2 5  7      385\n"
+  "1 5  8      561\n"
+  "5 3  9      484\n"
+  "7 5  10     904\n"
+  "3 6  11     47\n"
+  "7 6  12     888\n"
+  "3 0  13     747\n"
+  "6 1  14     310\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "2 5  0      710\n"
+  "0 5  1      241\n"
+  "2 4  2      856\n"
+  "2 6  3      762\n"
+  "4 1  4      747\n"
+  "6 1  5      962\n"
+  "4 7  6      723\n"
+  "1 7  7      661\n"
+  "2 3  8      376\n"
+  "1 0  9      416\n"
+  "6 7  10     391\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "6 2  0      553\n"
+  "0 7  1      653\n"
+  "6 3  2      22\n"
+  "4 7  3      846\n"
+  "7 2  4      981\n"
+  "7 6  5      250\n"
+  "5 2  6      539\n",
+};
+
+void checkMaxMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<bool> MatMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  MatMap mat(g);
+
+  MaxMatching<Graph> mat_test(g);
+  const MaxMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.greedyInit();
+  mat_test.matchingInit(mat);
+  mat_test.startSparse();
+  mat_test.startDense();
+  mat_test.run();
+
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  MaxMatching<Graph>::Status stat =
+    const_mat_test.status(n);
+  const MaxMatching<Graph>::StatusMap& smap =
+    const_mat_test.statusMap();
+  stat = smap[n];
+  const_mat_test.barrier(n);
+}
+
+void checkMaxWeightedMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedMatching<Graph> mat_test(g, w);
+  const MaxWeightedMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  int k = 0;
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+  const_mat_test.blossomNum();
+  const_mat_test.blossomSize(k);
+  const_mat_test.blossomValue(k);
+}
+
+void checkMaxWeightedPerfectMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
+  const MaxWeightedPerfectMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  int k = 0;
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+  const_mat_test.blossomNum();
+  const_mat_test.blossomSize(k);
+  const_mat_test.blossomValue(k);
+}
+
+void checkMatching(const SmartGraph& graph,
+                   const MaxMatching<SmartGraph>& mm) {
+  int num = 0;
+
+  IntNodeMap comp_index(graph);
+  UnionFind<IntNodeMap> comp(comp_index);
+
+  int barrier_num = 0;
+
+  for (NodeIt n(graph); n != INVALID; ++n) {
+    check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
+          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
+    if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
+      ++barrier_num;
+    } else {
+      comp.insert(n);
+    }
+  }
+
+  for (EdgeIt e(graph); e != INVALID; ++e) {
+    if (mm.matching(e)) {
+      check(e == mm.matching(graph.u(e)), "Wrong matching");
+      check(e == mm.matching(graph.v(e)), "Wrong matching");
+      ++num;
+    }
+    check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
+          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
+          "Wrong Gallai-Edmonds decomposition");
+
+    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
+          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
+          "Wrong Gallai-Edmonds decomposition");
+
+    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
+        mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
+      comp.join(graph.u(e), graph.v(e));
+    }
+  }
+
+  std::set<int> comp_root;
+  int odd_comp_num = 0;
+  for (NodeIt n(graph); n != INVALID; ++n) {
+    if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
+      int root = comp.find(n);
+      if (comp_root.find(root) == comp_root.end()) {
+        comp_root.insert(root);
+        if (comp.size(n) % 2 == 1) {
+          ++odd_comp_num;
+        }
+      }
+    }
+  }
+
+  check(mm.matchingSize() == num, "Wrong matching");
+  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
+         "Wrong matching");
+  return;
+}
+
+void checkWeightedMatching(const SmartGraph& graph,
+                   const SmartGraph::EdgeMap<int>& weight,
+                   const MaxWeightedMatching<SmartGraph>& mwm) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e)) continue;
+    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
+
+    for (int i = 0; i < mwm.blossomNum(); ++i) {
+      bool s = false, t = false;
+      for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
+           n != INVALID; ++n) {
+        if (graph.u(e) == n) s = true;
+        if (graph.v(e) == n) t = true;
+      }
+      if (s == true && t == true) {
+        rw += mwm.blossomValue(i);
+      }
+    }
+    rw -= weight[e] * mwm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (mwm.matching(n) != INVALID) {
+      check(mwm.nodeValue(n) >= 0, "Invalid node value");
+      pv += weight[mwm.matching(n)];
+      SmartGraph::Node o = graph.target(mwm.matching(n));
+      check(mwm.mate(n) == o, "Invalid matching");
+      check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
+            "Invalid matching");
+    } else {
+      check(mwm.mate(n) == INVALID, "Invalid matching");
+      check(mwm.nodeValue(n) == 0, "Invalid matching");
+    }
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwm.nodeValue(n);
+  }
+
+  for (int i = 0; i < mwm.blossomNum(); ++i) {
+    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
+    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
+    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
+  }
+
+  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
+
+  return;
+}
+
+void checkWeightedPerfectMatching(const SmartGraph& graph,
+                          const SmartGraph::EdgeMap<int>& weight,
+                          const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e)) continue;
+    int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
+
+    for (int i = 0; i < mwpm.blossomNum(); ++i) {
+      bool s = false, t = false;
+      for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
+           n != INVALID; ++n) {
+        if (graph.u(e) == n) s = true;
+        if (graph.v(e) == n) t = true;
+      }
+      if (s == true && t == true) {
+        rw += mwpm.blossomValue(i);
+      }
+    }
+    rw -= weight[e] * mwpm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwpm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    check(mwpm.matching(n) != INVALID, "Non perfect");
+    pv += weight[mwpm.matching(n)];
+    SmartGraph::Node o = graph.target(mwpm.matching(n));
+    check(mwpm.mate(n) == o, "Invalid matching");
+    check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
+          "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwpm.nodeValue(n);
+  }
+
+  for (int i = 0; i < mwpm.blossomNum(); ++i) {
+    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
+    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
+    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
+  }
+
+  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
+
+  return;
+}
+
+
+int main() {
+
+  for (int i = 0; i < lgfn; ++i) {
+    SmartGraph graph;
+    SmartGraph::EdgeMap<int> weight(graph);
+
+    istringstream lgfs(lgf[i]);
+    graphReader(graph, lgfs).
+      edgeMap("weight", weight).run();
+
+    MaxMatching<SmartGraph> mm(graph);
+    mm.run();
+    checkMatching(graph, mm);
+
+    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
+    mwm.run();
+    checkWeightedMatching(graph, weight, mwm);
+
+    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
+    bool perfect = mwpm.run();
+
+    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
+          "Perfect matching found");
+
+    if (perfect) {
+      checkWeightedPerfectMatching(graph, weight, mwpm);
+    }
+  }
+
+  return 0;
+}
Index: test/min_cost_arborescence_test.cc
===================================================================
--- test/min_cost_arborescence_test.cc	(revision 1081)
+++ test/min_cost_arborescence_test.cc	(revision 1081)
@@ -0,0 +1,206 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <set>
+#include <vector>
+#include <iterator>
+
+#include <lemon/smart_graph.h>
+#include <lemon/min_cost_arborescence.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/concepts/digraph.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace std;
+
+const char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "     label  cost\n"
+  "1 8  0      107\n"
+  "0 3  1      70\n"
+  "2 1  2      46\n"
+  "4 1  3      28\n"
+  "4 4  4      91\n"
+  "3 9  5      76\n"
+  "9 8  6      61\n"
+  "8 1  7      39\n"
+  "9 8  8      74\n"
+  "8 0  9      39\n"
+  "4 3  10     45\n"
+  "2 2  11     34\n"
+  "0 1  12     100\n"
+  "6 3  13     95\n"
+  "4 1  14     22\n"
+  "1 1  15     31\n"
+  "7 2  16     51\n"
+  "2 6  17     29\n"
+  "8 3  18     115\n"
+  "6 9  19     32\n"
+  "1 1  20     60\n"
+  "0 3  21     40\n"
+  "@attributes\n"
+  "source 0\n";
+
+
+void checkMinCostArborescenceCompile()
+{
+  typedef double VType;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
+  typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
+
+  typedef MinCostArborescence<Digraph, CostMap>::
+            SetArborescenceMap<ArbMap>::
+            SetPredMap<PredMap>::Create MinCostArbType;
+
+  Digraph g;
+  Node s, n;
+  Arc e;
+  VType c;
+  bool b;
+  int i;
+  CostMap cost;
+  ArbMap arb;
+  PredMap pred;
+
+  MinCostArbType mcarb_test(g, cost);
+  const MinCostArbType& const_mcarb_test = mcarb_test;
+
+  mcarb_test
+    .arborescenceMap(arb)
+    .predMap(pred)
+    .run(s);
+
+  mcarb_test.init();
+  mcarb_test.addSource(s);
+  mcarb_test.start();
+  n = mcarb_test.processNextNode();
+  b = const_mcarb_test.emptyQueue();
+  i = const_mcarb_test.queueSize();
+
+  c = const_mcarb_test.arborescenceCost();
+  b = const_mcarb_test.arborescence(e);
+  e = const_mcarb_test.pred(n);
+  const MinCostArbType::ArborescenceMap &am =
+    const_mcarb_test.arborescenceMap();
+  const MinCostArbType::PredMap &pm =
+    const_mcarb_test.predMap();
+  b = const_mcarb_test.reached(n);
+  b = const_mcarb_test.processed(n);
+
+  i = const_mcarb_test.dualNum();
+  c = const_mcarb_test.dualValue();
+  i = const_mcarb_test.dualSize(i);
+  c = const_mcarb_test.dualValue(i);
+
+  ignore_unused_variable_warning(am);
+  ignore_unused_variable_warning(pm);
+}
+
+int main() {
+  typedef SmartDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+
+  typedef Digraph::ArcMap<double> CostMap;
+
+  Digraph digraph;
+  CostMap cost(digraph);
+  Node source;
+
+  std::istringstream is(test_lgf);
+  digraphReader(digraph, is).
+    arcMap("cost", cost).
+    node("source", source).run();
+
+  MinCostArborescence<Digraph, CostMap> mca(digraph, cost);
+  mca.run(source);
+
+  vector<pair<double, set<Node> > > dualSolution(mca.dualNum());
+
+  for (int i = 0; i < mca.dualNum(); ++i) {
+    dualSolution[i].first = mca.dualValue(i);
+    for (MinCostArborescence<Digraph, CostMap>::DualIt it(mca, i);
+         it != INVALID; ++it) {
+      dualSolution[i].second.insert(it);
+    }
+  }
+
+  for (ArcIt it(digraph); it != INVALID; ++it) {
+    if (mca.reached(digraph.source(it))) {
+      double sum = 0.0;
+      for (int i = 0; i < int(dualSolution.size()); ++i) {
+        if (dualSolution[i].second.find(digraph.target(it))
+            != dualSolution[i].second.end() &&
+            dualSolution[i].second.find(digraph.source(it))
+            == dualSolution[i].second.end()) {
+          sum += dualSolution[i].first;
+        }
+      }
+      if (mca.arborescence(it)) {
+        check(sum == cost[it], "Invalid dual solution");
+      }
+      check(sum <= cost[it], "Invalid dual solution");
+    }
+  }
+
+
+  check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
+
+  check(mca.reached(source), "Invalid arborescence");
+  for (ArcIt a(digraph); a != INVALID; ++a) {
+    check(!mca.reached(digraph.source(a)) ||
+          mca.reached(digraph.target(a)), "Invalid arborescence");
+  }
+
+  for (NodeIt n(digraph); n != INVALID; ++n) {
+    if (!mca.reached(n)) continue;
+    int cnt = 0;
+    for (InArcIt a(digraph, n); a != INVALID; ++a) {
+      if (mca.arborescence(a)) {
+        check(mca.pred(n) == a, "Invalid arborescence");
+        ++cnt;
+      }
+    }
+    check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
+  }
+
+  Digraph::ArcMap<bool> arborescence(digraph);
+  check(mca.arborescenceCost() ==
+        minCostArborescence(digraph, cost, source, arborescence),
+        "Wrong result of the function interface");
+
+  return 0;
+}
Index: test/min_cost_flow_test.cc
===================================================================
--- test/min_cost_flow_test.cc	(revision 1081)
+++ test/min_cost_flow_test.cc	(revision 1081)
@@ -0,0 +1,450 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <limits>
+
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+
+#include <lemon/network_simplex.h>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concept_check.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
+  "    1    20   27    0   30   20   30\n"
+  "    2    -4    0    0    0   -8   -3\n"
+  "    3     0    0    0    0    0    0\n"
+  "    4     0    0    0    0    0    0\n"
+  "    5     9    0    0    0    6   11\n"
+  "    6    -6    0    0    0   -5   -6\n"
+  "    7     0    0    0    0    0    0\n"
+  "    8     0    0    0    0    0    3\n"
+  "    9     3    0    0    0    0    0\n"
+  "   10    -2    0    0    0   -7   -2\n"
+  "   11     0    0    0    0  -10    0\n"
+  "   12   -20  -27    0  -30  -30  -20\n"
+  "\n"
+  "@arcs\n"
+  "       cost  cap low1 low2 low3\n"
+  " 1  2    70   11    0    8    8\n"
+  " 1  3   150    3    0    1    0\n"
+  " 1  4    80   15    0    2    2\n"
+  " 2  8    80   12    0    0    0\n"
+  " 3  5   140    5    0    3    1\n"
+  " 4  6    60   10    0    1    0\n"
+  " 4  7    80    2    0    0    0\n"
+  " 4  8   110    3    0    0    0\n"
+  " 5  7    60   14    0    0    0\n"
+  " 5 11   120   12    0    0    0\n"
+  " 6  3     0    3    0    0    0\n"
+  " 6  9   140    4    0    0    0\n"
+  " 6 10    90    8    0    0    0\n"
+  " 7  1    30    5    0    0   -5\n"
+  " 8 12    60   16    0    4    3\n"
+  " 9 12    50    6    0    0    0\n"
+  "10 12    70   13    0    5    2\n"
+  "10  2   100    7    0    0    0\n"
+  "10  7    60   10    0    0   -3\n"
+  "11 10    20   14    0    6  -20\n"
+  "12 11    30   10    0    0  -10\n"
+  "\n"
+  "@attributes\n"
+  "source 1\n"
+  "target 12\n";
+
+
+enum SupplyType {
+  EQ,
+  GEQ,
+  LEQ
+};
+
+// Check the interface of an MCF algorithm
+template <typename GR, typename Value, typename Cost>
+class McfClassConcept
+{
+public:
+
+  template <typename MCF>
+  struct Constraints {
+    void constraints() {
+      checkConcept<concepts::Digraph, GR>();
+
+      const Constraints& me = *this;
+
+      MCF mcf(me.g);
+      const MCF& const_mcf = mcf;
+
+      b = mcf.reset()
+             .lowerMap(me.lower)
+             .upperMap(me.upper)
+             .costMap(me.cost)
+             .supplyMap(me.sup)
+             .stSupply(me.n, me.n, me.k)
+             .run();
+
+      c = const_mcf.totalCost();
+      x = const_mcf.template totalCost<double>();
+      v = const_mcf.flow(me.a);
+      c = const_mcf.potential(me.n);
+      const_mcf.flowMap(fm);
+      const_mcf.potentialMap(pm);
+    }
+
+    typedef typename GR::Node Node;
+    typedef typename GR::Arc Arc;
+    typedef concepts::ReadMap<Node, Value> NM;
+    typedef concepts::ReadMap<Arc, Value> VAM;
+    typedef concepts::ReadMap<Arc, Cost> CAM;
+    typedef concepts::WriteMap<Arc, Value> FlowMap;
+    typedef concepts::WriteMap<Node, Cost> PotMap;
+
+    GR g;
+    VAM lower;
+    VAM upper;
+    CAM cost;
+    NM sup;
+    Node n;
+    Arc a;
+    Value k;
+
+    FlowMap fm;
+    PotMap pm;
+    bool b;
+    double x;
+    typename MCF::Value v;
+    typename MCF::Cost c;
+  };
+
+};
+
+
+// Check the feasibility of the given flow (primal soluiton)
+template < typename GR, typename LM, typename UM,
+           typename SM, typename FM >
+bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
+                const SM& supply, const FM& flow,
+                SupplyType type = EQ )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  for (ArcIt e(gr); e != INVALID; ++e) {
+    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
+  }
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    typename SM::Value sum = 0;
+    for (OutArcIt e(gr, n); e != INVALID; ++e)
+      sum += flow[e];
+    for (InArcIt e(gr, n); e != INVALID; ++e)
+      sum -= flow[e];
+    bool b = (type ==  EQ && sum == supply[n]) ||
+             (type == GEQ && sum >= supply[n]) ||
+             (type == LEQ && sum <= supply[n]);
+    if (!b) return false;
+  }
+
+  return true;
+}
+
+// Check the feasibility of the given potentials (dual soluiton)
+// using the "Complementary Slackness" optimality condition
+template < typename GR, typename LM, typename UM,
+           typename CM, typename SM, typename FM, typename PM >
+bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
+                     const CM& cost, const SM& supply, const FM& flow,
+                     const PM& pi, SupplyType type )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  bool opt = true;
+  for (ArcIt e(gr); opt && e != INVALID; ++e) {
+    typename CM::Value red_cost =
+      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
+    opt = red_cost == 0 ||
+          (red_cost > 0 && flow[e] == lower[e]) ||
+          (red_cost < 0 && flow[e] == upper[e]);
+  }
+
+  for (NodeIt n(gr); opt && n != INVALID; ++n) {
+    typename SM::Value sum = 0;
+    for (OutArcIt e(gr, n); e != INVALID; ++e)
+      sum += flow[e];
+    for (InArcIt e(gr, n); e != INVALID; ++e)
+      sum -= flow[e];
+    if (type != LEQ) {
+      opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
+    } else {
+      opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
+    }
+  }
+
+  return opt;
+}
+
+// Check whether the dual cost is equal to the primal cost
+template < typename GR, typename LM, typename UM,
+           typename CM, typename SM, typename PM >
+bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
+                    const CM& cost, const SM& supply, const PM& pi,
+                    typename CM::Value total )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  typename CM::Value dual_cost = 0;
+  SM red_supply(gr);
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    red_supply[n] = supply[n];
+  }
+  for (ArcIt a(gr); a != INVALID; ++a) {
+    if (lower[a] != 0) {
+      dual_cost += lower[a] * cost[a];
+      red_supply[gr.source(a)] -= lower[a];
+      red_supply[gr.target(a)] += lower[a];
+    }
+  }
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    dual_cost -= red_supply[n] * pi[n];
+  }
+  for (ArcIt a(gr); a != INVALID; ++a) {
+    typename CM::Value red_cost =
+      cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
+    dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
+  }
+
+  return dual_cost == total;
+}
+
+// Run a minimum cost flow algorithm and check the results
+template < typename MCF, typename GR,
+           typename LM, typename UM,
+           typename CM, typename SM,
+           typename PT >
+void checkMcf( const MCF& mcf, PT mcf_result,
+               const GR& gr, const LM& lower, const UM& upper,
+               const CM& cost, const SM& supply,
+               PT result, bool optimal, typename CM::Value total,
+               const std::string &test_id = "",
+               SupplyType type = EQ )
+{
+  check(mcf_result == result, "Wrong result " + test_id);
+  if (optimal) {
+    typename GR::template ArcMap<typename SM::Value> flow(gr);
+    typename GR::template NodeMap<typename CM::Value> pi(gr);
+    mcf.flowMap(flow);
+    mcf.potentialMap(pi);
+    check(checkFlow(gr, lower, upper, supply, flow, type),
+          "The flow is not feasible " + test_id);
+    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
+    check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
+          "Wrong potentials " + test_id);
+    check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
+          "Wrong dual cost " + test_id);
+  }
+}
+
+int main()
+{
+  // Check the interfaces
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  NetworkSimplex<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  NetworkSimplex<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  NetworkSimplex<GR, int, double> >();
+  }
+
+  // Run various MCF tests
+  typedef ListDigraph Digraph;
+  DIGRAPH_TYPEDEFS(ListDigraph);
+
+  // Read the test digraph
+  Digraph gr;
+  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
+  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
+  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
+  Node v, w;
+
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(gr, input)
+    .arcMap("cost", c)
+    .arcMap("cap", u)
+    .arcMap("low1", l1)
+    .arcMap("low2", l2)
+    .arcMap("low3", l3)
+    .nodeMap("sup1", s1)
+    .nodeMap("sup2", s2)
+    .nodeMap("sup3", s3)
+    .nodeMap("sup4", s4)
+    .nodeMap("sup5", s5)
+    .nodeMap("sup6", s6)
+    .node("source", v)
+    .node("target", w)
+    .run();
+
+  // Build test digraphs with negative costs
+  Digraph neg_gr;
+  Node n1 = neg_gr.addNode();
+  Node n2 = neg_gr.addNode();
+  Node n3 = neg_gr.addNode();
+  Node n4 = neg_gr.addNode();
+  Node n5 = neg_gr.addNode();
+  Node n6 = neg_gr.addNode();
+  Node n7 = neg_gr.addNode();
+
+  Arc a1 = neg_gr.addArc(n1, n2);
+  Arc a2 = neg_gr.addArc(n1, n3);
+  Arc a3 = neg_gr.addArc(n2, n4);
+  Arc a4 = neg_gr.addArc(n3, n4);
+  Arc a5 = neg_gr.addArc(n3, n2);
+  Arc a6 = neg_gr.addArc(n5, n3);
+  Arc a7 = neg_gr.addArc(n5, n6);
+  Arc a8 = neg_gr.addArc(n6, n7);
+  Arc a9 = neg_gr.addArc(n7, n5);
+
+  Digraph::ArcMap<int> neg_c(neg_gr), neg_l1(neg_gr, 0), neg_l2(neg_gr, 0);
+  ConstMap<Arc, int> neg_u1(std::numeric_limits<int>::max()), neg_u2(5000);
+  Digraph::NodeMap<int> neg_s(neg_gr, 0);
+
+  neg_l2[a7] =  1000;
+  neg_l2[a8] = -1000;
+
+  neg_s[n1] =  100;
+  neg_s[n4] = -100;
+
+  neg_c[a1] =  100;
+  neg_c[a2] =   30;
+  neg_c[a3] =   20;
+  neg_c[a4] =   80;
+  neg_c[a5] =   50;
+  neg_c[a6] =   10;
+  neg_c[a7] =   80;
+  neg_c[a8] =   30;
+  neg_c[a9] = -120;
+
+  Digraph negs_gr;
+  Digraph::NodeMap<int> negs_s(negs_gr);
+  Digraph::ArcMap<int> negs_c(negs_gr);
+  ConstMap<Arc, int> negs_l(0), negs_u(1000);
+  n1 = negs_gr.addNode();
+  n2 = negs_gr.addNode();
+  negs_s[n1] = 100;
+  negs_s[n2] = -300;
+  negs_c[negs_gr.addArc(n1, n2)] = -1;
+
+
+  // A. Test NetworkSimplex with the default pivot rule
+  {
+    NetworkSimplex<Digraph> mcf(gr);
+
+    // Check the equality form
+    mcf.upperMap(u).costMap(c);
+    checkMcf(mcf, mcf.supplyMap(s1).run(),
+             gr, l1, u, c, s1, mcf.OPTIMAL, true,   5240, "#A1");
+    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
+             gr, l1, u, c, s2, mcf.OPTIMAL, true,   7620, "#A2");
+    mcf.lowerMap(l2);
+    checkMcf(mcf, mcf.supplyMap(s1).run(),
+             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#A3");
+    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
+             gr, l2, u, c, s2, mcf.OPTIMAL, true,   8010, "#A4");
+    mcf.reset();
+    checkMcf(mcf, mcf.supplyMap(s1).run(),
+             gr, l1, cu, cc, s1, mcf.OPTIMAL, true,   74, "#A5");
+    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
+             gr, l2, cu, cc, s2, mcf.OPTIMAL, true,   94, "#A6");
+    mcf.reset();
+    checkMcf(mcf, mcf.run(),
+             gr, l1, cu, cc, s3, mcf.OPTIMAL, true,    0, "#A7");
+    checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
+             gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
+    mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
+    checkMcf(mcf, mcf.run(),
+             gr, l3, u, c, s4, mcf.OPTIMAL, true,   6360, "#A9");
+
+    // Check the GEQ form
+    mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
+    checkMcf(mcf, mcf.run(),
+             gr, l1, u, c, s5, mcf.OPTIMAL, true,   3530, "#A10", GEQ);
+    mcf.supplyType(mcf.GEQ);
+    checkMcf(mcf, mcf.lowerMap(l2).run(),
+             gr, l2, u, c, s5, mcf.OPTIMAL, true,   4540, "#A11", GEQ);
+    mcf.supplyMap(s6);
+    checkMcf(mcf, mcf.run(),
+             gr, l2, u, c, s6, mcf.INFEASIBLE, false,  0, "#A12", GEQ);
+
+    // Check the LEQ form
+    mcf.reset().supplyType(mcf.LEQ);
+    mcf.upperMap(u).costMap(c).supplyMap(s6);
+    checkMcf(mcf, mcf.run(),
+             gr, l1, u, c, s6, mcf.OPTIMAL, true,   5080, "#A13", LEQ);
+    checkMcf(mcf, mcf.lowerMap(l2).run(),
+             gr, l2, u, c, s6, mcf.OPTIMAL, true,   5930, "#A14", LEQ);
+    mcf.supplyMap(s5);
+    checkMcf(mcf, mcf.run(),
+             gr, l2, u, c, s5, mcf.INFEASIBLE, false,  0, "#A15", LEQ);
+
+    // Check negative costs
+    NetworkSimplex<Digraph> neg_mcf(neg_gr);
+    neg_mcf.lowerMap(neg_l1).costMap(neg_c).supplyMap(neg_s);
+    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u1,
+      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A16");
+    neg_mcf.upperMap(neg_u2);
+    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u2,
+      neg_c, neg_s, neg_mcf.OPTIMAL, true,  -40000, "#A17");
+    neg_mcf.reset().lowerMap(neg_l2).costMap(neg_c).supplyMap(neg_s);
+    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l2, neg_u1,
+      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A18");
+
+    NetworkSimplex<Digraph> negs_mcf(negs_gr);
+    negs_mcf.costMap(negs_c).supplyMap(negs_s);
+    checkMcf(negs_mcf, negs_mcf.run(), negs_gr, negs_l, negs_u,
+      negs_c, negs_s, negs_mcf.OPTIMAL, true, -300, "#A19", GEQ);
+  }
+
+  // B. Test NetworkSimplex with each pivot rule
+  {
+    NetworkSimplex<Digraph> mcf(gr);
+    mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
+
+    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
+             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B1");
+    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
+             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B2");
+    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
+             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B3");
+    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
+             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B4");
+    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
+             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B5");
+  }
+
+  return 0;
+}
Index: test/mip_test.cc
===================================================================
--- test/mip_test.cc	(revision 795)
+++ test/mip_test.cc	(revision 795)
@@ -0,0 +1,159 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include "test_tools.h"
+
+#include <lemon/config.h>
+
+#ifdef LEMON_HAVE_CPLEX
+#include <lemon/cplex.h>
+#endif
+
+#ifdef LEMON_HAVE_GLPK
+#include <lemon/glpk.h>
+#endif
+
+#ifdef LEMON_HAVE_CBC
+#include <lemon/cbc.h>
+#endif
+
+
+using namespace lemon;
+
+void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
+                   double exp_opt) {
+  using std::string;
+
+  mip.solve();
+  //int decimal,sign;
+  std::ostringstream buf;
+  buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
+
+
+  //  itoa(stat,buf1, 10);
+  check(mip.type()==stat, buf.str());
+
+  if (stat ==  MipSolver::OPTIMAL) {
+    std::ostringstream sbuf;
+    sbuf << "Wrong optimal value ("<< mip.solValue()
+         <<" instead of " << exp_opt << ")";
+    check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
+    //+ecvt(exp_opt,2)
+  }
+}
+
+void aTest(MipSolver& mip)
+{
+  //The following example is very simple
+
+
+  typedef MipSolver::Row Row;
+  typedef MipSolver::Col Col;
+
+
+  Col x1 = mip.addCol();
+  Col x2 = mip.addCol();
+
+
+  //Objective function
+  mip.obj(x1);
+
+  mip.max();
+
+  //Unconstrained optimization
+  mip.solve();
+  //Check it out!
+
+  //Constraints
+  mip.addRow(2 * x1 + x2 <= 2);
+  Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
+
+  //Nonnegativity of the variable x1
+  mip.colLowerBound(x1, 0);
+
+
+  //Maximization of x1
+  //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
+  double expected_opt=4.0/5.0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+
+  //Restrict x2 to integer
+  mip.colType(x2,MipSolver::INTEGER);
+  expected_opt=1.0/2.0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+
+  //Restrict both to integer
+  mip.colType(x1,MipSolver::INTEGER);
+  expected_opt=0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+  //Erase a variable
+  mip.erase(x2);
+  mip.rowUpperBound(y2, 8);
+  expected_opt=1;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+}
+
+
+template<class MIP>
+void cloneTest()
+{
+
+  MIP* mip = new MIP();
+  MIP* mipnew = mip->newSolver();
+  MIP* mipclone = mip->cloneSolver();
+  delete mip;
+  delete mipnew;
+  delete mipclone;
+}
+
+int main()
+{
+
+#ifdef LEMON_HAVE_GLPK
+  {
+    GlpkMip mip1;
+    aTest(mip1);
+    cloneTest<GlpkMip>();
+  }
+#endif
+
+#ifdef LEMON_HAVE_CPLEX
+  try {
+    CplexMip mip2;
+    aTest(mip2);
+    cloneTest<CplexMip>();
+  } catch (CplexEnv::LicenseError& error) {
+    check(false, error.what());
+  }
+#endif
+
+#ifdef LEMON_HAVE_CBC
+  {
+    CbcMip mip1;
+    aTest(mip1);
+    cloneTest<CbcMip>();
+  }
+#endif
+
+  return 0;
+
+}
Index: test/path_test.cc
===================================================================
--- test/path_test.cc	(revision 209)
+++ test/path_test.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/preflow_test.cc
===================================================================
--- test/preflow_test.cc	(revision 1081)
+++ test/preflow_test.cc	(revision 1081)
@@ -0,0 +1,271 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/preflow.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/elevator.h>
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "    label capacity\n"
+  "0 1 0     20\n"
+  "0 2 1     0\n"
+  "1 1 2     3\n"
+  "1 2 3     8\n"
+  "1 3 4     8\n"
+  "2 5 5     5\n"
+  "3 2 6     5\n"
+  "3 5 7     5\n"
+  "3 6 8     5\n"
+  "4 3 9     3\n"
+  "5 7 10    3\n"
+  "5 6 11    10\n"
+  "5 8 12    10\n"
+  "6 8 13    8\n"
+  "8 9 14    20\n"
+  "8 1 15    5\n"
+  "9 5 16    5\n"
+  "@attributes\n"
+  "source 1\n"
+  "target 8\n";
+
+void checkPreflowCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc,VType> CapMap;
+  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
+  typedef concepts::WriteMap<Node,bool> CutMap;
+
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Node n;
+  Arc e;
+  CapMap cap;
+  FlowMap flow;
+  CutMap cut;
+  VType v;
+  bool b;
+
+  typedef Preflow<Digraph, CapMap>
+            ::SetFlowMap<FlowMap>
+            ::SetElevator<Elev>
+            ::SetStandardElevator<LinkedElev>
+            ::Create PreflowType;
+  PreflowType preflow_test(g, cap, n, n);
+  const PreflowType& const_preflow_test = preflow_test;
+
+  preflow_test
+    .capacityMap(cap)
+    .flowMap(flow)
+    .source(n)
+    .target(n);
+
+  preflow_test.init();
+  preflow_test.init(cap);
+  preflow_test.startFirstPhase();
+  preflow_test.startSecondPhase();
+  preflow_test.run();
+  preflow_test.runMinCut();
+
+  v = const_preflow_test.flowValue();
+  v = const_preflow_test.flow(e);
+  const FlowMap& fm = const_preflow_test.flowMap();
+  b = const_preflow_test.minCut(n);
+  const_preflow_test.minCutMap(cut);
+
+  ignore_unused_variable_warning(fm);
+}
+
+int cutValue (const SmartDigraph& g,
+              const SmartDigraph::NodeMap<bool>& cut,
+              const SmartDigraph::ArcMap<int>& cap) {
+
+  int c=0;
+  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
+    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
+  }
+  return c;
+}
+
+bool checkFlow(const SmartDigraph& g,
+               const SmartDigraph::ArcMap<int>& flow,
+               const SmartDigraph::ArcMap<int>& cap,
+               SmartDigraph::Node s, SmartDigraph::Node t) {
+
+  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
+    if (flow[e] < 0 || flow[e] > cap[e]) return false;
+  }
+
+  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
+    if (n == s || n == t) continue;
+    int sum = 0;
+    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
+      sum += flow[e];
+    }
+    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
+      sum -= flow[e];
+    }
+    if (sum != 0) return false;
+  }
+  return true;
+}
+
+void initFlowTest()
+{
+  DIGRAPH_TYPEDEFS(SmartDigraph);
+
+  SmartDigraph g;
+  SmartDigraph::ArcMap<int> cap(g),iflow(g);
+  Node s=g.addNode(); Node t=g.addNode();
+  Node n1=g.addNode(); Node n2=g.addNode();
+  Arc a;
+  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
+  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
+  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
+
+  Preflow<SmartDigraph> pre(g,cap,s,t);
+  pre.init(iflow);
+  pre.startFirstPhase();
+  check(pre.flowValue() == 10, "The incorrect max flow value.");
+  check(pre.minCut(s), "Wrong min cut (Node s).");
+  check(pre.minCut(n1), "Wrong min cut (Node n1).");
+  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
+  check(!pre.minCut(t), "Wrong min cut (Node t).");
+}
+
+
+int main() {
+
+  typedef SmartDigraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::NodeIt NodeIt;
+  typedef Digraph::ArcIt ArcIt;
+  typedef Digraph::ArcMap<int> CapMap;
+  typedef Digraph::ArcMap<int> FlowMap;
+  typedef Digraph::NodeMap<bool> CutMap;
+
+  typedef Preflow<Digraph, CapMap> PType;
+
+  Digraph g;
+  Node s, t;
+  CapMap cap(g);
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(g,input).
+    arcMap("capacity", cap).
+    node("source",s).
+    node("target",t).
+    run();
+
+  PType preflow_test(g, cap, s, t);
+  preflow_test.run();
+
+  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
+        "The flow is not feasible.");
+
+  CutMap min_cut(g);
+  preflow_test.minCutMap(min_cut);
+  int min_cut_value=cutValue(g,min_cut,cap);
+
+  check(preflow_test.flowValue() == min_cut_value,
+        "The max flow value is not equal to the three min cut values.");
+
+  FlowMap flow(g);
+  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
+
+  int flow_value=preflow_test.flowValue();
+
+  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
+  preflow_test.init(flow);
+  preflow_test.startFirstPhase();
+
+  CutMap min_cut1(g);
+  preflow_test.minCutMap(min_cut1);
+  min_cut_value=cutValue(g,min_cut1,cap);
+
+  check(preflow_test.flowValue() == min_cut_value &&
+        min_cut_value == 2*flow_value,
+        "The max flow value or the min cut value is wrong.");
+
+  preflow_test.startSecondPhase();
+
+  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
+        "The flow is not feasible.");
+
+  CutMap min_cut2(g);
+  preflow_test.minCutMap(min_cut2);
+  min_cut_value=cutValue(g,min_cut2,cap);
+
+  check(preflow_test.flowValue() == min_cut_value &&
+        min_cut_value == 2*flow_value,
+        "The max flow value or the three min cut values were not doubled");
+
+
+  preflow_test.flowMap(flow);
+
+  NodeIt tmp1(g,s);
+  ++tmp1;
+  if ( tmp1 != INVALID ) s=tmp1;
+
+  NodeIt tmp2(g,t);
+  ++tmp2;
+  if ( tmp2 != INVALID ) t=tmp2;
+
+  preflow_test.source(s);
+  preflow_test.target(t);
+
+  preflow_test.run();
+
+  CutMap min_cut3(g);
+  preflow_test.minCutMap(min_cut3);
+  min_cut_value=cutValue(g,min_cut3,cap);
+
+
+  check(preflow_test.flowValue() == min_cut_value,
+        "The max flow value or the three min cut values are incorrect.");
+
+  initFlowTest();
+
+  return 0;
+}
Index: test/radix_sort_test.cc
===================================================================
--- test/radix_sort_test.cc	(revision 467)
+++ test/radix_sort_test.cc	(revision 467)
@@ -0,0 +1,147 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/time_measure.h>
+#include <lemon/smart_graph.h>
+#include <lemon/maps.h>
+#include <lemon/radix_sort.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+#include <vector>
+#include <algorithm>
+
+using namespace lemon;
+
+static const int n = 10000;
+
+struct Negate {
+  typedef int argument_type;
+  typedef int result_type;
+  int operator()(int a) { return - a; }
+};
+
+int negate(int a) { return - a; }
+
+
+void generateIntSequence(int n, std::vector<int>& data) {
+  int prime = 9973;
+  int root = 136, value = 1;
+  for (int i = 0; i < n; ++i) {
+    data.push_back(value - prime / 2);
+    value = (value * root) % prime;
+  }
+}
+
+void generateCharSequence(int n, std::vector<unsigned char>& data) {
+  int prime = 251;
+  int root = 3, value = root;
+  for (int i = 0; i < n; ++i) {
+    data.push_back(static_cast<unsigned char>(value));
+    value = (value * root) % prime;
+  }
+}
+
+void checkRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    radixSort(data2.begin(), data2.end(), Negate());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+    radixSort(data2.begin(), data2.end(), negate);
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+}
+
+
+void checkStableRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    stableRadixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), Negate());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), negate);
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+}
+
+int main() {
+
+  checkRadixSort();
+  checkStableRadixSort();
+
+  return 0;
+}
Index: test/random_test.cc
===================================================================
--- test/random_test.cc	(revision 209)
+++ test/random_test.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/suurballe_test.cc
===================================================================
--- test/suurballe_test.cc	(revision 1081)
+++ test/suurballe_test.cc	(revision 1081)
@@ -0,0 +1,241 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/path.h>
+#include <lemon/suurballe.h>
+#include <lemon/concepts/digraph.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "10\n"
+  "11\n"
+  "12\n"
+  "@arcs\n"
+  "      length\n"
+  " 1  2  70\n"
+  " 1  3 150\n"
+  " 1  4  80\n"
+  " 2  8  80\n"
+  " 3  5 140\n"
+  " 4  6  60\n"
+  " 4  7  80\n"
+  " 4  8 110\n"
+  " 5  7  60\n"
+  " 5 11 120\n"
+  " 6  3   0\n"
+  " 6  9 140\n"
+  " 6 10  90\n"
+  " 7  1  30\n"
+  " 8 12  60\n"
+  " 9 12  50\n"
+  "10 12  70\n"
+  "10  2 100\n"
+  "10  7  60\n"
+  "11 10  20\n"
+  "12 11  30\n"
+  "@attributes\n"
+  "source  1\n"
+  "target 12\n"
+  "@end\n";
+
+// Check the interface of Suurballe
+void checkSuurballeCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc, VType> LengthMap;
+
+  typedef Suurballe<Digraph, LengthMap> SuurballeType;
+
+  Digraph g;
+  Node n;
+  Arc e;
+  LengthMap len;
+  SuurballeType::FlowMap flow(g);
+  SuurballeType::PotentialMap pi(g);
+
+  SuurballeType suurb_test(g, len);
+  const SuurballeType& const_suurb_test = suurb_test;
+
+  suurb_test
+    .flowMap(flow)
+    .potentialMap(pi);
+
+  int k;
+  k = suurb_test.run(n, n);
+  k = suurb_test.run(n, n, k);
+  suurb_test.init(n);
+  k = suurb_test.findFlow(n);
+  k = suurb_test.findFlow(n, k);
+  suurb_test.findPaths();
+
+  int f;
+  VType c;
+  c = const_suurb_test.totalLength();
+  f = const_suurb_test.flow(e);
+  const SuurballeType::FlowMap& fm =
+    const_suurb_test.flowMap();
+  c = const_suurb_test.potential(n);
+  const SuurballeType::PotentialMap& pm =
+    const_suurb_test.potentialMap();
+  k = const_suurb_test.pathNum();
+  Path<Digraph> p = const_suurb_test.path(k);
+
+  ignore_unused_variable_warning(fm);
+  ignore_unused_variable_warning(pm);
+}
+
+// Check the feasibility of the flow
+template <typename Digraph, typename FlowMap>
+bool checkFlow( const Digraph& gr, const FlowMap& flow,
+                typename Digraph::Node s, typename Digraph::Node t,
+                int value )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  for (ArcIt e(gr); e != INVALID; ++e)
+    if (!(flow[e] == 0 || flow[e] == 1)) return false;
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    int sum = 0;
+    for (OutArcIt e(gr, n); e != INVALID; ++e)
+      sum += flow[e];
+    for (InArcIt e(gr, n); e != INVALID; ++e)
+      sum -= flow[e];
+    if (n == s && sum != value) return false;
+    if (n == t && sum != -value) return false;
+    if (n != s && n != t && sum != 0) return false;
+  }
+
+  return true;
+}
+
+// Check the optimalitiy of the flow
+template < typename Digraph, typename CostMap,
+           typename FlowMap, typename PotentialMap >
+bool checkOptimality( const Digraph& gr, const CostMap& cost,
+                      const FlowMap& flow, const PotentialMap& pi )
+{
+  // Check the "Complementary Slackness" optimality condition
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  bool opt = true;
+  for (ArcIt e(gr); e != INVALID; ++e) {
+    typename CostMap::Value red_cost =
+      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
+    opt = (flow[e] == 0 && red_cost >= 0) ||
+          (flow[e] == 1 && red_cost <= 0);
+    if (!opt) break;
+  }
+  return opt;
+}
+
+// Check a path
+template <typename Digraph, typename Path>
+bool checkPath( const Digraph& gr, const Path& path,
+                typename Digraph::Node s, typename Digraph::Node t)
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  Node n = s;
+  for (int i = 0; i < path.length(); ++i) {
+    if (gr.source(path.nth(i)) != n) return false;
+    n = gr.target(path.nth(i));
+  }
+  return n == t;
+}
+
+
+int main()
+{
+  DIGRAPH_TYPEDEFS(ListDigraph);
+
+  // Read the test digraph
+  ListDigraph digraph;
+  ListDigraph::ArcMap<int> length(digraph);
+  Node s, t;
+
+  std::istringstream input(test_lgf);
+  DigraphReader<ListDigraph>(digraph, input).
+    arcMap("length", length).
+    node("source", s).
+    node("target", t).
+    run();
+
+  // Find 2 paths
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length);
+    check(suurballe.run(s, t) == 2, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 510, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+  }
+
+  // Find 3 paths
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length);
+    check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+  }
+
+  // Find 5 paths (only 3 can be found)
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length);
+    check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+  }
+
+  return 0;
+}
Index: test/test_tools.h
===================================================================
--- test/test_tools.h	(revision 209)
+++ test/test_tools.h	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/test_tools_fail.cc
===================================================================
--- test/test_tools_fail.cc	(revision 209)
+++ test/test_tools_fail.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/test_tools_pass.cc
===================================================================
--- test/test_tools_pass.cc	(revision 209)
+++ test/test_tools_pass.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/time_measure_test.cc
===================================================================
--- test/time_measure_test.cc	(revision 209)
+++ test/time_measure_test.cc	(revision 605)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -40,16 +40,14 @@
   Timer T;
   unsigned int n;
-  for(n=0;T.realTime()<1.0;n++) ;
+  for(n=0;T.realTime()<0.1;n++) ;
   std::cout << T << " (" << n << " time queries)\n";
-  T.restart();
-  while(T.realTime()<2.0) ;
-  std::cout << T << '\n';
+
   TimeStamp full;
   TimeStamp t;
-  t=runningTimeTest(f,1,&n,&full);
+  t=runningTimeTest(f,0.1,&n,&full);
   std::cout << t << " (" << n << " tests)\n";
   std::cout << "Total: " << full << "\n";
 
-  t=runningTimeTest(g,1,&n,&full);
+  t=runningTimeTest(g,0.1,&n,&full);
   std::cout << t << " (" << n << " tests)\n";
   std::cout << "Total: " << full << "\n";
Index: test/unionfind_test.cc
===================================================================
--- test/unionfind_test.cc	(revision 209)
+++ test/unionfind_test.cc	(revision 463)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
