Index: src/lemon/Makefile.am
===================================================================
--- src/lemon/Makefile.am	(revision 962)
+++ src/lemon/Makefile.am	(revision 977)
@@ -30,4 +30,5 @@
 	map_defines.h							\
 	map_bits.h							\
+	utility.h							\
 	iterable_graph_extender.h					\
 	idmappable_graph_extender.h				   	\
Index: src/lemon/bfs.h
===================================================================
--- src/lemon/bfs.h	(revision 946)
+++ src/lemon/bfs.h	(revision 977)
@@ -26,4 +26,5 @@
 #include <lemon/bin_heap.h>
 #include <lemon/invalid.h>
+#include <lemon/graph_utils.h>
 
 namespace lemon {
Index: src/lemon/full_graph.h
===================================================================
--- src/lemon/full_graph.h	(revision 959)
+++ src/lemon/full_graph.h	(revision 977)
@@ -20,9 +20,11 @@
 
 #include <lemon/idmappable_graph_extender.h>
-
 #include <lemon/iterable_graph_extender.h>
-
 #include <lemon/alteration_observer_registry.h>
 #include <lemon/default_map.h>
+
+#include <lemon/invalid.h>
+#include <lemon/utility.h>
+
 
 ///\ingroup graphs
@@ -30,6 +32,4 @@
 ///\brief FullGraph and SymFullGraph classes.
 
-
-#include <lemon/invalid.h>
 
 namespace lemon {
@@ -59,4 +59,7 @@
     //      : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { }
     
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+
     ///Number of nodes.
     int nodeNum() const { return NodeNum; }
@@ -207,14 +210,4 @@
   };
 
-  template <>
-  int countNodes<FullGraph>(const FullGraph& graph) {
-    return graph.nodeNum();
-  }
-
-  template <>
-  int countEdges<FullGraph>(const FullGraph& graph) {
-    return graph.edgeNum();
-  }
-
   /// @}  
 
@@ -222,5 +215,3 @@
 
 
-
-
 #endif //LEMON_FULL_GRAPH_H
Index: src/lemon/graph_utils.h
===================================================================
--- src/lemon/graph_utils.h	(revision 967)
+++ src/lemon/graph_utils.h	(revision 977)
@@ -21,4 +21,5 @@
 
 #include <lemon/invalid.h>
+#include <lemon/utility.h>
 
 ///\ingroup gutils
@@ -36,5 +37,4 @@
 /// @{
 
-  // counters in the graph
   /// \brief Function to count the items in the graph.
   ///
@@ -44,10 +44,24 @@
 
   template <typename Graph, typename ItemIt>
-  inline int countItems(const Graph& _g) {
+  inline int countItems(const Graph& g) {
     int num = 0;
-    for (ItemIt it(_g); it != INVALID; ++it) {
+    for (ItemIt it(g); it != INVALID; ++it) {
       ++num;
     }
     return num;
+  }
+
+  // Node counting:
+
+  template <typename Graph>
+  inline
+  typename enable_if<typename Graph::NodeNumTag, int>::type
+  _countNodes(const Graph &g) {
+    return g.nodeNum();
+  }
+
+  template <typename Graph>
+  inline int _countNodes(Wrap<Graph> w) {
+    return countItems<Graph, typename Graph::NodeIt>(w.value);
   }
 
@@ -57,8 +71,24 @@
   /// The complexity of the function is O(n) but for some
   /// graph structure it is specialized to run in O(1).
-
-  template <typename Graph>
-  inline int countNodes(const Graph& _g) {
-    return countItems<Graph, typename Graph::NodeIt>(_g);
+  ///
+  /// \todo refer how to specialize it
+
+  template <typename Graph>
+  inline int countNodes(const Graph& g) {
+    return _countNodes<Graph>(g);
+  }
+
+  // Edge counting:
+
+  template <typename Graph>
+  inline
+  typename enable_if<typename Graph::EdgeNumTag, int>::type
+  _countEdges(const Graph &g) {
+    return g.edgeNum();
+  }
+
+  template <typename Graph>
+  inline int _countEdges(Wrap<Graph> w) {
+    return countItems<Graph, typename Graph::EdgeIt>(w.value);
   }
 
@@ -68,7 +98,8 @@
   /// The complexity of the function is O(e) but for some
   /// graph structure it is specialized to run in O(1).
-  template <typename Graph>
-  inline int countEdges(const Graph& _g) {
-    return countItems<Graph, typename Graph::EdgeIt>(_g);
+
+  template <typename Graph>
+  inline int countEdges(const Graph& g) {
+    return _countEdges<Graph>(g);
   }
 
@@ -82,4 +113,5 @@
     return countItems<Graph, typename Graph::SymEdgeIt>(_g);
   }
+
 
   template <typename Graph, typename DegIt>
Index: src/lemon/maps.h
===================================================================
--- src/lemon/maps.h	(revision 959)
+++ src/lemon/maps.h	(revision 977)
@@ -105,7 +105,4 @@
     void set(const K&, const V&) { }
   };
-  //to document later
-  typedef Const<bool, true> True;
-  typedef Const<bool, false> False;
 
   /// \c std::map wrapper
Index: src/lemon/preflow.h
===================================================================
--- src/lemon/preflow.h	(revision 946)
+++ src/lemon/preflow.h	(revision 977)
@@ -23,4 +23,5 @@
 #include <lemon/invalid.h>
 #include <lemon/maps.h>
+#include <lemon/graph_utils.h>
 
 /// \file
Index: src/lemon/smart_graph.h
===================================================================
--- src/lemon/smart_graph.h	(revision 974)
+++ src/lemon/smart_graph.h	(revision 977)
@@ -28,15 +28,10 @@
 #include <lemon/clearable_graph_extender.h>
 #include <lemon/extendable_graph_extender.h>
-
 #include <lemon/idmappable_graph_extender.h>
-
 #include <lemon/iterable_graph_extender.h>
-
 #include <lemon/alteration_observer_registry.h>
 #include <lemon/default_map.h>
 
-
-#include <lemon/graph_utils.h>
-
+#include <lemon/utility.h>
 
 namespace lemon {
@@ -85,4 +80,7 @@
     SmartGraphBase(const SmartGraphBase &_g) : nodes(_g.nodes), edges(_g.edges) { }
     
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+
     ///Number of nodes.
     int nodeNum() const { return nodes.size(); }
@@ -324,19 +322,7 @@
   };
   
-  template <>
-  int countNodes<SmartGraph>(const SmartGraph& graph) {
-    return graph.nodeNum();
-  }
-
-  template <>
-  int countEdges<SmartGraph>(const SmartGraph& graph) {
-    return graph.edgeNum();
-  }
-
   /// @}  
 } //namespace lemon
 
 
-
-
 #endif //LEMON_SMART_GRAPH_H
Index: src/lemon/utility.h
===================================================================
--- src/lemon/utility.h	(revision 977)
+++ src/lemon/utility.h	(revision 977)
@@ -0,0 +1,110 @@
+/* -*- C++ -*-
+ *
+ * src/lemon/utility.h - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi
+ * Kutatocsoport (Egervary Combinatorial Optimization Research Group,
+ * EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ * This file contains a modified version of the enable_if library from BOOST.
+ * See the appropriate copyright notice below.
+ */
+
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//    Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+//             Jeremiah Willcock (jewillco at osl.iu.edu)
+//             Andrew Lumsdaine (lums at osl.iu.edu)
+
+
+#ifndef LEMON_UTILITY_H
+#define LEMON_UTILITY_H
+
+namespace lemon
+{
+
+  /// Basic type for defining "tags". A "YES" condidion for enable_if.
+
+  /// \todo This should go to a separate "basic_types.h" (or something)
+  /// file.
+  struct True {
+    static const bool value = true;
+  };
+
+  /// Basic type for defining "tags". A "NO" condidion for enable_if.
+  struct False {
+    static const bool value = false;
+  };
+
+  template <typename T>
+  struct Wrap {
+    const T &value;
+    Wrap(const T &t) : value(t) {}
+  };
+
+
+
+  /**************** enable_if from BOOST ****************/
+ 
+  template <bool B, class T = void>
+  struct enable_if_c {
+    typedef T type;
+  };
+
+  template <class T>
+  struct enable_if_c<false, T> {};
+
+  template <class Cond, class T = void> 
+  struct enable_if : public enable_if_c<Cond::value, T> {};
+
+  template <bool B, class T>
+  struct lazy_enable_if_c {
+    typedef typename T::type type;
+  };
+
+  template <class T>
+  struct lazy_enable_if_c<false, T> {};
+
+  template <class Cond, class T> 
+  struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
+
+
+  template <bool B, class T = void>
+  struct disable_if_c {
+    typedef T type;
+  };
+
+  template <class T>
+  struct disable_if_c<true, T> {};
+
+  template <class Cond, class T = void> 
+  struct disable_if : public disable_if_c<Cond::value, T> {};
+
+  template <bool B, class T>
+  struct lazy_disable_if_c {
+    typedef typename T::type type;
+  };
+
+  template <class T>
+  struct lazy_disable_if_c<true, T> {};
+
+  template <class Cond, class T> 
+  struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
+
+} // namespace lemon
+
+#endif
Index: src/test/graph_utils_test.cc
===================================================================
--- src/test/graph_utils_test.cc	(revision 946)
+++ src/test/graph_utils_test.cc	(revision 977)
@@ -3,4 +3,6 @@
 #include <iostream>
 #include <vector>
+
+#include <lemon/graph_utils.h>
 
 #include <lemon/list_graph.h>
@@ -23,4 +25,10 @@
     checkGraphCounters<SmartGraph>();
   }
+  {
+    int num = 5;
+    FullGraph fg(num);
+    check(countNodes(fg) == num, "FullGraph: wrong node number.");
+    check(countEdges(fg) == num*num, "FullGraph: wrong edge number.");    
+  }
 
   std::cout << __FILE__ ": All tests passed.\n";
Index: src/test/graph_utils_test.h
===================================================================
--- src/test/graph_utils_test.h	(revision 946)
+++ src/test/graph_utils_test.h	(revision 977)
@@ -31,9 +31,9 @@
     addPetersen(graph, num);
     bidirGraph(graph);
-    check(countNodes(graph) == 2*num, "Wrong node counter.");
-    check(countEdges(graph) == 6*num, "Wrong edge counter.");    
+    check(countNodes(graph) == 2*num, "Wrong node number.");
+    check(countEdges(graph) == 6*num, "Wrong edge number.");    
     for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
-      check(countOutEdges(graph, it) == 3, "Wrong out degree counter.");
-      check(countInEdges(graph, it) == 3, "Wrong in degree counter.");
+      check(countOutEdges(graph, it) == 3, "Wrong out degree number.");
+      check(countInEdges(graph, it) == 3, "Wrong in degree number.");
     }
   }
