Index: lemon/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 491)
+++ lemon/Makefile.am	(revision 492)
@@ -8,33 +8,64 @@
 
 lemon_libemon_la_SOURCES = \
-        lemon/arg_parser.cc \
-        lemon/base.cc \
-        lemon/color.cc \
-        lemon/random.cc
+	lemon/arg_parser.cc \
+	lemon/base.cc \
+	lemon/color.cc \
+	lemon/lp_base.cc \
+	lemon/lp_skeleton.cc \
+	lemon/random.cc
 
-#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS) $(AM_CXXFLAGS)
-#lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
+
+lemon_libemon_la_CXXFLAGS = \
+	$(GLPK_CFLAGS) \
+	$(CPLEX_CFLAGS) \
+	$(SOPLEX_CXXFLAGS) \
+	$(CLP_CXXFLAGS)
+
+lemon_libemon_la_LDFLAGS = \
+	$(GLPK_LIBS) \
+	$(CPLEX_LIBS) \
+	$(SOPLEX_LIBS) \
+	$(CLP_LIBS)
+
+if HAVE_GLPK
+lemon_libemon_la_SOURCES += lemon/glpk.cc
+endif
+
+if HAVE_CPLEX
+lemon_libemon_la_SOURCES += lemon/cplex.cc
+endif
+
+if HAVE_SOPLEX
+lemon_libemon_la_SOURCES += lemon/soplex.cc
+endif
+
+if HAVE_CLP
+lemon_libemon_la_SOURCES += lemon/clp.cc
+endif
 
 lemon_HEADERS += \
 	lemon/adaptors.h \
-        lemon/arg_parser.h \
+	lemon/arg_parser.h \
 	lemon/assert.h \
-        lemon/bfs.h \
-        lemon/bin_heap.h \
-        lemon/circulation.h \
-        lemon/color.h \
+	lemon/bfs.h \
+	lemon/bin_heap.h \
+	lemon/circulation.h \
+	lemon/clp.h \
+	lemon/color.h \
 	lemon/concept_check.h \
-        lemon/counter.h \
+	lemon/counter.h \
 	lemon/core.h \
-        lemon/dfs.h \
-        lemon/dijkstra.h \
-        lemon/dim2.h \
-        lemon/dimacs.h \
+	lemon/cplex.h \
+	lemon/dfs.h \
+	lemon/dijkstra.h \
+	lemon/dim2.h \
+	lemon/dimacs.h \
 	lemon/edge_set.h \
 	lemon/elevator.h \
 	lemon/error.h \
 	lemon/full_graph.h \
-        lemon/graph_to_eps.h \
-        lemon/grid_graph.h \
+	lemon/glpk.h \
+	lemon/graph_to_eps.h \
+	lemon/grid_graph.h \
 	lemon/hypercube_graph.h \
 	lemon/kruskal.h \
@@ -42,4 +73,8 @@
 	lemon/lgf_reader.h \
 	lemon/lgf_writer.h \
+	lemon/list_graph.h \
+	lemon/lp.h \
+	lemon/lp_base.h \
+	lemon/lp_skeleton.h \
 	lemon/list_graph.h \
 	lemon/maps.h \
@@ -49,9 +84,11 @@
 	lemon/path.h \
 	lemon/preflow.h \
-        lemon/random.h \
+	lemon/radix_sort.h \
+	lemon/random.h \
 	lemon/smart_graph.h \
+	lemon/soplex.h \
 	lemon/suurballe.h \
-        lemon/time_measure.h \
-        lemon/tolerance.h \
+	lemon/time_measure.h \
+	lemon/tolerance.h \
 	lemon/unionfind.h
 
@@ -60,12 +97,13 @@
 	lemon/bits/array_map.h \
 	lemon/bits/base_extender.h \
-        lemon/bits/bezier.h \
+	lemon/bits/bezier.h \
 	lemon/bits/default_map.h \
 	lemon/bits/edge_set_extender.h \
-        lemon/bits/enable_if.h \
+	lemon/bits/enable_if.h \
 	lemon/bits/graph_adaptor_extender.h \
 	lemon/bits/graph_extender.h \
 	lemon/bits/map_extender.h \
 	lemon/bits/path_dump.h \
+	lemon/bits/solver_bits.h \
 	lemon/bits/traits.h \
 	lemon/bits/variant.h \
Index: lemon/adaptors.h
===================================================================
--- lemon/adaptors.h	(revision 432)
+++ lemon/adaptors.h	(revision 487)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -22,5 +22,5 @@
 /// \ingroup graph_adaptors
 /// \file
-/// \brief Several graph adaptors
+/// \brief Adaptor classes for digraphs and graphs
 ///
 /// This file contains several useful adaptors for digraphs and graphs.
@@ -71,9 +71,9 @@
     int nodeNum() const { return _digraph->nodeNum(); }
 
-    typedef EdgeNumTagIndicator<Digraph> EdgeNumTag;
+    typedef ArcNumTagIndicator<Digraph> ArcNumTag;
     int arcNum() const { return _digraph->arcNum(); }
 
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
-    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) {
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const {
       return _digraph->findArc(u, v, prev);
     }
@@ -82,8 +82,8 @@
     Arc addArc(const Node& u, const Node& v) { return _digraph->addArc(u, v); }
 
-    void erase(const Node& n) const { _digraph->erase(n); }
-    void erase(const Arc& a) const { _digraph->erase(a); }
-
-    void clear() const { _digraph->clear(); }
+    void erase(const Node& n) { _digraph->erase(n); }
+    void erase(const Arc& a) { _digraph->erase(a); }
+
+    void clear() { _digraph->clear(); }
 
     int id(const Node& n) const { return _digraph->id(n); }
@@ -199,13 +199,19 @@
     int nodeNum() const { return _graph->nodeNum(); }
 
+    typedef ArcNumTagIndicator<Graph> ArcNumTag;
+    int arcNum() const { return _graph->arcNum(); }
+
     typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
-    int arcNum() const { return _graph->arcNum(); }
     int edgeNum() const { return _graph->edgeNum(); }
 
+    typedef FindArcTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      return _graph->findArc(u, v, prev);
+    }
+
     typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
-    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) {
-      return _graph->findArc(u, v, prev);
-    }
-    Edge findEdge(const Node& u, const Node& v, const Edge& prev = INVALID) {
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
       return _graph->findEdge(u, v, prev);
     }
@@ -331,7 +337,7 @@
     Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); }
 
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
     Arc findArc(const Node& u, const Node& v,
-                const Arc& prev = INVALID) {
+                const Arc& prev = INVALID) const {
       return Parent::findArc(v, u, prev);
     }
@@ -341,19 +347,31 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief A digraph adaptor which reverses the orientation of the arcs.
-  ///
-  /// ReverseDigraph reverses the arcs in the adapted digraph. The
-  /// SubDigraph is conform to the \ref concepts::Digraph
-  /// "Digraph concept".
-  ///
-  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
-  /// "Digraph concept". The type can be specified to be const.
-  template<typename _Digraph>
+  /// \brief Adaptor class for reversing the orientation of the arcs in
+  /// a digraph.
+  ///
+  /// ReverseDigraph can be used for reversing the arcs in a digraph.
+  /// It conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It can also be specified to be \c const.
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
+  template<typename GR>
+#ifdef DOXYGEN
+  class ReverseDigraph {
+#else
   class ReverseDigraph :
-    public DigraphAdaptorExtender<ReverseDigraphBase<_Digraph> > {
-  public:
-    typedef _Digraph Digraph;
-    typedef DigraphAdaptorExtender<
-      ReverseDigraphBase<_Digraph> > Parent;
+    public DigraphAdaptorExtender<ReverseDigraphBase<GR> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef GR Digraph;
+    typedef DigraphAdaptorExtender<ReverseDigraphBase<GR> > Parent;
   protected:
     ReverseDigraph() { }
@@ -362,5 +380,5 @@
     /// \brief Constructor
     ///
-    /// Creates a reverse digraph adaptor for the given digraph
+    /// Creates a reverse digraph adaptor for the given digraph.
     explicit ReverseDigraph(Digraph& digraph) {
       Parent::setDigraph(digraph);
@@ -368,11 +386,14 @@
   };
 
-  /// \brief Just gives back a reverse digraph adaptor
-  ///
-  /// Just gives back a reverse digraph adaptor
-  template<typename Digraph>
-  ReverseDigraph<const Digraph> reverseDigraph(const Digraph& digraph) {
-    return ReverseDigraph<const Digraph>(digraph);
+  /// \brief Returns a read-only ReverseDigraph adaptor
+  ///
+  /// This function just returns a read-only \ref ReverseDigraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates ReverseDigraph
+  template<typename GR>
+  ReverseDigraph<const GR> reverseDigraph(const GR& digraph) {
+    return ReverseDigraph<const GR>(digraph);
   }
+
 
   template <typename _Digraph, typename _NodeFilterMap,
@@ -458,19 +479,16 @@
     }
 
-    void hide(const Node& n) const { _node_filter->set(n, false); }
-    void hide(const Arc& a) const { _arc_filter->set(a, false); }
-
-    void unHide(const Node& n) const { _node_filter->set(n, true); }
-    void unHide(const Arc& a) const { _arc_filter->set(a, true); }
-
-    bool hidden(const Node& n) const { return !(*_node_filter)[n]; }
-    bool hidden(const Arc& a) const { return !(*_arc_filter)[a]; }
+    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
+    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
+
+    bool status(const Node& n) const { return (*_node_filter)[n]; }
+    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
 
     typedef False NodeNumTag;
-    typedef False EdgeNumTag;
-
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    typedef False ArcNumTag;
+
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
     Arc findArc(const Node& source, const Node& target,
-                const Arc& prev = INVALID) {
+                const Arc& prev = INVALID) const {
       if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
         return INVALID;
@@ -601,19 +619,16 @@
     }
 
-    void hide(const Node& n) const { _node_filter->set(n, false); }
-    void hide(const Arc& e) const { _arc_filter->set(e, false); }
-
-    void unHide(const Node& n) const { _node_filter->set(n, true); }
-    void unHide(const Arc& e) const { _arc_filter->set(e, true); }
-
-    bool hidden(const Node& n) const { return !(*_node_filter)[n]; }
-    bool hidden(const Arc& e) const { return !(*_arc_filter)[e]; }
+    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
+    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
+
+    bool status(const Node& n) const { return (*_node_filter)[n]; }
+    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
 
     typedef False NodeNumTag;
-    typedef False EdgeNumTag;
-
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    typedef False ArcNumTag;
+
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
     Arc findArc(const Node& source, const Node& target,
-                const Arc& prev = INVALID) {
+                const Arc& prev = INVALID) const {
       if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
         return INVALID;
@@ -680,40 +695,55 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief An adaptor for hiding nodes and arcs in a digraph
-  ///
-  /// SubDigraph hides nodes and arcs in a digraph. A bool node map
-  /// and a bool arc map must be specified, which define the filters
-  /// for nodes and arcs. Just the nodes and arcs with true value are
-  /// shown in the subdigraph. The SubDigraph is conform to the \ref
-  /// concepts::Digraph "Digraph concept". If the \c _checked parameter
-  /// is true, then the arcs incident to filtered nodes are also
-  /// filtered out.
-  ///
-  /// \tparam _Digraph It must be conform to the \ref
-  /// concepts::Digraph "Digraph concept". The type can be specified
-  /// to const.
-  /// \tparam _NodeFilterMap A bool valued node map of the the adapted digraph.
-  /// \tparam _ArcFilterMap A bool valued arc map of the the adapted digraph.
-  /// \tparam _checked If the parameter is false then the arc filtering
-  /// is not checked with respect to node filter. Otherwise, each arc
-  /// is automatically filtered, which is incident to a filtered node.
+  /// \brief Adaptor class for hiding nodes and arcs in a digraph
+  ///
+  /// SubDigraph can be used for hiding nodes and arcs in a digraph.
+  /// A \c bool node map and a \c bool arc map must be specified, which
+  /// define the filters for nodes and arcs.
+  /// Only the nodes and arcs with \c true filter value are
+  /// shown in the subdigraph. The arcs that are incident to hidden
+  /// nodes are also filtered out.
+  /// This adaptor conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::NodeMap "GR::NodeMap<bool>".
+  /// \tparam AF The type of the arc filter map.
+  /// It must be \c bool (or convertible) arc map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<bool>".
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
   ///
   /// \see FilterNodes
   /// \see FilterArcs
-  template<typename _Digraph,
-           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
-           typename _ArcFilterMap = typename _Digraph::template ArcMap<bool>,
-           bool _checked = true>
-  class SubDigraph
-    : public DigraphAdaptorExtender<
-      SubDigraphBase<_Digraph, _NodeFilterMap, _ArcFilterMap, _checked> > {
-  public:
-    typedef _Digraph Digraph;
-    typedef _NodeFilterMap NodeFilterMap;
-    typedef _ArcFilterMap ArcFilterMap;
-
-    typedef DigraphAdaptorExtender<
-      SubDigraphBase<Digraph, NodeFilterMap, ArcFilterMap, _checked> >
-    Parent;
+#ifdef DOXYGEN
+  template<typename GR, typename NF, typename AF>
+  class SubDigraph {
+#else
+  template<typename GR,
+           typename NF = typename GR::template NodeMap<bool>,
+           typename AF = typename GR::template ArcMap<bool> >
+  class SubDigraph :
+    public DigraphAdaptorExtender<SubDigraphBase<GR, NF, AF, true> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef GR Digraph;
+    /// The type of the node filter map.
+    typedef NF NodeFilterMap;
+    /// The type of the arc filter map.
+    typedef AF ArcFilterMap;
+
+    typedef DigraphAdaptorExtender<SubDigraphBase<GR, NF, AF, true> >
+      Parent;
 
     typedef typename Parent::Node Node;
@@ -726,6 +756,6 @@
     /// \brief Constructor
     ///
-    /// Creates a subdigraph for the given digraph with
-    /// given node and arc map filters.
+    /// Creates a subdigraph for the given digraph with the
+    /// given node and arc filter maps.
     SubDigraph(Digraph& digraph, NodeFilterMap& node_filter,
                ArcFilterMap& arc_filter) {
@@ -735,86 +765,104 @@
     }
 
-    /// \brief Hides the node of the graph
-    ///
-    /// This function hides \c n in the digraph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c n
-    /// to be false in the corresponding node-map.
-    void hide(const Node& n) const { Parent::hide(n); }
-
-    /// \brief Hides the arc of the graph
-    ///
-    /// This function hides \c a in the digraph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c a
-    /// to be false in the corresponding arc-map.
-    void hide(const Arc& a) const { Parent::hide(a); }
-
-    /// \brief Unhides the node of the graph
-    ///
-    /// The value of \c n is set to be true in the node-map which stores
-    /// hide information. If \c n was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Node& n) const { Parent::unHide(n); }
-
-    /// \brief Unhides the arc of the graph
-    ///
-    /// The value of \c a is set to be true in the arc-map which stores
-    /// hide information. If \c a was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Arc& a) const { Parent::unHide(a); }
-
-    /// \brief Returns true if \c n is hidden.
-    ///
-    /// Returns true if \c n is hidden.
-    ///
-    bool hidden(const Node& n) const { return Parent::hidden(n); }
-
-    /// \brief Returns true if \c a is hidden.
-    ///
-    /// Returns true if \c a is hidden.
-    ///
-    bool hidden(const Arc& a) const { return Parent::hidden(a); }
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Sets the status of the given arc
+    ///
+    /// This function sets the status of the given arc.
+    /// It is done by simply setting the assigned value of \c a
+    /// to \c v in the arc filter map.
+    void status(const Arc& a, bool v) const { Parent::status(a, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Returns the status of the given arc
+    ///
+    /// This function returns the status of the given arc.
+    /// It is \c true if the given arc is enabled (i.e. not hidden).
+    bool status(const Arc& a) const { return Parent::status(a); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Disables the given arc
+    ///
+    /// This function disables the given arc in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(a, false)".
+    void disable(const Arc& a) const { Parent::status(a, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node in the subdigraph.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+    /// \brief Enables the given arc
+    ///
+    /// This function enables the given arc in the subdigraph.
+    /// It is the same as \ref status() "status(a, true)".
+    void enable(const Arc& a) const { Parent::status(a, true); }
 
   };
 
-  /// \brief Just gives back a subdigraph
-  ///
-  /// Just gives back a subdigraph
-  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
-  SubDigraph<const Digraph, NodeFilterMap, ArcFilterMap>
-  subDigraph(const Digraph& digraph, NodeFilterMap& nfm, ArcFilterMap& afm) {
-    return SubDigraph<const Digraph, NodeFilterMap, ArcFilterMap>
-      (digraph, nfm, afm);
+  /// \brief Returns a read-only SubDigraph adaptor
+  ///
+  /// This function just returns a read-only \ref SubDigraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SubDigraph
+  template<typename GR, typename NF, typename AF>
+  SubDigraph<const GR, NF, AF>
+  subDigraph(const GR& digraph,
+             NF& node_filter_map, AF& arc_filter_map) {
+    return SubDigraph<const GR, NF, AF>
+      (digraph, node_filter_map, arc_filter_map);
   }
 
-  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
-  SubDigraph<const Digraph, const NodeFilterMap, ArcFilterMap>
-  subDigraph(const Digraph& digraph,
-             const NodeFilterMap& nfm, ArcFilterMap& afm) {
-    return SubDigraph<const Digraph, const NodeFilterMap, ArcFilterMap>
-      (digraph, nfm, afm);
+  template<typename GR, typename NF, typename AF>
+  SubDigraph<const GR, const NF, AF>
+  subDigraph(const GR& digraph,
+             const NF& node_filter_map, AF& arc_filter_map) {
+    return SubDigraph<const GR, const NF, AF>
+      (digraph, node_filter_map, arc_filter_map);
   }
 
-  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
-  SubDigraph<const Digraph, NodeFilterMap, const ArcFilterMap>
-  subDigraph(const Digraph& digraph,
-             NodeFilterMap& nfm, const ArcFilterMap& afm) {
-    return SubDigraph<const Digraph, NodeFilterMap, const ArcFilterMap>
-      (digraph, nfm, afm);
+  template<typename GR, typename NF, typename AF>
+  SubDigraph<const GR, NF, const AF>
+  subDigraph(const GR& digraph,
+             NF& node_filter_map, const AF& arc_filter_map) {
+    return SubDigraph<const GR, NF, const AF>
+      (digraph, node_filter_map, arc_filter_map);
   }
 
-  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
-  SubDigraph<const Digraph, const NodeFilterMap, const ArcFilterMap>
-  subDigraph(const Digraph& digraph,
-             const NodeFilterMap& nfm, const ArcFilterMap& afm) {
-    return SubDigraph<const Digraph, const NodeFilterMap,
-      const ArcFilterMap>(digraph, nfm, afm);
+  template<typename GR, typename NF, typename AF>
+  SubDigraph<const GR, const NF, const AF>
+  subDigraph(const GR& digraph,
+             const NF& node_filter_map, const AF& arc_filter_map) {
+    return SubDigraph<const GR, const NF, const AF>
+      (digraph, node_filter_map, arc_filter_map);
   }
 
 
-  template <typename _Graph, typename NodeFilterMap,
-            typename EdgeFilterMap, bool _checked = true>
+  template <typename _Graph, typename _NodeFilterMap,
+            typename _EdgeFilterMap, bool _checked = true>
   class SubGraphBase : public GraphAdaptorBase<_Graph> {
   public:
     typedef _Graph Graph;
+    typedef _NodeFilterMap NodeFilterMap;
+    typedef _EdgeFilterMap EdgeFilterMap;
+
     typedef SubGraphBase Adaptor;
     typedef GraphAdaptorBase<_Graph> Parent;
@@ -926,19 +974,17 @@
     }
 
-    void hide(const Node& n) const { _node_filter_map->set(n, false); }
-    void hide(const Edge& e) const { _edge_filter_map->set(e, false); }
-
-    void unHide(const Node& n) const { _node_filter_map->set(n, true); }
-    void unHide(const Edge& e) const { _edge_filter_map->set(e, true); }
-
-    bool hidden(const Node& n) const { return !(*_node_filter_map)[n]; }
-    bool hidden(const Edge& e) const { return !(*_edge_filter_map)[e]; }
+    void status(const Node& n, bool v) const { _node_filter_map->set(n, v); }
+    void status(const Edge& e, bool v) const { _edge_filter_map->set(e, v); }
+
+    bool status(const Node& n) const { return (*_node_filter_map)[n]; }
+    bool status(const Edge& e) const { return (*_edge_filter_map)[e]; }
 
     typedef False NodeNumTag;
+    typedef False ArcNumTag;
     typedef False EdgeNumTag;
 
-    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    typedef FindArcTagIndicator<Graph> FindArcTag;
     Arc findArc(const Node& u, const Node& v,
-                const Arc& prev = INVALID) {
+                const Arc& prev = INVALID) const {
       if (!(*_node_filter_map)[u] || !(*_node_filter_map)[v]) {
         return INVALID;
@@ -950,6 +996,8 @@
       return arc;
     }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
     Edge findEdge(const Node& u, const Node& v,
-                  const Edge& prev = INVALID) {
+                  const Edge& prev = INVALID) const {
       if (!(*_node_filter_map)[u] || !(*_node_filter_map)[v]) {
         return INVALID;
@@ -1040,9 +1088,12 @@
   };
 
-  template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
-  class SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap, false>
+  template <typename _Graph, typename _NodeFilterMap, typename _EdgeFilterMap>
+  class SubGraphBase<_Graph, _NodeFilterMap, _EdgeFilterMap, false>
     : public GraphAdaptorBase<_Graph> {
   public:
     typedef _Graph Graph;
+    typedef _NodeFilterMap NodeFilterMap;
+    typedef _EdgeFilterMap EdgeFilterMap;
+
     typedef SubGraphBase Adaptor;
     typedef GraphAdaptorBase<_Graph> Parent;
@@ -1122,19 +1173,17 @@
     }
 
-    void hide(const Node& n) const { _node_filter_map->set(n, false); }
-    void hide(const Edge& e) const { _edge_filter_map->set(e, false); }
-
-    void unHide(const Node& n) const { _node_filter_map->set(n, true); }
-    void unHide(const Edge& e) const { _edge_filter_map->set(e, true); }
-
-    bool hidden(const Node& n) const { return !(*_node_filter_map)[n]; }
-    bool hidden(const Edge& e) const { return !(*_edge_filter_map)[e]; }
+    void status(const Node& n, bool v) const { _node_filter_map->set(n, v); }
+    void status(const Edge& e, bool v) const { _edge_filter_map->set(e, v); }
+
+    bool status(const Node& n) const { return (*_node_filter_map)[n]; }
+    bool status(const Edge& e) const { return (*_edge_filter_map)[e]; }
 
     typedef False NodeNumTag;
+    typedef False ArcNumTag;
     typedef False EdgeNumTag;
 
-    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    typedef FindArcTagIndicator<Graph> FindArcTag;
     Arc findArc(const Node& u, const Node& v,
-                const Arc& prev = INVALID) {
+                const Arc& prev = INVALID) const {
       Arc arc = Parent::findArc(u, v, prev);
       while (arc != INVALID && !(*_edge_filter_map)[arc]) {
@@ -1143,6 +1192,8 @@
       return arc;
     }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
     Edge findEdge(const Node& u, const Node& v,
-                  const Edge& prev = INVALID) {
+                  const Edge& prev = INVALID) const {
       Edge edge = Parent::findEdge(u, v, prev);
       while (edge != INVALID && !(*_edge_filter_map)[edge]) {
@@ -1232,35 +1283,56 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief A graph adaptor for hiding nodes and edges in an
-  /// undirected graph.
-  ///
-  /// SubGraph hides nodes and edges in a graph. A bool node map and a
-  /// bool edge map must be specified, which define the filters for
-  /// nodes and edges. Just the nodes and edges with true value are
-  /// shown in the subgraph. The SubGraph is conform to the \ref
-  /// concepts::Graph "Graph concept". If the \c _checked parameter is
-  /// true, then the edges incident to filtered nodes are also
-  /// filtered out.
-  ///
-  /// \tparam _Graph It must be conform to the \ref
-  /// concepts::Graph "Graph concept". The type can be specified
-  /// to const.
-  /// \tparam _NodeFilterMap A bool valued node map of the the adapted graph.
-  /// \tparam _EdgeFilterMap A bool valued edge map of the the adapted graph.
-  /// \tparam _checked If the parameter is false then the edge filtering
-  /// is not checked with respect to node filter. Otherwise, each edge
-  /// is automatically filtered, which is incident to a filtered node.
+  /// \brief Adaptor class for hiding nodes and edges in an undirected
+  /// graph.
+  ///
+  /// SubGraph can be used for hiding nodes and edges in a graph.
+  /// A \c bool node map and a \c bool edge map must be specified, which
+  /// define the filters for nodes and edges.
+  /// Only the nodes and edges with \c true filter value are
+  /// shown in the subgraph. The edges that are incident to hidden
+  /// nodes are also filtered out.
+  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
+  /// \tparam EF The type of the edge filter map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
+  /// adapted graph are convertible to each other.
   ///
   /// \see FilterNodes
   /// \see FilterEdges
-  template<typename _Graph, typename NodeFilterMap,
-           typename EdgeFilterMap, bool _checked = true>
-  class SubGraph
-    : public GraphAdaptorExtender<
-      SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap, _checked> > {
-  public:
-    typedef _Graph Graph;
-    typedef GraphAdaptorExtender<
-      SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
+#ifdef DOXYGEN
+  template<typename GR, typename NF, typename EF>
+  class SubGraph {
+#else
+  template<typename GR,
+           typename NF = typename GR::template NodeMap<bool>,
+           typename EF = typename GR::template EdgeMap<bool> >
+  class SubGraph :
+    public GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> > {
+#endif
+  public:
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the node filter map.
+    typedef NF NodeFilterMap;
+    /// The type of the edge filter map.
+    typedef EF EdgeFilterMap;
+
+    typedef GraphAdaptorExtender< SubGraphBase<GR, NF, EF, true> >
+      Parent;
 
     typedef typename Parent::Node Node;
@@ -1273,130 +1345,151 @@
     /// \brief Constructor
     ///
-    /// Creates a subgraph for the given graph with given node and
-    /// edge map filters.
-    SubGraph(Graph& _graph, NodeFilterMap& node_filter_map,
+    /// Creates a subgraph for the given graph with the given node
+    /// and edge filter maps.
+    SubGraph(Graph& graph, NodeFilterMap& node_filter_map,
              EdgeFilterMap& edge_filter_map) {
-      setGraph(_graph);
+      setGraph(graph);
       setNodeFilterMap(node_filter_map);
       setEdgeFilterMap(edge_filter_map);
     }
 
-    /// \brief Hides the node of the graph
-    ///
-    /// This function hides \c n in the graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c n
-    /// to be false in the corresponding node-map.
-    void hide(const Node& n) const { Parent::hide(n); }
-
-    /// \brief Hides the edge of the graph
-    ///
-    /// This function hides \c e in the graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c e
-    /// to be false in the corresponding edge-map.
-    void hide(const Edge& e) const { Parent::hide(e); }
-
-    /// \brief Unhides the node of the graph
-    ///
-    /// The value of \c n is set to be true in the node-map which stores
-    /// hide information. If \c n was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Node& n) const { Parent::unHide(n); }
-
-    /// \brief Unhides the edge of the graph
-    ///
-    /// The value of \c e is set to be true in the edge-map which stores
-    /// hide information. If \c e was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Edge& e) const { Parent::unHide(e); }
-
-    /// \brief Returns true if \c n is hidden.
-    ///
-    /// Returns true if \c n is hidden.
-    ///
-    bool hidden(const Node& n) const { return Parent::hidden(n); }
-
-    /// \brief Returns true if \c e is hidden.
-    ///
-    /// Returns true if \c e is hidden.
-    ///
-    bool hidden(const Edge& e) const { return Parent::hidden(e); }
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Sets the status of the given edge
+    ///
+    /// This function sets the status of the given edge.
+    /// It is done by simply setting the assigned value of \c e
+    /// to \c v in the edge filter map.
+    void status(const Edge& e, bool v) const { Parent::status(e, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Returns the status of the given edge
+    ///
+    /// This function returns the status of the given edge.
+    /// It is \c true if the given edge is enabled (i.e. not hidden).
+    bool status(const Edge& e) const { return Parent::status(e); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Disables the given edge
+    ///
+    /// This function disables the given edge in the subgraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(e, false)".
+    void disable(const Edge& e) const { Parent::status(e, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node in the subdigraph.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+    /// \brief Enables the given edge
+    ///
+    /// This function enables the given edge in the subgraph.
+    /// It is the same as \ref status() "status(e, true)".
+    void enable(const Edge& e) const { Parent::status(e, true); }
+
   };
 
-  /// \brief Just gives back a subgraph
-  ///
-  /// Just gives back a subgraph
-  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
-  SubGraph<const Graph, NodeFilterMap, ArcFilterMap>
-  subGraph(const Graph& graph, NodeFilterMap& nfm, ArcFilterMap& efm) {
-    return SubGraph<const Graph, NodeFilterMap, ArcFilterMap>(graph, nfm, efm);
+  /// \brief Returns a read-only SubGraph adaptor
+  ///
+  /// This function just returns a read-only \ref SubGraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SubGraph
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, NF, EF>
+  subGraph(const GR& graph,
+           NF& node_filter_map, EF& edge_filter_map) {
+    return SubGraph<const GR, NF, EF>
+      (graph, node_filter_map, edge_filter_map);
   }
 
-  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
-  SubGraph<const Graph, const NodeFilterMap, ArcFilterMap>
-  subGraph(const Graph& graph,
-           const NodeFilterMap& nfm, ArcFilterMap& efm) {
-    return SubGraph<const Graph, const NodeFilterMap, ArcFilterMap>
-      (graph, nfm, efm);
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, const NF, EF>
+  subGraph(const GR& graph,
+           const NF& node_filter_map, EF& edge_filter_map) {
+    return SubGraph<const GR, const NF, EF>
+      (graph, node_filter_map, edge_filter_map);
   }
 
-  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
-  SubGraph<const Graph, NodeFilterMap, const ArcFilterMap>
-  subGraph(const Graph& graph,
-           NodeFilterMap& nfm, const ArcFilterMap& efm) {
-    return SubGraph<const Graph, NodeFilterMap, const ArcFilterMap>
-      (graph, nfm, efm);
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, NF, const EF>
+  subGraph(const GR& graph,
+           NF& node_filter_map, const EF& edge_filter_map) {
+    return SubGraph<const GR, NF, const EF>
+      (graph, node_filter_map, edge_filter_map);
   }
 
-  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
-  SubGraph<const Graph, const NodeFilterMap, const ArcFilterMap>
-  subGraph(const Graph& graph,
-           const NodeFilterMap& nfm, const ArcFilterMap& efm) {
-    return SubGraph<const Graph, const NodeFilterMap, const ArcFilterMap>
-      (graph, nfm, efm);
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, const NF, const EF>
+  subGraph(const GR& graph,
+           const NF& node_filter_map, const EF& edge_filter_map) {
+    return SubGraph<const GR, const NF, const EF>
+      (graph, node_filter_map, edge_filter_map);
   }
 
+
   /// \ingroup graph_adaptors
   ///
-  /// \brief An adaptor for hiding nodes from a digraph or a graph.
-  ///
-  /// FilterNodes adaptor hides nodes in a graph or a digraph. A bool
-  /// node map must be specified, which defines the filters for
-  /// nodes. Just the unfiltered nodes and the arcs or edges incident
-  /// to unfiltered nodes are shown in the subdigraph or subgraph. The
-  /// FilterNodes is conform to the \ref concepts::Digraph
-  /// "Digraph concept" or \ref concepts::Graph "Graph concept" depending
-  /// on the \c _Digraph template parameter. If the \c _checked
-  /// parameter is true, then the arc or edges incident to filtered nodes
-  /// are also filtered out.
-  ///
-  /// \tparam _Digraph It must be conform to the \ref
-  /// concepts::Digraph "Digraph concept" or \ref concepts::Graph
-  /// "Graph concept". The type can be specified to be const.
-  /// \tparam _NodeFilterMap A bool valued node map of the the adapted graph.
-  /// \tparam _checked If the parameter is false then the arc or edge
-  /// filtering is not checked with respect to node filter. In this
-  /// case just isolated nodes can be filtered out from the
-  /// graph.
+  /// \brief Adaptor class for hiding nodes in a digraph or a graph.
+  ///
+  /// FilterNodes adaptor can be used for hiding nodes in a digraph or a
+  /// graph. A \c bool node map must be specified, which defines the filter
+  /// for the nodes. Only the nodes with \c true filter value and the
+  /// arcs/edges incident to nodes both with \c true filter value are shown
+  /// in the subgraph. This adaptor conforms to the \ref concepts::Digraph
+  /// "Digraph" concept or the \ref concepts::Graph "Graph" concept
+  /// depending on the \c GR template parameter.
+  ///
+  /// The adapted (di)graph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs/edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph or graph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept
+  /// or the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted (di)graph. The default type is
+  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
+  ///
+  /// \note The \c Node and <tt>Arc/Edge</tt> types of this adaptor and the
+  /// adapted (di)graph are convertible to each other.
 #ifdef DOXYGEN
-  template<typename _Digraph,
-           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
-           bool _checked = true>
+  template<typename GR, typename NF>
+  class FilterNodes {
 #else
-  template<typename _Digraph,
-           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
-           bool _checked = true,
+  template<typename GR,
+           typename NF = typename GR::template NodeMap<bool>,
            typename Enable = void>
+  class FilterNodes :
+    public DigraphAdaptorExtender<
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, bool>, true> > {
 #endif
-  class FilterNodes
-    : public SubDigraph<_Digraph, _NodeFilterMap,
-                        ConstMap<typename _Digraph::Arc, bool>, _checked> {
-  public:
-
-    typedef _Digraph Digraph;
-    typedef _NodeFilterMap NodeFilterMap;
-
-    typedef SubDigraph<Digraph, NodeFilterMap,
-                       ConstMap<typename Digraph::Arc, bool>, _checked>
-    Parent;
+  public:
+
+    typedef GR Digraph;
+    typedef NF NodeFilterMap;
+
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, bool>, true> >
+      Parent;
 
     typedef typename Parent::Node Node;
@@ -1413,45 +1506,54 @@
     /// \brief Constructor
     ///
-    /// Creates an adaptor for the given digraph or graph with
+    /// Creates a subgraph for the given digraph or graph with the
     /// given node filter map.
-    FilterNodes(Digraph& _digraph, NodeFilterMap& node_filter) :
-      Parent(), const_true_map(true) {
-      Parent::setDigraph(_digraph);
+    FilterNodes(GR& graph, NodeFilterMap& node_filter) :
+      Parent(), const_true_map(true)
+    {
+      Parent::setDigraph(graph);
       Parent::setNodeFilterMap(node_filter);
       Parent::setArcFilterMap(const_true_map);
     }
 
-    /// \brief Hides the node of the graph
-    ///
-    /// This function hides \c n in the digraph or graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c n
-    /// to be false in the corresponding node map.
-    void hide(const Node& n) const { Parent::hide(n); }
-
-    /// \brief Unhides the node of the graph
-    ///
-    /// The value of \c n is set to be true in the node-map which stores
-    /// hide information. If \c n was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Node& n) const { Parent::unHide(n); }
-
-    /// \brief Returns true if \c n is hidden.
-    ///
-    /// Returns true if \c n is hidden.
-    ///
-    bool hidden(const Node& n) const { return Parent::hidden(n); }
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node, so the iteration
+    /// jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
 
   };
 
-  template<typename _Graph, typename _NodeFilterMap, bool _checked>
-  class FilterNodes<_Graph, _NodeFilterMap, _checked,
-                    typename enable_if<UndirectedTagIndicator<_Graph> >::type>
-    : public SubGraph<_Graph, _NodeFilterMap,
-                      ConstMap<typename _Graph::Edge, bool>, _checked> {
-  public:
-    typedef _Graph Graph;
-    typedef _NodeFilterMap NodeFilterMap;
-    typedef SubGraph<Graph, NodeFilterMap,
-                     ConstMap<typename Graph::Edge, bool> > Parent;
+  template<typename GR, typename NF>
+  class FilterNodes<GR, NF,
+                    typename enable_if<UndirectedTagIndicator<GR> >::type> :
+    public GraphAdaptorExtender<
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, bool>, true> > {
+
+  public:
+    typedef GR Graph;
+    typedef NF NodeFilterMap;
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, bool>, true> >
+      Parent;
 
     typedef typename Parent::Node Node;
@@ -1472,49 +1574,73 @@
     }
 
-    void hide(const Node& n) const { Parent::hide(n); }
-    void unHide(const Node& n) const { Parent::unHide(n); }
-    bool hidden(const Node& n) const { return Parent::hidden(n); }
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+    bool status(const Node& n) const { return Parent::status(n); }
+    void disable(const Node& n) const { Parent::status(n, false); }
+    void enable(const Node& n) const { Parent::status(n, true); }
 
   };
 
 
-  /// \brief Just gives back a FilterNodes adaptor
-  ///
-  /// Just gives back a FilterNodes adaptor
-  template<typename Digraph, typename NodeFilterMap>
-  FilterNodes<const Digraph, NodeFilterMap>
-  filterNodes(const Digraph& digraph, NodeFilterMap& nfm) {
-    return FilterNodes<const Digraph, NodeFilterMap>(digraph, nfm);
+  /// \brief Returns a read-only FilterNodes adaptor
+  ///
+  /// This function just returns a read-only \ref FilterNodes adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterNodes
+  template<typename GR, typename NF>
+  FilterNodes<const GR, NF>
+  filterNodes(const GR& graph, NF& node_filter_map) {
+    return FilterNodes<const GR, NF>(graph, node_filter_map);
   }
 
-  template<typename Digraph, typename NodeFilterMap>
-  FilterNodes<const Digraph, const NodeFilterMap>
-  filterNodes(const Digraph& digraph, const NodeFilterMap& nfm) {
-    return FilterNodes<const Digraph, const NodeFilterMap>(digraph, nfm);
+  template<typename GR, typename NF>
+  FilterNodes<const GR, const NF>
+  filterNodes(const GR& graph, const NF& node_filter_map) {
+    return FilterNodes<const GR, const NF>(graph, node_filter_map);
   }
 
   /// \ingroup graph_adaptors
   ///
-  /// \brief An adaptor for hiding arcs from a digraph.
-  ///
-  /// FilterArcs adaptor hides arcs in a digraph. A bool arc map must
-  /// be specified, which defines the filters for arcs. Just the
-  /// unfiltered arcs are shown in the subdigraph. The FilterArcs is
-  /// conform to the \ref concepts::Digraph "Digraph concept".
-  ///
-  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
-  /// "Digraph concept". The type can be specified to be const.
-  /// \tparam _ArcFilterMap A bool valued arc map of the the adapted
-  /// graph.
-  template<typename _Digraph, typename _ArcFilterMap>
+  /// \brief Adaptor class for hiding arcs in a digraph.
+  ///
+  /// FilterArcs adaptor can be used for hiding arcs in a digraph.
+  /// A \c bool arc map must be specified, which defines the filter for
+  /// the arcs. Only the arcs with \c true filter value are shown in the
+  /// subdigraph. This adaptor conforms to the \ref concepts::Digraph
+  /// "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam AF The type of the arc filter map.
+  /// It must be a \c bool (or convertible) arc map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<bool>".
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename AF>
+  class FilterArcs {
+#else
+  template<typename GR,
+           typename AF = typename GR::template ArcMap<bool> >
   class FilterArcs :
-    public SubDigraph<_Digraph, ConstMap<typename _Digraph::Node, bool>,
-                      _ArcFilterMap, false> {
-  public:
-    typedef _Digraph Digraph;
-    typedef _ArcFilterMap ArcFilterMap;
-
-    typedef SubDigraph<Digraph, ConstMap<typename Digraph::Node, bool>,
-                       ArcFilterMap, false> Parent;
+    public DigraphAdaptorExtender<
+      SubDigraphBase<GR, ConstMap<typename GR::Node, bool>, AF, false> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef GR Digraph;
+    /// The type of the arc filter map.
+    typedef AF ArcFilterMap;
+
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<GR, ConstMap<typename GR::Node, bool>, AF, false> >
+      Parent;
 
     typedef typename Parent::Arc Arc;
@@ -1531,6 +1657,6 @@
     /// \brief Constructor
     ///
-    /// Creates a FilterArcs adaptor for the given graph with
-    /// given arc map filter.
+    /// Creates a subdigraph for the given digraph with the given arc
+    /// filter map.
     FilterArcs(Digraph& digraph, ArcFilterMap& arc_filter)
       : Parent(), const_true_map(true) {
@@ -1540,64 +1666,96 @@
     }
 
-    /// \brief Hides the arc of the graph
-    ///
-    /// This function hides \c a in the graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c a
-    /// to be false in the corresponding arc map.
-    void hide(const Arc& a) const { Parent::hide(a); }
-
-    /// \brief Unhides the arc of the graph
-    ///
-    /// The value of \c a is set to be true in the arc-map which stores
-    /// hide information. If \c a was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Arc& a) const { Parent::unHide(a); }
-
-    /// \brief Returns true if \c a is hidden.
-    ///
-    /// Returns true if \c a is hidden.
-    ///
-    bool hidden(const Arc& a) const { return Parent::hidden(a); }
+    /// \brief Sets the status of the given arc
+    ///
+    /// This function sets the status of the given arc.
+    /// It is done by simply setting the assigned value of \c a
+    /// to \c v in the arc filter map.
+    void status(const Arc& a, bool v) const { Parent::status(a, v); }
+
+    /// \brief Returns the status of the given arc
+    ///
+    /// This function returns the status of the given arc.
+    /// It is \c true if the given arc is enabled (i.e. not hidden).
+    bool status(const Arc& a) const { return Parent::status(a); }
+
+    /// \brief Disables the given arc
+    ///
+    /// This function disables the given arc in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(a, false)".
+    void disable(const Arc& a) const { Parent::status(a, false); }
+
+    /// \brief Enables the given arc
+    ///
+    /// This function enables the given arc in the subdigraph.
+    /// It is the same as \ref status() "status(a, true)".
+    void enable(const Arc& a) const { Parent::status(a, true); }
 
   };
 
-  /// \brief Just gives back an FilterArcs adaptor
-  ///
-  /// Just gives back an FilterArcs adaptor
-  template<typename Digraph, typename ArcFilterMap>
-  FilterArcs<const Digraph, ArcFilterMap>
-  filterArcs(const Digraph& digraph, ArcFilterMap& afm) {
-    return FilterArcs<const Digraph, ArcFilterMap>(digraph, afm);
+  /// \brief Returns a read-only FilterArcs adaptor
+  ///
+  /// This function just returns a read-only \ref FilterArcs adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterArcs
+  template<typename GR, typename AF>
+  FilterArcs<const GR, AF>
+  filterArcs(const GR& digraph, AF& arc_filter_map) {
+    return FilterArcs<const GR, AF>(digraph, arc_filter_map);
   }
 
-  template<typename Digraph, typename ArcFilterMap>
-  FilterArcs<const Digraph, const ArcFilterMap>
-  filterArcs(const Digraph& digraph, const ArcFilterMap& afm) {
-    return FilterArcs<const Digraph, const ArcFilterMap>(digraph, afm);
+  template<typename GR, typename AF>
+  FilterArcs<const GR, const AF>
+  filterArcs(const GR& digraph, const AF& arc_filter_map) {
+    return FilterArcs<const GR, const AF>(digraph, arc_filter_map);
   }
 
   /// \ingroup graph_adaptors
   ///
-  /// \brief An adaptor for hiding edges from a graph.
-  ///
-  /// FilterEdges adaptor hides edges in a digraph. A bool edge map must
-  /// be specified, which defines the filters for edges. Just the
-  /// unfiltered edges are shown in the subdigraph. The FilterEdges is
-  /// conform to the \ref concepts::Graph "Graph concept".
-  ///
-  /// \tparam _Graph It must be conform to the \ref concepts::Graph
-  /// "Graph concept". The type can be specified to be const.
-  /// \tparam _EdgeFilterMap A bool valued edge map of the the adapted
-  /// graph.
-  template<typename _Graph, typename _EdgeFilterMap>
+  /// \brief Adaptor class for hiding edges in a graph.
+  ///
+  /// FilterEdges adaptor can be used for hiding edges in a graph.
+  /// A \c bool edge map must be specified, which defines the filter for
+  /// the edges. Only the edges with \c true filter value are shown in the
+  /// subgraph. This adaptor conforms to the \ref concepts::Graph
+  /// "Graph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam EF The type of the edge filter map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
+  /// adapted graph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename EF>
+  class FilterEdges {
+#else
+  template<typename GR,
+           typename EF = typename GR::template EdgeMap<bool> >
   class FilterEdges :
-    public SubGraph<_Graph, ConstMap<typename _Graph::Node,bool>,
-                    _EdgeFilterMap, false> {
-  public:
-    typedef _Graph Graph;
-    typedef _EdgeFilterMap EdgeFilterMap;
-    typedef SubGraph<Graph, ConstMap<typename Graph::Node,bool>,
-                     EdgeFilterMap, false> Parent;
+    public GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node,bool>, EF, false> > {
+#endif
+  public:
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the edge filter map.
+    typedef EF EdgeFilterMap;
+
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node,bool>, EF, false> >
+      Parent;
+
     typedef typename Parent::Edge Edge;
+
   protected:
     ConstMap<typename Graph::Node, bool> const_true_map;
@@ -1611,49 +1769,58 @@
     /// \brief Constructor
     ///
-    /// Creates a FilterEdges adaptor for the given graph with
-    /// given edge map filters.
-    FilterEdges(Graph& _graph, EdgeFilterMap& edge_filter_map) :
+    /// Creates a subgraph for the given graph with the given edge
+    /// filter map.
+    FilterEdges(Graph& graph, EdgeFilterMap& edge_filter_map) :
       Parent(), const_true_map(true) {
-      Parent::setGraph(_graph);
+      Parent::setGraph(graph);
       Parent::setNodeFilterMap(const_true_map);
       Parent::setEdgeFilterMap(edge_filter_map);
     }
 
-    /// \brief Hides the edge of the graph
-    ///
-    /// This function hides \c e in the graph, i.e. the iteration
-    /// jumps over it. This is done by simply setting the value of \c e
-    /// to be false in the corresponding edge-map.
-    void hide(const Edge& e) const { Parent::hide(e); }
-
-    /// \brief Unhides the edge of the graph
-    ///
-    /// The value of \c e is set to be true in the edge-map which stores
-    /// hide information. If \c e was hidden previuosly, then it is shown
-    /// again
-    void unHide(const Edge& e) const { Parent::unHide(e); }
-
-    /// \brief Returns true if \c e is hidden.
-    ///
-    /// Returns true if \c e is hidden.
-    ///
-    bool hidden(const Edge& e) const { return Parent::hidden(e); }
+    /// \brief Sets the status of the given edge
+    ///
+    /// This function sets the status of the given edge.
+    /// It is done by simply setting the assigned value of \c e
+    /// to \c v in the edge filter map.
+    void status(const Edge& e, bool v) const { Parent::status(e, v); }
+
+    /// \brief Returns the status of the given edge
+    ///
+    /// This function returns the status of the given edge.
+    /// It is \c true if the given edge is enabled (i.e. not hidden).
+    bool status(const Edge& e) const { return Parent::status(e); }
+
+    /// \brief Disables the given edge
+    ///
+    /// This function disables the given edge in the subgraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(e, false)".
+    void disable(const Edge& e) const { Parent::status(e, false); }
+
+    /// \brief Enables the given edge
+    ///
+    /// This function enables the given edge in the subgraph.
+    /// It is the same as \ref status() "status(e, true)".
+    void enable(const Edge& e) const { Parent::status(e, true); }
 
   };
 
-  /// \brief Just gives back a FilterEdges adaptor
-  ///
-  /// Just gives back a FilterEdges adaptor
-  template<typename Graph, typename EdgeFilterMap>
-  FilterEdges<const Graph, EdgeFilterMap>
-  filterEdges(const Graph& graph, EdgeFilterMap& efm) {
-    return FilterEdges<const Graph, EdgeFilterMap>(graph, efm);
+  /// \brief Returns a read-only FilterEdges adaptor
+  ///
+  /// This function just returns a read-only \ref FilterEdges adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterEdges
+  template<typename GR, typename EF>
+  FilterEdges<const GR, EF>
+  filterEdges(const GR& graph, EF& edge_filter_map) {
+    return FilterEdges<const GR, EF>(graph, edge_filter_map);
   }
 
-  template<typename Graph, typename EdgeFilterMap>
-  FilterEdges<const Graph, const EdgeFilterMap>
-  filterEdges(const Graph& graph, const EdgeFilterMap& efm) {
-    return FilterEdges<const Graph, const EdgeFilterMap>(graph, efm);
+  template<typename GR, typename EF>
+  FilterEdges<const GR, const EF>
+  filterEdges(const GR& graph, const EF& edge_filter_map) {
+    return FilterEdges<const GR, const EF>(graph, edge_filter_map);
   }
+
 
   template <typename _Digraph>
@@ -1695,6 +1862,4 @@
       }
     };
-
-
 
     void first(Node& n) const {
@@ -1846,10 +2011,13 @@
 
     typedef NodeNumTagIndicator<Digraph> NodeNumTag;
-    int nodeNum() const { return 2 * _digraph->arcNum(); }
-    typedef EdgeNumTagIndicator<Digraph> EdgeNumTag;
+    int nodeNum() const { return _digraph->nodeNum(); }
+
+    typedef ArcNumTagIndicator<Digraph> ArcNumTag;
     int arcNum() const { return 2 * _digraph->arcNum(); }
+
+    typedef ArcNumTag EdgeNumTag;
     int edgeNum() const { return _digraph->arcNum(); }
 
-    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
     Arc findArc(Node s, Node t, Arc p = INVALID) const {
       if (p == INVALID) {
@@ -1870,4 +2038,5 @@
     }
 
+    typedef FindArcTag FindEdgeTag;
     Edge findEdge(Node s, Node t, Edge p = INVALID) const {
       if (s != t) {
@@ -1877,5 +2046,5 @@
           arc = _digraph->findArc(t, s);
           if (arc != INVALID) return arc;
-        } else if (_digraph->s(p) == s) {
+        } else if (_digraph->source(p) == s) {
           Edge arc = _digraph->findArc(s, t, p);
           if (arc != INVALID) return arc;
@@ -1906,4 +2075,8 @@
       typedef _Value Value;
       typedef Arc Key;
+      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<MapImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReference;
+      typedef typename MapTraits<MapImpl>::ReturnValue Reference;
 
       ArcMapBase(const Adaptor& adaptor) :
@@ -1921,6 +2094,5 @@
       }
 
-      typename MapTraits<MapImpl>::ConstReturnValue
-      operator[](const Arc& a) const {
+      ConstReturnValue operator[](const Arc& a) const {
         if (direction(a)) {
           return _forward[a];
@@ -1930,6 +2102,5 @@
       }
 
-      typename MapTraits<MapImpl>::ReturnValue
-      operator[](const Arc& a) {
+      ReturnValue operator[](const Arc& a) {
         if (direction(a)) {
           return _forward[a];
@@ -1981,5 +2152,5 @@
       typedef SubMapExtender<Adaptor, ArcMapBase<Value> > Parent;
 
-      ArcMap(const Adaptor& adaptor)
+      explicit ArcMap(const Adaptor& adaptor)
         : Parent(adaptor) {}
 
@@ -2028,4 +2199,7 @@
     NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
 
+    typedef typename ItemSetTraits<Digraph, Edge>::ItemNotifier EdgeNotifier;
+    EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
+
   protected:
 
@@ -2042,20 +2216,36 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief Undirect the graph
-  ///
-  /// This adaptor makes an undirected graph from a directed
-  /// graph. All arcs of the underlying digraph will be showed in the
-  /// adaptor as an edge. The Orienter adaptor is conform to the \ref
-  /// concepts::Graph "Graph concept".
-  ///
-  /// \tparam _Digraph It must be conform to the \ref
-  /// concepts::Digraph "Digraph concept". The type can be specified
-  /// to const.
-  template<typename _Digraph>
-  class Undirector
-    : public GraphAdaptorExtender<UndirectorBase<_Digraph> > {
-  public:
-    typedef _Digraph Digraph;
-    typedef GraphAdaptorExtender<UndirectorBase<Digraph> > Parent;
+  /// \brief Adaptor class for viewing a digraph as an undirected graph.
+  ///
+  /// Undirector adaptor can be used for viewing a digraph as an undirected
+  /// graph. All arcs of the underlying digraph are showed in the
+  /// adaptor as an edge (and also as a pair of arcs, of course).
+  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It can also be specified to be \c const.
+  ///
+  /// \note The \c Node type of this adaptor and the adapted digraph are
+  /// convertible to each other, moreover the \c Edge type of the adaptor
+  /// and the \c Arc type of the adapted digraph are also convertible to
+  /// each other.
+  /// (Thus the \c Arc type of the adaptor is convertible to the \c Arc type
+  /// of the adapted digraph.)
+  template<typename GR>
+#ifdef DOXYGEN
+  class Undirector {
+#else
+  class Undirector :
+    public GraphAdaptorExtender<UndirectorBase<GR> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef GR Digraph;
+    typedef GraphAdaptorExtender<UndirectorBase<GR> > Parent;
   protected:
     Undirector() { }
@@ -2064,35 +2254,36 @@
     /// \brief Constructor
     ///
-    /// Creates a undirected graph from the given digraph
-    Undirector(_Digraph& digraph) {
+    /// Creates an undirected graph from the given digraph.
+    Undirector(Digraph& digraph) {
       setDigraph(digraph);
     }
 
-    /// \brief ArcMap combined from two original ArcMap
-    ///
-    /// This class adapts two original digraph ArcMap to
-    /// get an arc map on the undirected graph.
-    template <typename _ForwardMap, typename _BackwardMap>
+    /// \brief Arc map combined from two original arc maps
+    ///
+    /// This map adaptor class adapts two arc maps of the underlying
+    /// digraph to get an arc map of the undirected graph.
+    /// Its value type is inherited from the first arc map type
+    /// (\c %ForwardMap).
+    template <typename ForwardMap, typename BackwardMap>
     class CombinedArcMap {
     public:
 
-      typedef _ForwardMap ForwardMap;
-      typedef _BackwardMap BackwardMap;
+      /// The key type of the map
+      typedef typename Parent::Arc Key;
+      /// The value type of the map
+      typedef typename ForwardMap::Value Value;
 
       typedef typename MapTraits<ForwardMap>::ReferenceMapTag ReferenceMapTag;
 
-      typedef typename ForwardMap::Value Value;
-      typedef typename Parent::Arc Key;
-
-      /// \brief Constructor
-      ///
+      typedef typename MapTraits<ForwardMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ForwardMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ForwardMap>::ReturnValue Reference;
+      typedef typename MapTraits<ForwardMap>::ConstReturnValue ConstReference;
+
       /// Constructor
       CombinedArcMap(ForwardMap& forward, BackwardMap& backward)
         : _forward(&forward), _backward(&backward) {}
 
-
-      /// \brief Sets the value associated with a key.
-      ///
-      /// Sets the value associated with a key.
+      /// Sets the value associated with the given key.
       void set(const Key& e, const Value& a) {
         if (Parent::direction(e)) {
@@ -2103,9 +2294,6 @@
       }
 
-      /// \brief Returns the value associated with a key.
-      ///
-      /// Returns the value associated with a key.
-      typename MapTraits<ForwardMap>::ConstReturnValue
-      operator[](const Key& e) const {
+      /// Returns the value associated with the given key.
+      ConstReturnValue operator[](const Key& e) const {
         if (Parent::direction(e)) {
           return (*_forward)[e];
@@ -2115,9 +2303,6 @@
       }
 
-      /// \brief Returns the value associated with a key.
-      ///
-      /// Returns the value associated with a key.
-      typename MapTraits<ForwardMap>::ReturnValue
-      operator[](const Key& e) {
+      /// Returns a reference to the value associated with the given key.
+      ReturnValue operator[](const Key& e) {
         if (Parent::direction(e)) {
           return (*_forward)[e];
@@ -2134,7 +2319,7 @@
     };
 
-    /// \brief Just gives back a combined arc map
-    ///
-    /// Just gives back a combined arc map
+    /// \brief Returns a combined arc map
+    ///
+    /// This function just returns a combined arc map.
     template <typename ForwardMap, typename BackwardMap>
     static CombinedArcMap<ForwardMap, BackwardMap>
@@ -2166,12 +2351,14 @@
   };
 
-  /// \brief Just gives back an undirected view of the given digraph
-  ///
-  /// Just gives back an undirected view of the given digraph
-  template<typename Digraph>
-  Undirector<const Digraph>
-  undirector(const Digraph& digraph) {
-    return Undirector<const Digraph>(digraph);
+  /// \brief Returns a read-only Undirector adaptor
+  ///
+  /// This function just returns a read-only \ref Undirector adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates Undirector
+  template<typename GR>
+  Undirector<const GR> undirector(const GR& digraph) {
+    return Undirector<const GR>(digraph);
   }
+
 
   template <typename _Graph, typename _DirectionMap>
@@ -2192,10 +2379,10 @@
     void first(Arc& i) const { _graph->first(i); }
     void firstIn(Arc& i, const Node& n) const {
-      bool d;
+      bool d = true;
       _graph->firstInc(i, d, n);
       while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
     }
     void firstOut(Arc& i, const Node& n ) const {
-      bool d;
+      bool d = true;
       _graph->firstInc(i, d, n);
       while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
@@ -2225,22 +2412,13 @@
     int nodeNum() const { return _graph->nodeNum(); }
 
-    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
+    typedef EdgeNumTagIndicator<Graph> ArcNumTag;
     int arcNum() const { return _graph->edgeNum(); }
 
-    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    typedef FindEdgeTagIndicator<Graph> FindArcTag;
     Arc findArc(const Node& u, const Node& v,
-                const Arc& prev = INVALID) {
-      Arc arc = prev;
-      bool d = arc == INVALID ? true : (*_direction)[arc];
-      if (d) {
+                const Arc& prev = INVALID) const {
+      Arc arc = _graph->findEdge(u, v, prev);
+      while (arc != INVALID && source(arc) != u) {
         arc = _graph->findEdge(u, v, arc);
-        while (arc != INVALID && !(*_direction)[arc]) {
-          _graph->findEdge(u, v, arc);
-        }
-        if (arc != INVALID) return arc;
-      }
-      _graph->findEdge(v, u, arc);
-      while (arc != INVALID && (*_direction)[arc]) {
-        _graph->findEdge(u, v, arc);
       }
       return arc;
@@ -2252,6 +2430,6 @@
 
     Arc addArc(const Node& u, const Node& v) {
-      Arc arc = _graph->addArc(u, v);
-      _direction->set(arc, _graph->source(arc) == u);
+      Arc arc = _graph->addEdge(u, v);
+      _direction->set(arc, _graph->u(arc) == u);
       return arc;
     }
@@ -2344,26 +2522,47 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief Orients the edges of the graph to get a digraph
-  ///
-  /// This adaptor orients each edge in the undirected graph. The
-  /// direction of the arcs stored in an edge node map.  The arcs can
-  /// be easily reverted by the \c reverseArc() member function in the
-  /// adaptor. The Orienter adaptor is conform to the \ref
-  /// concepts::Digraph "Digraph concept".
-  ///
-  /// \tparam _Graph It must be conform to the \ref concepts::Graph
-  /// "Graph concept". The type can be specified to be const.
-  /// \tparam _DirectionMap A bool valued edge map of the the adapted
-  /// graph.
-  ///
-  /// \sa orienter
-  template<typename _Graph,
-           typename DirectionMap = typename _Graph::template EdgeMap<bool> >
+  /// \brief Adaptor class for orienting the edges of a graph to get a digraph
+  ///
+  /// Orienter adaptor can be used for orienting the edges of a graph to
+  /// get a digraph. A \c bool edge map of the underlying graph must be
+  /// specified, which define the direction of the arcs in the adaptor.
+  /// The arcs can be easily reversed by the \c reverseArc() member function
+  /// of the adaptor.
+  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam DM The type of the direction map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node type of this adaptor and the adapted graph are
+  /// convertible to each other, moreover the \c Arc type of the adaptor
+  /// and the \c Edge type of the adapted graph are also convertible to
+  /// each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename DM>
+  class Orienter {
+#else
+  template<typename GR,
+           typename DM = typename GR::template EdgeMap<bool> >
   class Orienter :
-    public DigraphAdaptorExtender<OrienterBase<_Graph, DirectionMap> > {
-  public:
-    typedef _Graph Graph;
-    typedef DigraphAdaptorExtender<
-      OrienterBase<_Graph, DirectionMap> > Parent;
+    public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
+#endif
+  public:
+
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the direction edge map.
+    typedef DM DirectionMap;
+
+    typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
     typedef typename Parent::Arc Arc;
   protected:
@@ -2371,7 +2570,7 @@
   public:
 
-    /// \brief Constructor of the adaptor
-    ///
-    /// Constructor of the adaptor
+    /// \brief Constructor
+    ///
+    /// Constructor of the adaptor.
     Orienter(Graph& graph, DirectionMap& direction) {
       setGraph(graph);
@@ -2379,7 +2578,9 @@
     }
 
-    /// \brief Reverse arc
-    ///
-    /// It reverse the given arc. It simply negate the direction in the map.
+    /// \brief Reverses the given arc
+    ///
+    /// This function reverses the given arc.
+    /// It is done by simply negate the assigned value of \c a
+    /// in the direction map.
     void reverseArc(const Arc& a) {
       Parent::reverseArc(a);
@@ -2387,32 +2588,29 @@
   };
 
-  /// \brief Just gives back a Orienter
-  ///
-  /// Just gives back a Orienter
-  template<typename Graph, typename DirectionMap>
-  Orienter<const Graph, DirectionMap>
-  orienter(const Graph& graph, DirectionMap& dm) {
-    return Orienter<const Graph, DirectionMap>(graph, dm);
+  /// \brief Returns a read-only Orienter adaptor
+  ///
+  /// This function just returns a read-only \ref Orienter adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates Orienter
+  template<typename GR, typename DM>
+  Orienter<const GR, DM>
+  orienter(const GR& graph, DM& direction_map) {
+    return Orienter<const GR, DM>(graph, direction_map);
   }
 
-  template<typename Graph, typename DirectionMap>
-  Orienter<const Graph, const DirectionMap>
-  orienter(const Graph& graph, const DirectionMap& dm) {
-    return Orienter<const Graph, const DirectionMap>(graph, dm);
+  template<typename GR, typename DM>
+  Orienter<const GR, const DM>
+  orienter(const GR& graph, const DM& direction_map) {
+    return Orienter<const GR, const DM>(graph, direction_map);
   }
 
   namespace _adaptor_bits {
 
-    template<typename _Digraph,
-             typename _CapacityMap = typename _Digraph::template ArcMap<int>,
-             typename _FlowMap = _CapacityMap,
-             typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
+    template<typename Digraph,
+             typename CapacityMap,
+             typename FlowMap,
+             typename Tolerance>
     class ResForwardFilter {
     public:
-
-      typedef _Digraph Digraph;
-      typedef _CapacityMap CapacityMap;
-      typedef _FlowMap FlowMap;
-      typedef _Tolerance Tolerance;
 
       typedef typename Digraph::Arc Key;
@@ -2435,15 +2633,10 @@
     };
 
-    template<typename _Digraph,
-             typename _CapacityMap = typename _Digraph::template ArcMap<int>,
-             typename _FlowMap = _CapacityMap,
-             typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
+    template<typename Digraph,
+             typename CapacityMap,
+             typename FlowMap,
+             typename Tolerance>
     class ResBackwardFilter {
     public:
-
-      typedef _Digraph Digraph;
-      typedef _CapacityMap CapacityMap;
-      typedef _FlowMap FlowMap;
-      typedef _Tolerance Tolerance;
 
       typedef typename Digraph::Arc Key;
@@ -2471,51 +2664,72 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief An adaptor for composing the residual graph for directed
+  /// \brief Adaptor class for composing the residual digraph for directed
   /// flow and circulation problems.
   ///
-  /// An adaptor for composing the residual graph for directed flow and
-  /// circulation problems.  Let \f$ G=(V, A) \f$ be a directed graph
-  /// and let \f$ F \f$ be a number type. Let moreover \f$ f,c:A\to F \f$,
-  /// be functions on the arc-set.
-  ///
-  /// Then Residual implements the digraph structure with
-  /// node-set \f$ V \f$ and arc-set \f$ A_{forward}\cup A_{backward} \f$,
-  /// where \f$ A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\} \f$ and
-  /// \f$ A_{backward}=\{vu : uv\in A, f(uv)>0\} \f$, i.e. the so
-  /// called residual graph.  When we take the union
-  /// \f$ A_{forward}\cup A_{backward} \f$, multiplicities are counted,
-  /// i.e.  if an arc is in both \f$ A_{forward} \f$ and
-  /// \f$ A_{backward} \f$, then in the adaptor it appears in both
-  /// orientation.
-  ///
-  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
-  /// "Digraph concept". The type is implicitly const.
-  /// \tparam _CapacityMap An arc map of some numeric type, it defines
-  /// the capacities in the flow problem. The map is implicitly const.
-  /// \tparam _FlowMap An arc map of some numeric type, it defines
-  /// the capacities in the flow problem.
-  /// \tparam _Tolerance Handler for inexact computation.
-  template<typename _Digraph,
-           typename _CapacityMap = typename _Digraph::template ArcMap<int>,
-           typename _FlowMap = _CapacityMap,
-           typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
-  class Residual :
+  /// ResidualDigraph can be used for composing the \e residual digraph
+  /// for directed flow and circulation problems. Let \f$ G=(V, A) \f$
+  /// be a directed graph and let \f$ F \f$ be a number type.
+  /// Let \f$ flow, cap: A\to F \f$ be functions on the arcs.
+  /// This adaptor implements a digraph structure with node set \f$ V \f$
+  /// and arc set \f$ A_{forward}\cup A_{backward} \f$,
+  /// where \f$ A_{forward}=\{uv : uv\in A, flow(uv)<cap(uv)\} \f$ and
+  /// \f$ A_{backward}=\{vu : uv\in A, flow(uv)>0\} \f$, i.e. the so
+  /// called residual digraph.
+  /// When the union \f$ A_{forward}\cup A_{backward} \f$ is taken,
+  /// multiplicities are counted, i.e. the adaptor has exactly
+  /// \f$ |A_{forward}| + |A_{backward}|\f$ arcs (it may have parallel
+  /// arcs).
+  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It is implicitly \c const.
+  /// \tparam CM The type of the capacity map.
+  /// It must be an arc map of some numerical type, which defines
+  /// the capacities in the flow problem. It is implicitly \c const.
+  /// The default type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam FM The type of the flow map.
+  /// It must be an arc map of some numerical type, which defines
+  /// the flow values in the flow problem. The default type is \c CM.
+  /// \tparam TL The tolerance type for handling inexact computation.
+  /// The default tolerance type depends on the value type of the
+  /// capacity map.
+  ///
+  /// \note This adaptor is implemented using Undirector and FilterArcs
+  /// adaptors.
+  ///
+  /// \note The \c Node type of this adaptor and the adapted digraph are
+  /// convertible to each other, moreover the \c Arc type of the adaptor
+  /// is convertible to the \c Arc type of the adapted digraph.
+#ifdef DOXYGEN
+  template<typename GR, typename CM, typename FM, typename TL>
+  class ResidualDigraph
+#else
+  template<typename GR,
+           typename CM = typename GR::template ArcMap<int>,
+           typename FM = CM,
+           typename TL = Tolerance<typename CM::Value> >
+  class ResidualDigraph :
     public FilterArcs<
-    Undirector<const _Digraph>,
-    typename Undirector<const _Digraph>::template CombinedArcMap<
-      _adaptor_bits::ResForwardFilter<const _Digraph, _CapacityMap,
-                                      _FlowMap, _Tolerance>,
-      _adaptor_bits::ResBackwardFilter<const _Digraph, _CapacityMap,
-                                       _FlowMap, _Tolerance> > >
+      Undirector<const GR>,
+      typename Undirector<const GR>::template CombinedArcMap<
+        _adaptor_bits::ResForwardFilter<const GR, CM, FM, TL>,
+        _adaptor_bits::ResBackwardFilter<const GR, CM, FM, TL> > >
+#endif
   {
   public:
 
-    typedef _Digraph Digraph;
-    typedef _CapacityMap CapacityMap;
-    typedef _FlowMap FlowMap;
-    typedef _Tolerance Tolerance;
+    /// The type of the underlying digraph.
+    typedef GR Digraph;
+    /// The type of the capacity map.
+    typedef CM CapacityMap;
+    /// The type of the flow map.
+    typedef FM FlowMap;
+    /// The tolerance type.
+    typedef TL Tolerance;
 
     typedef typename CapacityMap::Value Value;
-    typedef Residual Adaptor;
+    typedef ResidualDigraph Adaptor;
 
   protected:
@@ -2530,5 +2744,5 @@
 
     typedef typename Undirected::
-    template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
+      template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
 
     typedef FilterArcs<Undirected, ArcFilter> Parent;
@@ -2544,10 +2758,10 @@
   public:
 
-    /// \brief Constructor of the residual digraph.
-    ///
-    /// Constructor of the residual graph. The parameters are the digraph,
-    /// the flow map, the capacity map and a tolerance object.
-    Residual(const Digraph& digraph, const CapacityMap& capacity,
-             FlowMap& flow, const Tolerance& tolerance = Tolerance())
+    /// \brief Constructor
+    ///
+    /// Constructor of the residual digraph adaptor. The parameters are the
+    /// digraph, the capacity map, the flow map, and a tolerance object.
+    ResidualDigraph(const Digraph& digraph, const CapacityMap& capacity,
+                    FlowMap& flow, const Tolerance& tolerance = Tolerance())
       : Parent(), _capacity(&capacity), _flow(&flow), _graph(digraph),
         _forward_filter(capacity, flow, tolerance),
@@ -2561,7 +2775,7 @@
     typedef typename Parent::Arc Arc;
 
-    /// \brief Gives back the residual capacity of the arc.
-    ///
-    /// Gives back the residual capacity of the arc.
+    /// \brief Returns the residual capacity of the given arc.
+    ///
+    /// Returns the residual capacity of the given arc.
     Value residualCapacity(const Arc& a) const {
       if (Undirected::direction(a)) {
@@ -2572,9 +2786,9 @@
     }
 
-    /// \brief Augment on the given arc in the residual graph.
-    ///
-    /// Augment on the given arc in the residual graph. It increase
-    /// or decrease the flow on the original arc depend on the direction
-    /// of the residual arc.
+    /// \brief Augments on the given arc in the residual digraph.
+    ///
+    /// Augments on the given arc in the residual digraph. It increases
+    /// or decreases the flow value on the original arc according to the
+    /// direction of the residual arc.
     void augment(const Arc& a, const Value& v) const {
       if (Undirected::direction(a)) {
@@ -2585,28 +2799,32 @@
     }
 
-    /// \brief Returns the direction of the arc.
-    ///
-    /// Returns true when the arc is same oriented as the original arc.
+    /// \brief Returns \c true if the given residual arc is a forward arc.
+    ///
+    /// Returns \c true if the given residual arc has the same orientation
+    /// as the original arc, i.e. it is a so called forward arc.
     static bool forward(const Arc& a) {
       return Undirected::direction(a);
     }
 
-    /// \brief Returns the direction of the arc.
-    ///
-    /// Returns true when the arc is opposite oriented as the original arc.
+    /// \brief Returns \c true if the given residual arc is a backward arc.
+    ///
+    /// Returns \c true if the given residual arc has the opposite orientation
+    /// than the original arc, i.e. it is a so called backward arc.
     static bool backward(const Arc& a) {
       return !Undirected::direction(a);
     }
 
-    /// \brief Gives back the forward oriented residual arc.
-    ///
-    /// Gives back the forward oriented residual arc.
+    /// \brief Returns the forward oriented residual arc.
+    ///
+    /// Returns the forward oriented residual arc related to the given
+    /// arc of the underlying digraph.
     static Arc forward(const typename Digraph::Arc& a) {
       return Undirected::direct(a, true);
     }
 
-    /// \brief Gives back the backward oriented residual arc.
-    ///
-    /// Gives back the backward oriented residual arc.
+    /// \brief Returns the backward oriented residual arc.
+    ///
+    /// Returns the backward oriented residual arc related to the given
+    /// arc of the underlying digraph.
     static Arc backward(const typename Digraph::Arc& a) {
       return Undirected::direct(a, false);
@@ -2615,19 +2833,20 @@
     /// \brief Residual capacity map.
     ///
-    /// In generic residual graph the residual capacity can be obtained
-    /// as a map.
+    /// This map adaptor class can be used for obtaining the residual
+    /// capacities as an arc map of the residual digraph.
+    /// Its value type is inherited from the capacity map.
     class ResidualCapacity {
     protected:
       const Adaptor* _adaptor;
     public:
-      /// The Key type
+      /// The key type of the map
       typedef Arc Key;
-      /// The Value type
-      typedef typename _CapacityMap::Value Value;
+      /// The value type of the map
+      typedef typename CapacityMap::Value Value;
 
       /// Constructor
       ResidualCapacity(const Adaptor& adaptor) : _adaptor(&adaptor) {}
 
-      /// \e
+      /// Returns the value associated with the given residual arc
       Value operator[](const Arc& a) const {
         return _adaptor->residualCapacity(a);
@@ -2636,5 +2855,24 @@
     };
 
+    /// \brief Returns a residual capacity map
+    ///
+    /// This function just returns a residual capacity map.
+    ResidualCapacity residualCapacity() const {
+      return ResidualCapacity(*this);
+    }
+
   };
+
+  /// \brief Returns a (read-only) Residual adaptor
+  ///
+  /// This function just returns a (read-only) \ref Residual adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates Residual
+  template<typename GR, typename CM, typename FM>
+  ResidualDigraph<GR, CM, FM>
+  residualDigraph(const GR& digraph, const CM& capacity_map, FM& flow_map) {
+    return ResidualDigraph<GR, CM, FM> (digraph, capacity_map, flow_map);
+  }
+
 
   template <typename _Digraph>
@@ -2885,28 +3123,24 @@
 
     typedef True NodeNumTag;
-
     int nodeNum() const {
       return  2 * countNodes(*_digraph);
     }
 
-    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
     int arcNum() const {
       return countArcs(*_digraph) + countNodes(*_digraph);
     }
 
-    typedef True FindEdgeTag;
+    typedef True FindArcTag;
     Arc findArc(const Node& u, const Node& v,
                 const Arc& prev = INVALID) const {
-      if (inNode(u)) {
-        if (outNode(v)) {
-          if (static_cast<const DigraphNode&>(u) ==
-              static_cast<const DigraphNode&>(v) && prev == INVALID) {
-            return Arc(u);
-          }
+      if (inNode(u) && outNode(v)) {
+        if (static_cast<const DigraphNode&>(u) ==
+            static_cast<const DigraphNode&>(v) && prev == INVALID) {
+          return Arc(u);
         }
-      } else {
-        if (inNode(v)) {
-          return Arc(::lemon::findArc(*_digraph, u, v, prev));
-        }
+      }
+      else if (outNode(u) && inNode(v)) {
+        return Arc(::lemon::findArc(*_digraph, u, v, prev));
       }
       return INVALID;
@@ -2922,4 +3156,9 @@
       typedef Node Key;
       typedef _Value Value;
+      typedef typename MapTraits<NodeImpl>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<NodeImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<NodeImpl>::ReturnValue Reference;
+      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReference;
 
       NodeMapBase(const Adaptor& adaptor)
@@ -2934,12 +3173,10 @@
       }
 
-      typename MapTraits<NodeImpl>::ReturnValue
-      operator[](const Node& key) {
+      ReturnValue operator[](const Node& key) {
         if (Adaptor::inNode(key)) { return _in_map[key]; }
         else { return _out_map[key]; }
       }
 
-      typename MapTraits<NodeImpl>::ConstReturnValue
-      operator[](const Node& key) const {
+      ConstReturnValue operator[](const Node& key) const {
         if (Adaptor::inNode(key)) { return _in_map[key]; }
         else { return _out_map[key]; }
@@ -2958,4 +3195,9 @@
       typedef Arc Key;
       typedef _Value Value;
+      typedef typename MapTraits<ArcImpl>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<ArcImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ArcImpl>::ReturnValue Reference;
+      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReference;
 
       ArcMapBase(const Adaptor& adaptor)
@@ -2973,6 +3215,5 @@
       }
 
-      typename MapTraits<ArcImpl>::ReturnValue
-      operator[](const Arc& key) {
+      ReturnValue operator[](const Arc& key) {
         if (Adaptor::origArc(key)) {
           return _arc_map[key._item.first()];
@@ -2982,6 +3223,5 @@
       }
 
-      typename MapTraits<ArcImpl>::ConstReturnValue
-      operator[](const Arc& key) const {
+      ConstReturnValue operator[](const Arc& key) const {
         if (Adaptor::origArc(key)) {
           return _arc_map[key._item.first()];
@@ -3064,29 +3304,39 @@
   /// \ingroup graph_adaptors
   ///
-  /// \brief Split the nodes of a directed graph
-  ///
-  /// The SplitNodes adaptor splits each node into an in-node and an
-  /// out-node. Formaly, the adaptor replaces each \f$ u \f$ node in
-  /// the digraph with two nodes(namely node \f$ u_{in} \f$ and node
-  /// \f$ u_{out} \f$). If there is a \f$ (v, u) \f$ arc in the
-  /// original digraph the new target of the arc will be \f$ u_{in} \f$
-  /// and similarly the source of the original \f$ (u, v) \f$ arc
-  /// will be \f$ u_{out} \f$.  The adaptor will add for each node in
-  /// the original digraph an additional arc which connects
-  /// \f$ (u_{in}, u_{out}) \f$.
-  ///
-  /// The aim of this class is to run algorithm with node costs if the
-  /// algorithm can use directly just arc costs. In this case we should use
-  /// a \c SplitNodes and set the node cost of the graph to the
-  /// bind arc in the adapted graph.
-  ///
-  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
-  /// "Digraph concept". The type can be specified to be const.
-  template <typename _Digraph>
+  /// \brief Adaptor class for splitting the nodes of a digraph.
+  ///
+  /// SplitNodes adaptor can be used for splitting each node into an
+  /// \e in-node and an \e out-node in a digraph. Formaly, the adaptor
+  /// replaces each node \f$ u \f$ in the digraph with two nodes,
+  /// namely node \f$ u_{in} \f$ and node \f$ u_{out} \f$.
+  /// If there is a \f$ (v, u) \f$ arc in the original digraph, then the
+  /// new target of the arc will be \f$ u_{in} \f$ and similarly the
+  /// source of each original \f$ (u, v) \f$ arc will be \f$ u_{out} \f$.
+  /// The adaptor adds an additional \e bind \e arc from \f$ u_{in} \f$
+  /// to \f$ u_{out} \f$ for each node \f$ u \f$ of the original digraph.
+  ///
+  /// The aim of this class is running an algorithm with respect to node
+  /// costs or capacities if the algorithm considers only arc costs or
+  /// capacities directly.
+  /// In this case you can use \c SplitNodes adaptor, and set the node
+  /// costs/capacities of the original digraph to the \e bind \e arcs
+  /// in the adaptor.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It is implicitly \c const.
+  ///
+  /// \note The \c Node type of this adaptor is converible to the \c Node
+  /// type of the adapted digraph.
+  template <typename GR>
+#ifdef DOXYGEN
+  class SplitNodes {
+#else
   class SplitNodes
-    : public DigraphAdaptorExtender<SplitNodesBase<_Digraph> > {
-  public:
-    typedef _Digraph Digraph;
-    typedef DigraphAdaptorExtender<SplitNodesBase<Digraph> > Parent;
+    : public DigraphAdaptorExtender<SplitNodesBase<const GR> > {
+#endif
+  public:
+    typedef GR Digraph;
+    typedef DigraphAdaptorExtender<SplitNodesBase<const GR> > Parent;
 
     typedef typename Digraph::Node DigraphNode;
@@ -3096,87 +3346,108 @@
     typedef typename Parent::Arc Arc;
 
-    /// \brief Constructor of the adaptor.
+    /// \brief Constructor
     ///
     /// Constructor of the adaptor.
-    SplitNodes(Digraph& g) {
+    SplitNodes(const Digraph& g) {
       Parent::setDigraph(g);
     }
 
-    /// \brief Returns true when the node is in-node.
-    ///
-    /// Returns true when the node is in-node.
+    /// \brief Returns \c true if the given node is an in-node.
+    ///
+    /// Returns \c true if the given node is an in-node.
     static bool inNode(const Node& n) {
       return Parent::inNode(n);
     }
 
-    /// \brief Returns true when the node is out-node.
-    ///
-    /// Returns true when the node is out-node.
+    /// \brief Returns \c true if the given node is an out-node.
+    ///
+    /// Returns \c true if the given node is an out-node.
     static bool outNode(const Node& n) {
       return Parent::outNode(n);
     }
 
-    /// \brief Returns true when the arc is arc in the original digraph.
-    ///
-    /// Returns true when the arc is arc in the original digraph.
+    /// \brief Returns \c true if the given arc is an original arc.
+    ///
+    /// Returns \c true if the given arc is one of the arcs in the
+    /// original digraph.
     static bool origArc(const Arc& a) {
       return Parent::origArc(a);
     }
 
-    /// \brief Returns true when the arc binds an in-node and an out-node.
-    ///
-    /// Returns true when the arc binds an in-node and an out-node.
+    /// \brief Returns \c true if the given arc is a bind arc.
+    ///
+    /// Returns \c true if the given arc is a bind arc, i.e. it connects
+    /// an in-node and an out-node.
     static bool bindArc(const Arc& a) {
       return Parent::bindArc(a);
     }
 
-    /// \brief Gives back the in-node created from the \c node.
-    ///
-    /// Gives back the in-node created from the \c node.
+    /// \brief Returns the in-node created from the given original node.
+    ///
+    /// Returns the in-node created from the given original node.
     static Node inNode(const DigraphNode& n) {
       return Parent::inNode(n);
     }
 
-    /// \brief Gives back the out-node created from the \c node.
-    ///
-    /// Gives back the out-node created from the \c node.
+    /// \brief Returns the out-node created from the given original node.
+    ///
+    /// Returns the out-node created from the given original node.
     static Node outNode(const DigraphNode& n) {
       return Parent::outNode(n);
     }
 
-    /// \brief Gives back the arc binds the two part of the node.
-    ///
-    /// Gives back the arc binds the two part of the node.
+    /// \brief Returns the bind arc that corresponds to the given
+    /// original node.
+    ///
+    /// Returns the bind arc in the adaptor that corresponds to the given
+    /// original node, i.e. the arc connecting the in-node and out-node
+    /// of \c n.
     static Arc arc(const DigraphNode& n) {
       return Parent::arc(n);
     }
 
-    /// \brief Gives back the arc of the original arc.
-    ///
-    /// Gives back the arc of the original arc.
+    /// \brief Returns the arc that corresponds to the given original arc.
+    ///
+    /// Returns the arc in the adaptor that corresponds to the given
+    /// original arc.
     static Arc arc(const DigraphArc& a) {
       return Parent::arc(a);
     }
 
-    /// \brief NodeMap combined from two original NodeMap
-    ///
-    /// This class adapt two of the original digraph NodeMap to
-    /// get a node map on the adapted digraph.
+    /// \brief Node map combined from two original node maps
+    ///
+    /// This map adaptor class adapts two node maps of the original digraph
+    /// to get a node map of the split digraph.
+    /// Its value type is inherited from the first node map type
+    /// (\c InNodeMap).
     template <typename InNodeMap, typename OutNodeMap>
     class CombinedNodeMap {
     public:
 
+      /// The key type of the map
       typedef Node Key;
+      /// The value type of the map
       typedef typename InNodeMap::Value Value;
 
-      /// \brief Constructor
-      ///
-      /// Constructor.
+      typedef typename MapTraits<InNodeMap>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<InNodeMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<InNodeMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<InNodeMap>::ReturnValue Reference;
+      typedef typename MapTraits<InNodeMap>::ConstReturnValue ConstReference;
+
+      /// Constructor
       CombinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map)
         : _in_map(in_map), _out_map(out_map) {}
 
-      /// \brief The subscript operator.
-      ///
-      /// The subscript operator.
+      /// Returns the value associated with the given key.
+      Value operator[](const Key& key) const {
+        if (Parent::inNode(key)) {
+          return _in_map[key];
+        } else {
+          return _out_map[key];
+        }
+      }
+
+      /// Returns a reference to the value associated with the given key.
       Value& operator[](const Key& key) {
         if (Parent::inNode(key)) {
@@ -3187,18 +3458,5 @@
       }
 
-      /// \brief The const subscript operator.
-      ///
-      /// The const subscript operator.
-      Value operator[](const Key& key) const {
-        if (Parent::inNode(key)) {
-          return _in_map[key];
-        } else {
-          return _out_map[key];
-        }
-      }
-
-      /// \brief The setter function of the map.
-      ///
-      /// The setter function of the map.
+      /// Sets the value associated with the given key.
       void set(const Key& key, const Value& value) {
         if (Parent::inNode(key)) {
@@ -3217,7 +3475,7 @@
 
 
-    /// \brief Just gives back a combined node map
-    ///
-    /// Just gives back a combined node map
+    /// \brief Returns a combined node map
+    ///
+    /// This function just returns a combined node map.
     template <typename InNodeMap, typename OutNodeMap>
     static CombinedNodeMap<InNodeMap, OutNodeMap>
@@ -3245,24 +3503,49 @@
     }
 
-    /// \brief ArcMap combined from an original ArcMap and a NodeMap
-    ///
-    /// This class adapt an original ArcMap and a NodeMap to get an
-    /// arc map on the adapted digraph
-    template <typename DigraphArcMap, typename DigraphNodeMap>
+    /// \brief Arc map combined from an arc map and a node map of the
+    /// original digraph.
+    ///
+    /// This map adaptor class adapts an arc map and a node map of the
+    /// original digraph to get an arc map of the split digraph.
+    /// Its value type is inherited from the original arc map type
+    /// (\c ArcMap).
+    template <typename ArcMap, typename NodeMap>
     class CombinedArcMap {
     public:
 
+      /// The key type of the map
       typedef Arc Key;
-      typedef typename DigraphArcMap::Value Value;
-
-      /// \brief Constructor
-      ///
-      /// Constructor.
-      CombinedArcMap(DigraphArcMap& arc_map, DigraphNodeMap& node_map)
+      /// The value type of the map
+      typedef typename ArcMap::Value Value;
+
+      typedef typename MapTraits<ArcMap>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<ArcMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ArcMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ArcMap>::ReturnValue Reference;
+      typedef typename MapTraits<ArcMap>::ConstReturnValue ConstReference;
+
+      /// Constructor
+      CombinedArcMap(ArcMap& arc_map, NodeMap& node_map)
         : _arc_map(arc_map), _node_map(node_map) {}
 
-      /// \brief The subscript operator.
-      ///
-      /// The subscript operator.
+      /// Returns the value associated with the given key.
+      Value operator[](const Key& arc) const {
+        if (Parent::origArc(arc)) {
+          return _arc_map[arc];
+        } else {
+          return _node_map[arc];
+        }
+      }
+
+      /// Returns a reference to the value associated with the given key.
+      Value& operator[](const Key& arc) {
+        if (Parent::origArc(arc)) {
+          return _arc_map[arc];
+        } else {
+          return _node_map[arc];
+        }
+      }
+
+      /// Sets the value associated with the given key.
       void set(const Arc& arc, const Value& val) {
         if (Parent::origArc(arc)) {
@@ -3273,74 +3556,49 @@
       }
 
-      /// \brief The const subscript operator.
-      ///
-      /// The const subscript operator.
-      Value operator[](const Key& arc) const {
-        if (Parent::origArc(arc)) {
-          return _arc_map[arc];
-        } else {
-          return _node_map[arc];
-        }
-      }
-
-      /// \brief The const subscript operator.
-      ///
-      /// The const subscript operator.
-      Value& operator[](const Key& arc) {
-        if (Parent::origArc(arc)) {
-          return _arc_map[arc];
-        } else {
-          return _node_map[arc];
-        }
-      }
-
     private:
-      DigraphArcMap& _arc_map;
-      DigraphNodeMap& _node_map;
+      ArcMap& _arc_map;
+      NodeMap& _node_map;
     };
 
-    /// \brief Just gives back a combined arc map
-    ///
-    /// Just gives back a combined arc map
-    template <typename DigraphArcMap, typename DigraphNodeMap>
-    static CombinedArcMap<DigraphArcMap, DigraphNodeMap>
-    combinedArcMap(DigraphArcMap& arc_map, DigraphNodeMap& node_map) {
-      return CombinedArcMap<DigraphArcMap, DigraphNodeMap>(arc_map, node_map);
-    }
-
-    template <typename DigraphArcMap, typename DigraphNodeMap>
-    static CombinedArcMap<const DigraphArcMap, DigraphNodeMap>
-    combinedArcMap(const DigraphArcMap& arc_map, DigraphNodeMap& node_map) {
-      return CombinedArcMap<const DigraphArcMap,
-        DigraphNodeMap>(arc_map, node_map);
-    }
-
-    template <typename DigraphArcMap, typename DigraphNodeMap>
-    static CombinedArcMap<DigraphArcMap, const DigraphNodeMap>
-    combinedArcMap(DigraphArcMap& arc_map, const DigraphNodeMap& node_map) {
-      return CombinedArcMap<DigraphArcMap,
-        const DigraphNodeMap>(arc_map, node_map);
-    }
-
-    template <typename DigraphArcMap, typename DigraphNodeMap>
-    static CombinedArcMap<const DigraphArcMap, const DigraphNodeMap>
-    combinedArcMap(const DigraphArcMap& arc_map,
-                   const DigraphNodeMap& node_map) {
-      return CombinedArcMap<const DigraphArcMap,
-        const DigraphNodeMap>(arc_map, node_map);
+    /// \brief Returns a combined arc map
+    ///
+    /// This function just returns a combined arc map.
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<ArcMap, NodeMap>
+    combinedArcMap(ArcMap& arc_map, NodeMap& node_map) {
+      return CombinedArcMap<ArcMap, NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<const ArcMap, NodeMap>
+    combinedArcMap(const ArcMap& arc_map, NodeMap& node_map) {
+      return CombinedArcMap<const ArcMap, NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<ArcMap, const NodeMap>
+    combinedArcMap(ArcMap& arc_map, const NodeMap& node_map) {
+      return CombinedArcMap<ArcMap, const NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<const ArcMap, const NodeMap>
+    combinedArcMap(const ArcMap& arc_map, const NodeMap& node_map) {
+      return CombinedArcMap<const ArcMap, const NodeMap>(arc_map, node_map);
     }
 
   };
 
-  /// \brief Just gives back a node splitter
-  ///
-  /// Just gives back a node splitter
-  template<typename Digraph>
-  SplitNodes<Digraph>
-  splitNodes(const Digraph& digraph) {
-    return SplitNodes<Digraph>(digraph);
+  /// \brief Returns a (read-only) SplitNodes adaptor
+  ///
+  /// This function just returns a (read-only) \ref SplitNodes adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SplitNodes
+  template<typename GR>
+  SplitNodes<GR>
+  splitNodes(const GR& digraph) {
+    return SplitNodes<GR>(digraph);
   }
 
-
 } //namespace lemon
 
Index: lemon/arg_parser.cc
===================================================================
--- lemon/arg_parser.cc	(revision 311)
+++ lemon/arg_parser.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: lemon/arg_parser.h
===================================================================
--- lemon/arg_parser.h	(revision 311)
+++ lemon/arg_parser.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: lemon/assert.h
===================================================================
--- lemon/assert.h	(revision 290)
+++ lemon/assert.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: lemon/base.cc
===================================================================
--- lemon/base.cc	(revision 220)
+++ lemon/base.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: lemon/bfs.h
===================================================================
--- lemon/bfs.h	(revision 437)
+++ lemon/bfs.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: lemon/bin_heap.h
===================================================================
--- lemon/bin_heap.h	(revision 209)
+++ lemon/bin_heap.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: lemon/bits/alteration_notifier.h
===================================================================
--- lemon/bits/alteration_notifier.h	(revision 373)
+++ lemon/bits/alteration_notifier.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: lemon/bits/array_map.h
===================================================================
--- lemon/bits/array_map.h	(revision 373)
+++ lemon/bits/array_map.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: lemon/bits/base_extender.h
===================================================================
--- lemon/bits/base_extender.h	(revision 373)
+++ lemon/bits/base_extender.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: lemon/bits/bezier.h
===================================================================
--- lemon/bits/bezier.h	(revision 314)
+++ lemon/bits/bezier.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: lemon/bits/default_map.h
===================================================================
--- lemon/bits/default_map.h	(revision 314)
+++ lemon/bits/default_map.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: lemon/bits/enable_if.h
===================================================================
--- lemon/bits/enable_if.h	(revision 314)
+++ lemon/bits/enable_if.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: lemon/bits/graph_adaptor_extender.h
===================================================================
--- lemon/bits/graph_adaptor_extender.h	(revision 432)
+++ lemon/bits/graph_adaptor_extender.h	(revision 478)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -174,8 +174,4 @@
   };
 
-
-  /// \ingroup digraphbits
-  ///
-  /// \brief Extender for the GraphAdaptors
   template <typename _Graph>
   class GraphAdaptorExtender : public _Graph {
Index: lemon/bits/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 373)
+++ lemon/bits/graph_extender.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: lemon/bits/map_extender.h
===================================================================
--- lemon/bits/map_extender.h	(revision 314)
+++ lemon/bits/map_extender.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: lemon/bits/path_dump.h
===================================================================
--- lemon/bits/path_dump.h	(revision 209)
+++ lemon/bits/path_dump.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: lemon/bits/solver_bits.h
===================================================================
--- lemon/bits/solver_bits.h	(revision 482)
+++ lemon/bits/solver_bits.h	(revision 482)
@@ -0,0 +1,191 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BITS_SOLVER_BITS_H
+#define LEMON_BITS_SOLVER_BITS_H
+
+namespace lemon {
+
+  namespace _solver_bits {
+
+    class VarIndex {
+    private:
+      struct ItemT {
+        int prev, next;
+        int index;
+      };
+      std::vector<ItemT> items;
+      int first_item, last_item, first_free_item;
+
+      std::vector<int> cross;
+
+    public:
+
+      VarIndex()
+        : first_item(-1), last_item(-1), first_free_item(-1) {
+      }
+
+      void clear() {
+        first_item = -1;
+        first_free_item = -1;
+        items.clear();
+        cross.clear();
+      }
+
+      int addIndex(int idx) {
+        int n;
+        if (first_free_item == -1) {
+          n = items.size();
+          items.push_back(ItemT());
+        } else {
+          n = first_free_item;
+          first_free_item = items[n].next;
+          if (first_free_item != -1) {
+            items[first_free_item].prev = -1;
+          }
+        }
+        items[n].index = idx;
+        if (static_cast<int>(cross.size()) <= idx) {
+          cross.resize(idx + 1, -1);
+        }
+        cross[idx] = n;
+
+        items[n].prev = last_item;
+        items[n].next = -1;
+        if (last_item != -1) {
+          items[last_item].next = n;
+        } else {
+          first_item = n;
+        }
+        last_item = n;
+
+        return n;
+      }
+
+      int addIndex(int idx, int n) {
+        while (n >= static_cast<int>(items.size())) {
+          items.push_back(ItemT());
+          items.back().prev = -1;
+          items.back().next = first_free_item;
+          if (first_free_item != -1) {
+            items[first_free_item].prev = items.size() - 1;
+          }
+          first_free_item = items.size() - 1;
+        }
+        if (items[n].next != -1) {
+          items[items[n].next].prev = items[n].prev;
+        }
+        if (items[n].prev != -1) {
+          items[items[n].prev].next = items[n].next;
+        } else {
+          first_free_item = items[n].next;
+        }
+
+        items[n].index = idx;
+        if (static_cast<int>(cross.size()) <= idx) {
+          cross.resize(idx + 1, -1);
+        }
+        cross[idx] = n;
+
+        items[n].prev = last_item;
+        items[n].next = -1;
+        if (last_item != -1) {
+          items[last_item].next = n;
+        } else {
+          first_item = n;
+        }
+        last_item = n;
+
+        return n;
+      }
+
+      void eraseIndex(int idx) {
+        int n = cross[idx];
+
+        if (items[n].prev != -1) {
+          items[items[n].prev].next = items[n].next;
+        } else {
+          first_item = items[n].next;
+        }
+        if (items[n].next != -1) {
+          items[items[n].next].prev = items[n].prev;
+        } else {
+          last_item = items[n].prev;
+        }
+
+        if (first_free_item != -1) {
+          items[first_free_item].prev = n;
+        }
+        items[n].next = first_free_item;
+        items[n].prev = -1;
+        first_free_item = n;
+
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      int maxIndex() const {
+        return cross.size() - 1;
+      }
+
+      void shiftIndices(int idx) {
+        for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
+          cross[i - 1] = cross[i];
+          if (cross[i] != -1) {
+            --items[cross[i]].index;
+          }
+        }
+        cross.back() = -1;
+        cross.pop_back();
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      void relocateIndex(int idx, int jdx) {
+        cross[idx] = cross[jdx];
+        items[cross[jdx]].index = idx;
+        cross[jdx] = -1;
+
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      int operator[](int idx) const {
+        return cross[idx];
+      }
+
+      int operator()(int fdx) const {
+        return items[fdx].index;
+      }
+
+      void firstItem(int& fdx) const {
+        fdx = first_item;
+      }
+
+      void nextItem(int& fdx) const {
+        fdx = items[fdx].next;
+      }
+
+    };
+  }
+}
+
+#endif
Index: lemon/bits/traits.h
===================================================================
--- lemon/bits/traits.h	(revision 372)
+++ lemon/bits/traits.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: lemon/bits/variant.h
===================================================================
--- lemon/bits/variant.h	(revision 432)
+++ lemon/bits/variant.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).
@@ -22,6 +22,6 @@
 #include <lemon/assert.h>
 
-/// \file
-/// \brief Variant types
+// \file
+// \brief Variant types
 
 namespace lemon {
@@ -37,25 +37,25 @@
 
 
-  /// \brief Simple Variant type for two types
-  ///
-  /// Simple Variant type for two types. The Variant type is a type
-  /// safe union. The C++ has strong limitations for using unions, by
-  /// example we can not store type with non default constructor or
-  /// destructor in an union. This class always knowns the current
-  /// state of the variant and it cares for the proper construction
-  /// and destruction.
+  // \brief Simple Variant type for two types
+  //
+  // Simple Variant type for two types. The Variant type is a type-safe
+  // union. C++ has strong limitations for using unions, for
+  // example you cannot store a type with non-default constructor or
+  // destructor in a union. This class always knowns the current
+  // state of the variant and it cares for the proper construction
+  // and destruction.
   template <typename _First, typename _Second>
   class BiVariant {
   public:
 
-    /// \brief The \c First type.
+    // \brief The \c First type.
     typedef _First First;
-    /// \brief The \c Second type.
+    // \brief The \c Second type.
     typedef _Second Second;
 
-    /// \brief Constructor
-    ///
-    /// This constructor initalizes to the default value of the \c First
-    /// type.
+    // \brief Constructor
+    //
+    // This constructor initalizes to the default value of the \c First
+    // type.
     BiVariant() {
       flag = true;
@@ -63,8 +63,8 @@
     }
 
-    /// \brief Constructor
-    ///
-    /// This constructor initalizes to the given value of the \c First
-    /// type.
+    // \brief Constructor
+    //
+    // This constructor initalizes to the given value of the \c First
+    // type.
     BiVariant(const First& f) {
       flag = true;
@@ -72,8 +72,8 @@
     }
 
-    /// \brief Constructor
-    ///
-    /// This constructor initalizes to the given value of the \c
-    /// Second type.
+    // \brief Constructor
+    //
+    // This constructor initalizes to the given value of the \c
+    // Second type.
     BiVariant(const Second& s) {
       flag = false;
@@ -81,7 +81,7 @@
     }
 
-    /// \brief Copy constructor
-    ///
-    /// Copy constructor
+    // \brief Copy constructor
+    //
+    // Copy constructor
     BiVariant(const BiVariant& bivariant) {
       flag = bivariant.flag;
@@ -93,15 +93,15 @@
     }
 
-    /// \brief Destrcutor
-    ///
-    /// Destructor
+    // \brief Destrcutor
+    //
+    // Destructor
     ~BiVariant() {
       destroy();
     }
 
-    /// \brief Set to the default value of the \c First type.
-    ///
-    /// This function sets the variant to the default value of the \c
-    /// First type.
+    // \brief Set to the default value of the \c First type.
+    //
+    // This function sets the variant to the default value of the \c
+    // First type.
     BiVariant& setFirst() {
       destroy();
@@ -111,8 +111,8 @@
     }
 
-    /// \brief Set to the given value of the \c First type.
-    ///
-    /// This function sets the variant to the given value of the \c
-    /// First type.
+    // \brief Set to the given value of the \c First type.
+    //
+    // This function sets the variant to the given value of the \c
+    // First type.
     BiVariant& setFirst(const First& f) {
       destroy();
@@ -122,8 +122,8 @@
     }
 
-    /// \brief Set to the default value of the \c Second type.
-    ///
-    /// This function sets the variant to the default value of the \c
-    /// Second type.
+    // \brief Set to the default value of the \c Second type.
+    //
+    // This function sets the variant to the default value of the \c
+    // Second type.
     BiVariant& setSecond() {
       destroy();
@@ -133,8 +133,8 @@
     }
 
-    /// \brief Set to the given value of the \c Second type.
-    ///
-    /// This function sets the variant to the given value of the \c
-    /// Second type.
+    // \brief Set to the given value of the \c Second type.
+    //
+    // This function sets the variant to the given value of the \c
+    // Second type.
     BiVariant& setSecond(const Second& s) {
       destroy();
@@ -144,15 +144,15 @@
     }
 
-    /// \brief Operator form of the \c setFirst()
+    // \brief Operator form of the \c setFirst()
     BiVariant& operator=(const First& f) {
       return setFirst(f);
     }
 
-    /// \brief Operator form of the \c setSecond()
+    // \brief Operator form of the \c setSecond()
     BiVariant& operator=(const Second& s) {
       return setSecond(s);
     }
 
-    /// \brief Assign operator
+    // \brief Assign operator
     BiVariant& operator=(const BiVariant& bivariant) {
       if (this == &bivariant) return *this;
@@ -167,58 +167,58 @@
     }
 
-    /// \brief Reference to the value
-    ///
-    /// Reference to the value of the \c First type.
-    /// \pre The BiVariant should store value of \c First type.
+    // \brief Reference to the value
+    //
+    // Reference to the value of the \c First type.
+    // \pre The BiVariant should store value of \c First type.
     First& first() {
       LEMON_DEBUG(flag, "Variant wrong state");
-      return *reinterpret_cast<First*>(data); 
-    }
-
-    /// \brief Const reference to the value
-    ///
-    /// Const reference to the value of the \c First type.
-    /// \pre The BiVariant should store value of \c First type.
-    const First& first() const { 
+      return *reinterpret_cast<First*>(data);
+    }
+
+    // \brief Const reference to the value
+    //
+    // Const reference to the value of the \c First type.
+    // \pre The BiVariant should store value of \c First type.
+    const First& first() const {
       LEMON_DEBUG(flag, "Variant wrong state");
-      return *reinterpret_cast<const First*>(data); 
-    }
-
-    /// \brief Operator form of the \c first()
+      return *reinterpret_cast<const First*>(data);
+    }
+
+    // \brief Operator form of the \c first()
     operator First&() { return first(); }
-    /// \brief Operator form of the const \c first()
+    // \brief Operator form of the const \c first()
     operator const First&() const { return first(); }
 
-    /// \brief Reference to the value
-    ///
-    /// Reference to the value of the \c Second type.
-    /// \pre The BiVariant should store value of \c Second type.
-    Second& second() { 
+    // \brief Reference to the value
+    //
+    // Reference to the value of the \c Second type.
+    // \pre The BiVariant should store value of \c Second type.
+    Second& second() {
       LEMON_DEBUG(!flag, "Variant wrong state");
-      return *reinterpret_cast<Second*>(data); 
-    }
-
-    /// \brief Const reference to the value
-    ///
-    /// Const reference to the value of the \c Second type.
-    /// \pre The BiVariant should store value of \c Second type.
-    const Second& second() const { 
+      return *reinterpret_cast<Second*>(data);
+    }
+
+    // \brief Const reference to the value
+    //
+    // Const reference to the value of the \c Second type.
+    // \pre The BiVariant should store value of \c Second type.
+    const Second& second() const {
       LEMON_DEBUG(!flag, "Variant wrong state");
-      return *reinterpret_cast<const Second*>(data); 
-    }
-
-    /// \brief Operator form of the \c second()
+      return *reinterpret_cast<const Second*>(data);
+    }
+
+    // \brief Operator form of the \c second()
     operator Second&() { return second(); }
-    /// \brief Operator form of the const \c second()
+    // \brief Operator form of the const \c second()
     operator const Second&() const { return second(); }
 
-    /// \brief %True when the variant is in the first state
-    ///
-    /// %True when the variant stores value of the \c First type.
+    // \brief %True when the variant is in the first state
+    //
+    // %True when the variant stores value of the \c First type.
     bool firstState() const { return flag; }
 
-    /// \brief %True when the variant is in the second state
-    ///
-    /// %True when the variant stores value of the \c Second type.
+    // \brief %True when the variant is in the second state
+    //
+    // %True when the variant stores value of the \c Second type.
     bool secondState() const { return !flag; }
 
@@ -290,38 +290,38 @@
   }
 
-  /// \brief Variant type
-  ///
-  /// Simple Variant type. The Variant type is a type safe union. The
-  /// C++ has strong limitations for using unions, for example we
-  /// cannot store type with non default constructor or destructor in
-  /// a union. This class always knowns the current state of the
-  /// variant and it cares for the proper construction and
-  /// destruction.
-  ///
-  /// \param _num The number of the types which can be stored in the
-  /// variant type.
-  /// \param _TypeMap This class describes the types of the Variant. The
-  /// _TypeMap::Map<index>::Type should be a valid type for each index
-  /// in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
-  /// class to define such type mappings up to 10 types.
-  ///
-  /// And the usage of the class:
-  ///\code
-  /// typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
-  /// MyVariant var;
-  /// var.set<0>(12);
-  /// std::cout << var.get<0>() << std::endl;
-  /// var.set<1>("alpha");
-  /// std::cout << var.get<1>() << std::endl;
-  /// var.set<2>(0.75);
-  /// std::cout << var.get<2>() << std::endl;
-  ///\endcode
-  ///
-  /// The result of course:
-  ///\code
-  /// 12
-  /// alpha
-  /// 0.75
-  ///\endcode
+  // \brief Variant type
+  //
+  // Simple Variant type. The Variant type is a type-safe union.
+  // C++ has strong limitations for using unions, for example you
+  // cannot store type with non-default constructor or destructor in
+  // a union. This class always knowns the current state of the
+  // variant and it cares for the proper construction and
+  // destruction.
+  //
+  // \param _num The number of the types which can be stored in the
+  // variant type.
+  // \param _TypeMap This class describes the types of the Variant. The
+  // _TypeMap::Map<index>::Type should be a valid type for each index
+  // in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
+  // class to define such type mappings up to 10 types.
+  //
+  // And the usage of the class:
+  //\code
+  // typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
+  // MyVariant var;
+  // var.set<0>(12);
+  // std::cout << var.get<0>() << std::endl;
+  // var.set<1>("alpha");
+  // std::cout << var.get<1>() << std::endl;
+  // var.set<2>(0.75);
+  // std::cout << var.get<2>() << std::endl;
+  //\endcode
+  //
+  // The result of course:
+  //\code
+  // 12
+  // alpha
+  // 0.75
+  //\endcode
   template <int _num, typename _TypeMap>
   class Variant {
@@ -332,8 +332,8 @@
     typedef _TypeMap TypeMap;
 
-    /// \brief Constructor
-    ///
-    /// This constructor initalizes to the default value of the \c type
-    /// with 0 index.
+    // \brief Constructor
+    //
+    // This constructor initalizes to the default value of the \c type
+    // with 0 index.
     Variant() {
       flag = 0;
@@ -343,7 +343,7 @@
 
 
-    /// \brief Copy constructor
-    ///
-    /// Copy constructor
+    // \brief Copy constructor
+    //
+    // Copy constructor
     Variant(const Variant& variant) {
       flag = variant.flag;
@@ -351,7 +351,7 @@
     }
 
-    /// \brief Assign operator
-    ///
-    /// Assign operator
+    // \brief Assign operator
+    //
+    // Assign operator
     Variant& operator=(const Variant& variant) {
       if (this == &variant) return *this;
@@ -364,15 +364,15 @@
     }
 
-    /// \brief Destrcutor
-    ///
-    /// Destructor
+    // \brief Destrcutor
+    //
+    // Destructor
     ~Variant() {
       _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
     }
 
-    /// \brief Set to the default value of the type with \c _idx index.
-    ///
-    /// This function sets the variant to the default value of the
-    /// type with \c _idx index.
+    // \brief Set to the default value of the type with \c _idx index.
+    //
+    // This function sets the variant to the default value of the
+    // type with \c _idx index.
     template <int _idx>
     Variant& set() {
@@ -384,8 +384,8 @@
     }
 
-    /// \brief Set to the given value of the type with \c _idx index.
-    ///
-    /// This function sets the variant to the given value of the type
-    /// with \c _idx index.
+    // \brief Set to the given value of the type with \c _idx index.
+    //
+    // This function sets the variant to the given value of the type
+    // with \c _idx index.
     template <int _idx>
     Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
@@ -397,7 +397,7 @@
     }
 
-    /// \brief Gets the current value of the type with \c _idx index.
-    ///
-    /// Gets the current value of the type with \c _idx index.
+    // \brief Gets the current value of the type with \c _idx index.
+    //
+    // Gets the current value of the type with \c _idx index.
     template <int _idx>
     const typename TypeMap::template Map<_idx>::Type& get() const {
@@ -407,7 +407,7 @@
     }
 
-    /// \brief Gets the current value of the type with \c _idx index.
-    ///
-    /// Gets the current value of the type with \c _idx index.
+    // \brief Gets the current value of the type with \c _idx index.
+    //
+    // Gets the current value of the type with \c _idx index.
     template <int _idx>
     typename _TypeMap::template Map<_idx>::Type& get() {
@@ -417,7 +417,7 @@
     }
 
-    /// \brief Returns the current state of the variant.
-    ///
-    /// Returns the current state of the variant.
+    // \brief Returns the current state of the variant.
+    //
+    // Returns the current state of the variant.
     int state() const {
       return flag;
@@ -451,5 +451,5 @@
 
     template <int _idx, typename _T0, typename _T1, typename _T2,
-              typename _T3, typename _T5, typename _T4, typename _T6,
+              typename _T3, typename _T4, typename _T5, typename _T6,
               typename _T7, typename _T8, typename _T9>
     struct Mapper {
@@ -470,13 +470,13 @@
   }
 
-  /// \brief Helper class for Variant
-  ///
-  /// Helper class to define type mappings for Variant. This class
-  /// converts the template parameters to be mappable by integer.
-  /// \see Variant
+  // \brief Helper class for Variant
+  //
+  // Helper class to define type mappings for Variant. This class
+  // converts the template parameters to be mappable by integer.
+  // \see Variant
   template <
     typename _T0,
     typename _T1 = void, typename _T2 = void, typename _T3 = void,
-    typename _T5 = void, typename _T4 = void, typename _T6 = void,
+    typename _T4 = void, typename _T5 = void, typename _T6 = void,
     typename _T7 = void, typename _T8 = void, typename _T9 = void>
   struct VariantTypeMap {
Index: lemon/bits/vector_map.h
===================================================================
--- lemon/bits/vector_map.h	(revision 373)
+++ lemon/bits/vector_map.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: lemon/circulation.h
===================================================================
--- lemon/circulation.h	(revision 437)
+++ lemon/circulation.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: lemon/clp.cc
===================================================================
--- lemon/clp.cc	(revision 485)
+++ lemon/clp.cc	(revision 485)
@@ -0,0 +1,437 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/clp.h>
+#include <coin/ClpSimplex.hpp>
+
+namespace lemon {
+
+  ClpLp::ClpLp() {
+    _prob = new ClpSimplex();
+    _init_temporals();
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  ClpLp::ClpLp(const ClpLp& other) {
+    _prob = new ClpSimplex(*other._prob);
+    rows = other.rows;
+    cols = other.cols;
+    _init_temporals();
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  ClpLp::~ClpLp() {
+    delete _prob;
+    _clear_temporals();
+  }
+
+  void ClpLp::_init_temporals() {
+    _primal_ray = 0;
+    _dual_ray = 0;
+  }
+
+  void ClpLp::_clear_temporals() {
+    if (_primal_ray) {
+      delete[] _primal_ray;
+      _primal_ray = 0;
+    }
+    if (_dual_ray) {
+      delete[] _dual_ray;
+      _dual_ray = 0;
+    }
+  }
+
+  ClpLp* ClpLp::_newSolver() const {
+    ClpLp* newlp = new ClpLp;
+    return newlp;
+  }
+
+  ClpLp* ClpLp::_cloneSolver() const {
+    ClpLp* copylp = new ClpLp(*this);
+    return copylp;
+  }
+
+  const char* ClpLp::_solverName() const { return "ClpLp"; }
+
+  int ClpLp::_addCol() {
+    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
+    return _prob->numberColumns() - 1;
+  }
+
+  int ClpLp::_addRow() {
+    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
+    return _prob->numberRows() - 1;
+  }
+
+
+  void ClpLp::_eraseCol(int c) {
+    _col_names_ref.erase(_prob->getColumnName(c));
+    _prob->deleteColumns(1, &c);
+  }
+
+  void ClpLp::_eraseRow(int r) {
+    _row_names_ref.erase(_prob->getRowName(r));
+    _prob->deleteRows(1, &r);
+  }
+
+  void ClpLp::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+
+  void ClpLp::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void ClpLp::_getColName(int c, std::string& name) const {
+    name = _prob->getColumnName(c);
+  }
+
+  void ClpLp::_setColName(int c, const std::string& name) {
+    _prob->setColumnName(c, const_cast<std::string&>(name));
+    _col_names_ref[name] = c;
+  }
+
+  int ClpLp::_colByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
+    return it != _col_names_ref.end() ? it->second : -1;
+  }
+
+  void ClpLp::_getRowName(int r, std::string& name) const {
+    name = _prob->getRowName(r);
+  }
+
+  void ClpLp::_setRowName(int r, const std::string& name) {
+    _prob->setRowName(r, const_cast<std::string&>(name));
+    _row_names_ref[name] = r;
+  }
+
+  int ClpLp::_rowByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
+    return it != _row_names_ref.end() ? it->second : -1;
+  }
+
+
+  void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
+    std::map<int, Value> coeffs;
+
+    int n = _prob->clpMatrix()->getNumCols();
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (int i = 0; i < n; ++i) {
+      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
+      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
+
+      const int* it = std::lower_bound(indices + begin, indices + end, ix);
+      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
+        coeffs[i] = 0.0;
+      }
+    }
+
+    for (ExprIterator it = b; it != e; ++it) {
+      coeffs[it->first] = it->second;
+    }
+
+    for (std::map<int, Value>::iterator it = coeffs.begin();
+         it != coeffs.end(); ++it) {
+      _prob->modifyCoefficient(ix, it->first, it->second);
+    }
+  }
+
+  void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
+    int n = _prob->clpMatrix()->getNumCols();
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (int i = 0; i < n; ++i) {
+      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
+      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
+
+      const int* it = std::lower_bound(indices + begin, indices + end, ix);
+      if (it != indices + end && *it == ix) {
+        *b = std::make_pair(i, elements[it - indices]);
+      }
+    }
+  }
+
+  void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
+    std::map<int, Value> coeffs;
+
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (CoinBigIndex i = begin; i != end; ++i) {
+      if (elements[i] != 0.0) {
+        coeffs[indices[i]] = 0.0;
+      }
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      coeffs[it->first] = it->second;
+    }
+    for (std::map<int, Value>::iterator it = coeffs.begin();
+         it != coeffs.end(); ++it) {
+      _prob->modifyCoefficient(it->first, ix, it->second);
+    }
+  }
+
+  void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (CoinBigIndex i = begin; i != end; ++i) {
+      *b = std::make_pair(indices[i], elements[i]);
+      ++b;
+    }
+  }
+
+  void ClpLp::_setCoeff(int ix, int jx, Value value) {
+    _prob->modifyCoefficient(ix, jx, value);
+  }
+
+  ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    const int* it = std::lower_bound(indices + begin, indices + end, jx);
+    if (it != indices + end && *it == jx) {
+      return elements[it - indices];
+    } else {
+      return 0.0;
+    }
+  }
+
+  void ClpLp::_setColLowerBound(int i, Value lo) {
+    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  ClpLp::Value ClpLp::_getColLowerBound(int i) const {
+    double val = _prob->getColLower()[i];
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void ClpLp::_setColUpperBound(int i, Value up) {
+    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  ClpLp::Value ClpLp::_getColUpperBound(int i) const {
+    double val = _prob->getColUpper()[i];
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void ClpLp::_setRowLowerBound(int i, Value lo) {
+    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
+    double val = _prob->getRowLower()[i];
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void ClpLp::_setRowUpperBound(int i, Value up) {
+    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
+    double val = _prob->getRowUpper()[i];
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    int num = _prob->clpMatrix()->getNumCols();
+    for (int i = 0; i < num; ++i) {
+      _prob->setObjectiveCoefficient(i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setObjectiveCoefficient(it->first, it->second);
+    }
+  }
+
+  void ClpLp::_getObjCoeffs(InsertIterator b) const {
+    int num = _prob->clpMatrix()->getNumCols();
+    for (int i = 0; i < num; ++i) {
+      Value coef = _prob->getObjCoefficients()[i];
+      if (coef != 0.0) {
+        *b = std::make_pair(i, coef);
+        ++b;
+      }
+    }
+  }
+
+  void ClpLp::_setObjCoeff(int i, Value obj_coef) {
+    _prob->setObjectiveCoefficient(i, obj_coef);
+  }
+
+  ClpLp::Value ClpLp::_getObjCoeff(int i) const {
+    return _prob->getObjCoefficients()[i];
+  }
+
+  ClpLp::SolveExitStatus ClpLp::_solve() {
+    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  ClpLp::SolveExitStatus ClpLp::solvePrimal() {
+    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  ClpLp::SolveExitStatus ClpLp::solveDual() {
+    return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  ClpLp::SolveExitStatus ClpLp::solveBarrier() {
+    return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  ClpLp::Value ClpLp::_getPrimal(int i) const {
+    return _prob->primalColumnSolution()[i];
+  }
+  ClpLp::Value ClpLp::_getPrimalValue() const {
+    return _prob->objectiveValue();
+  }
+
+  ClpLp::Value ClpLp::_getDual(int i) const {
+    return _prob->dualRowSolution()[i];
+  }
+
+  ClpLp::Value ClpLp::_getPrimalRay(int i) const {
+    if (!_primal_ray) {
+      _primal_ray = _prob->unboundedRay();
+      LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
+    }
+    return _primal_ray[i];
+  }
+
+  ClpLp::Value ClpLp::_getDualRay(int i) const {
+    if (!_dual_ray) {
+      _dual_ray = _prob->infeasibilityRay();
+      LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
+    }
+    return _dual_ray[i];
+  }
+
+  ClpLp::VarStatus ClpLp::_getColStatus(int i) const {
+    switch (_prob->getColumnStatus(i)) {
+    case ClpSimplex::basic:
+      return BASIC;
+    case ClpSimplex::isFree:
+      return FREE;
+    case ClpSimplex::atUpperBound:
+      return UPPER;
+    case ClpSimplex::atLowerBound:
+      return LOWER;
+    case ClpSimplex::isFixed:
+      return FIXED;
+    case ClpSimplex::superBasic:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return VarStatus();
+    }
+  }
+
+  ClpLp::VarStatus ClpLp::_getRowStatus(int i) const {
+    switch (_prob->getColumnStatus(i)) {
+    case ClpSimplex::basic:
+      return BASIC;
+    case ClpSimplex::isFree:
+      return FREE;
+    case ClpSimplex::atUpperBound:
+      return UPPER;
+    case ClpSimplex::atLowerBound:
+      return LOWER;
+    case ClpSimplex::isFixed:
+      return FIXED;
+    case ClpSimplex::superBasic:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return VarStatus();
+    }
+  }
+
+
+  ClpLp::ProblemType ClpLp::_getPrimalType() const {
+    if (_prob->isProvenOptimal()) {
+      return OPTIMAL;
+    } else if (_prob->isProvenPrimalInfeasible()) {
+      return INFEASIBLE;
+    } else if (_prob->isProvenDualInfeasible()) {
+      return UNBOUNDED;
+    } else {
+      return UNDEFINED;
+    }
+  }
+
+  ClpLp::ProblemType ClpLp::_getDualType() const {
+    if (_prob->isProvenOptimal()) {
+      return OPTIMAL;
+    } else if (_prob->isProvenDualInfeasible()) {
+      return INFEASIBLE;
+    } else if (_prob->isProvenPrimalInfeasible()) {
+      return INFEASIBLE;
+    } else {
+      return UNDEFINED;
+    }
+  }
+
+  void ClpLp::_setSense(ClpLp::Sense sense) {
+    switch (sense) {
+    case MIN:
+      _prob->setOptimizationDirection(1);
+      break;
+    case MAX:
+      _prob->setOptimizationDirection(-1);
+      break;
+    }
+  }
+
+  ClpLp::Sense ClpLp::_getSense() const {
+    double dir = _prob->optimizationDirection();
+    if (dir > 0.0) {
+      return MIN;
+    } else {
+      return MAX;
+    }
+  }
+
+  void ClpLp::_clear() {
+    delete _prob;
+    _prob = new ClpSimplex();
+    rows.clear();
+    cols.clear();
+    _col_names_ref.clear();
+    _clear_temporals();
+  }
+
+  void ClpLp::messageLevel(MessageLevel m) {
+    _prob->setLogLevel(static_cast<int>(m));
+  }
+
+} //END OF NAMESPACE LEMON
Index: lemon/clp.h
===================================================================
--- lemon/clp.h	(revision 485)
+++ lemon/clp.h	(revision 485)
@@ -0,0 +1,179 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_CLP_H
+#define LEMON_CLP_H
+
+///\file
+///\brief Header of the LEMON-CLP lp solver interface.
+
+#include <vector>
+#include <string>
+
+#include <lemon/lp_base.h>
+
+class ClpSimplex;
+
+namespace lemon {
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Interface for the CLP solver
+  ///
+  /// This class implements an interface for the Clp LP solver.  The
+  /// Clp library is an object oriented lp solver library developed at
+  /// the IBM. The CLP is part of the COIN-OR package and it can be
+  /// used with Common Public License.
+  class ClpLp : public LpSolver {
+  protected:
+
+    ClpSimplex* _prob;
+
+    std::map<std::string, int> _col_names_ref;
+    std::map<std::string, int> _row_names_ref;
+
+  public:
+
+    /// \e
+    ClpLp();
+    /// \e
+    ClpLp(const ClpLp&);
+    /// \e
+    ~ClpLp();
+
+  protected:
+
+    mutable double* _primal_ray;
+    mutable double* _dual_ray;
+
+    void _init_temporals();
+    void _clear_temporals();
+
+  protected:
+
+    virtual ClpLp* _newSolver() const;
+    virtual ClpLp* _cloneSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
+    virtual void _getObjCoeffs(InsertIterator) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual SolveExitStatus _solve();
+
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+    virtual void _clear();
+
+  public:
+
+    ///Solves LP with primal simplex method.
+    SolveExitStatus solvePrimal();
+
+    ///Solves LP with dual simplex method.
+    SolveExitStatus solveDual();
+
+    ///Solves LP with barrier method.
+    SolveExitStatus solveBarrier();
+
+    ///Returns the constraint identifier understood by CLP.
+    int clpRow(Row r) const { return rows(id(r)); }
+
+    ///Returns the variable identifier understood by CLP.
+    int clpCol(Col c) const { return cols(id(c)); }
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// print final solution
+      MESSAGE_FINAL_SOLUTION = 1,
+      /// print factorization
+      MESSAGE_FACTORIZATION = 2,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 3,
+      /// verbose output
+      MESSAGE_VERBOSE_OUTPUT = 4
+    };
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_CLP_H
+
Index: lemon/color.cc
===================================================================
--- lemon/color.cc	(revision 209)
+++ lemon/color.cc	(revision 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: lemon/color.h
===================================================================
--- lemon/color.h	(revision 313)
+++ lemon/color.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: lemon/concept_check.h
===================================================================
--- lemon/concept_check.h	(revision 285)
+++ lemon/concept_check.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: lemon/concepts/digraph.h
===================================================================
--- lemon/concepts/digraph.h	(revision 263)
+++ lemon/concepts/digraph.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: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 263)
+++ lemon/concepts/graph.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: lemon/concepts/graph_components.h
===================================================================
--- lemon/concepts/graph_components.h	(revision 313)
+++ lemon/concepts/graph_components.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: lemon/concepts/heap.h
===================================================================
--- lemon/concepts/heap.h	(revision 290)
+++ lemon/concepts/heap.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: lemon/concepts/maps.h
===================================================================
--- lemon/concepts/maps.h	(revision 314)
+++ lemon/concepts/maps.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: lemon/concepts/path.h
===================================================================
--- lemon/concepts/path.h	(revision 281)
+++ lemon/concepts/path.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: lemon/config.h.in
===================================================================
--- lemon/config.h.in	(revision 1)
+++ lemon/config.h.in	(revision 482)
@@ -1,2 +1,8 @@
+/* Define to 1 if you have any LP solver. */
+#undef HAVE_LP
+
+/* Define to 1 if you have any MIP solver. */
+#undef HAVE_MIP
+
 /* Define to 1 if you have CPLEX. */
 #undef HAVE_CPLEX
@@ -4,2 +10,8 @@
 /* Define to 1 if you have GLPK. */
 #undef HAVE_GLPK
+
+/* Define to 1 if you have SOPLEX */
+#undef HAVE_SOPLEX
+
+/* Define to 1 if you have CLP */
+#undef HAVE_CLP
Index: lemon/connectivity.h
===================================================================
--- lemon/connectivity.h	(revision 435)
+++ lemon/connectivity.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).
@@ -296,5 +296,5 @@
   /// direction.
   ///
-  /// \param graph The graph.
+  /// \param digraph The graph.
   /// \return The number of components
   /// \note By definition, the empty graph has zero
@@ -1226,5 +1226,5 @@
   /// that the given graph is DAG.
   ///
-  /// \param graph The graph. It must be directed and acyclic.
+  /// \param digraph The graph. It must be directed and acyclic.
   /// \retval order A readable - writable node map. The values will be set
   /// from 0 to the number of the nodes in the graph minus one. Each values
Index: lemon/core.h
===================================================================
--- lemon/core.h	(revision 319)
+++ lemon/core.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).
@@ -1171,6 +1171,6 @@
     /// Construct a new ConEdgeIt iterating on the edges that
     /// connects nodes \c u and \c v.
-    ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g) {
-      Parent::operator=(findEdge(_graph, u, v));
+    ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
+      Parent::operator=(findEdge(_graph, _u, _v));
     }
 
@@ -1184,10 +1184,10 @@
     /// It increments the iterator and gives back the next edge.
     ConEdgeIt& operator++() {
-      Parent::operator=(findEdge(_graph, _graph.u(*this),
-                                 _graph.v(*this), *this));
+      Parent::operator=(findEdge(_graph, _u, _v, *this));
       return *this;
     }
   private:
     const Graph& _graph;
+    Node _u, _v;
   };
 
Index: lemon/counter.h
===================================================================
--- lemon/counter.h	(revision 209)
+++ lemon/counter.h	(revision 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: lemon/cplex.cc
===================================================================
--- lemon/cplex.cc	(revision 485)
+++ lemon/cplex.cc	(revision 485)
@@ -0,0 +1,925 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <vector>
+#include <cstring>
+
+#include <lemon/cplex.h>
+
+extern "C" {
+#include <ilcplex/cplex.h>
+}
+
+
+///\file
+///\brief Implementation of the LEMON-CPLEX lp solver interface.
+namespace lemon {
+
+  CplexEnv::LicenseError::LicenseError(int status) {
+    if (!CPXgeterrorstring(0, status, _message)) {
+      std::strcpy(_message, "Cplex unknown error");
+    }
+  }
+
+  CplexEnv::CplexEnv() {
+    int status;
+    _cnt = new int;
+    _env = CPXopenCPLEX(&status);
+    if (_env == 0) {
+      delete _cnt;
+      _cnt = 0;
+      throw LicenseError(status);
+    }
+  }
+
+  CplexEnv::CplexEnv(const CplexEnv& other) {
+    _env = other._env;
+    _cnt = other._cnt;
+    ++(*_cnt);
+  }
+
+  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
+    _env = other._env;
+    _cnt = other._cnt;
+    ++(*_cnt);
+    return *this;
+  }
+
+  CplexEnv::~CplexEnv() {
+    --(*_cnt);
+    if (*_cnt == 0) {
+      delete _cnt;
+      CPXcloseCPLEX(&_env);
+    }
+  }
+
+  CplexBase::CplexBase() : LpBase() {
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+  }
+
+  CplexBase::CplexBase(const CplexEnv& env)
+    : LpBase(), _env(env) {
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+  }
+
+  CplexBase::CplexBase(const CplexBase& cplex)
+    : LpBase() {
+    int status;
+    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
+    rows = cplex.rows;
+    cols = cplex.cols;
+  }
+
+  CplexBase::~CplexBase() {
+    CPXfreeprob(cplexEnv(),&_prob);
+  }
+
+  int CplexBase::_addCol() {
+    int i = CPXgetnumcols(cplexEnv(), _prob);
+    double lb = -INF, ub = INF;
+    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
+    return i;
+  }
+
+
+  int CplexBase::_addRow() {
+    int i = CPXgetnumrows(cplexEnv(), _prob);
+    const double ub = INF;
+    const char s = 'L';
+    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
+    return i;
+  }
+
+
+  void CplexBase::_eraseCol(int i) {
+    CPXdelcols(cplexEnv(), _prob, i, i);
+  }
+
+  void CplexBase::_eraseRow(int i) {
+    CPXdelrows(cplexEnv(), _prob, i, i);
+  }
+
+  void CplexBase::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+  void CplexBase::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void CplexBase::_getColName(int col, std::string &name) const {
+    int size;
+    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
+    if (size == 0) {
+      name.clear();
+      return;
+    }
+
+    size *= -1;
+    std::vector<char> buf(size);
+    char *cname;
+    int tmp;
+    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
+                  &tmp, col, col);
+    name = cname;
+  }
+
+  void CplexBase::_setColName(int col, const std::string &name) {
+    char *cname;
+    cname = const_cast<char*>(name.c_str());
+    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
+  }
+
+  int CplexBase::_colByName(const std::string& name) const {
+    int index;
+    if (CPXgetcolindex(cplexEnv(), _prob,
+                       const_cast<char*>(name.c_str()), &index) == 0) {
+      return index;
+    }
+    return -1;
+  }
+
+  void CplexBase::_getRowName(int row, std::string &name) const {
+    int size;
+    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
+    if (size == 0) {
+      name.clear();
+      return;
+    }
+
+    size *= -1;
+    std::vector<char> buf(size);
+    char *cname;
+    int tmp;
+    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
+                  &tmp, row, row);
+    name = cname;
+  }
+
+  void CplexBase::_setRowName(int row, const std::string &name) {
+    char *cname;
+    cname = const_cast<char*>(name.c_str());
+    CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
+  }
+
+  int CplexBase::_rowByName(const std::string& name) const {
+    int index;
+    if (CPXgetrowindex(cplexEnv(), _prob,
+                       const_cast<char*>(name.c_str()), &index) == 0) {
+      return index;
+    }
+    return -1;
+  }
+
+  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
+                                      ExprIterator e)
+  {
+    std::vector<int> indices;
+    std::vector<int> rowlist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      rowlist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &rowlist.front(), &indices.front(), &values.front());
+  }
+
+  void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
+    int tmp1, tmp2, tmp3, length;
+    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
+               &indices.front(), &values.front(),
+               length, &tmp3, i, i);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+  }
+
+  void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
+    std::vector<int> indices;
+    std::vector<int> collist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      collist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &indices.front(), &collist.front(), &values.front());
+  }
+
+  void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
+
+    int tmp1, tmp2, tmp3, length;
+    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
+               &indices.front(), &values.front(),
+               length, &tmp3, i, i);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+
+  }
+
+  void CplexBase::_setCoeff(int row, int col, Value value) {
+    CPXchgcoef(cplexEnv(), _prob, row, col, value);
+  }
+
+  CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
+    CplexBase::Value value;
+    CPXgetcoef(cplexEnv(), _prob, row, col, &value);
+    return value;
+  }
+
+  void CplexBase::_setColLowerBound(int i, Value value) {
+    const char s = 'L';
+    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
+  }
+
+  CplexBase::Value CplexBase::_getColLowerBound(int i) const {
+    CplexBase::Value res;
+    CPXgetlb(cplexEnv(), _prob, &res, i, i);
+    return res <= -CPX_INFBOUND ? -INF : res;
+  }
+
+  void CplexBase::_setColUpperBound(int i, Value value)
+  {
+    const char s = 'U';
+    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
+  }
+
+  CplexBase::Value CplexBase::_getColUpperBound(int i) const {
+    CplexBase::Value res;
+    CPXgetub(cplexEnv(), _prob, &res, i, i);
+    return res >= CPX_INFBOUND ? INF : res;
+  }
+
+  CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
+    char s;
+    CPXgetsense(cplexEnv(), _prob, &s, i, i);
+    CplexBase::Value res;
+
+    switch (s) {
+    case 'G':
+    case 'R':
+    case 'E':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      return res <= -CPX_INFBOUND ? -INF : res;
+    default:
+      return -INF;
+    }
+  }
+
+  CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
+    char s;
+    CPXgetsense(cplexEnv(), _prob, &s, i, i);
+    CplexBase::Value res;
+
+    switch (s) {
+    case 'L':
+    case 'E':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      return res >= CPX_INFBOUND ? INF : res;
+    case 'R':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      {
+        double rng;
+        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
+        res += rng;
+      }
+      return res >= CPX_INFBOUND ? INF : res;
+    default:
+      return INF;
+    }
+  }
+
+  //This is easier to implement
+  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
+    if (lb == -INF) {
+      const char s = 'L';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
+    } else if (ub == INF) {
+      const char s = 'G';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+    } else if (lb == ub){
+      const char s = 'E';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+    } else {
+      const char s = 'R';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+      double len = ub - lb;
+      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
+    }
+  }
+
+  void CplexBase::_setRowLowerBound(int i, Value lb)
+  {
+    LEMON_ASSERT(lb != INF, "Invalid bound");
+    _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
+  }
+
+  void CplexBase::_setRowUpperBound(int i, Value ub)
+  {
+
+    LEMON_ASSERT(ub != -INF, "Invalid bound");
+    _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
+  }
+
+  void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
+  {
+    std::vector<int> indices;
+    std::vector<Value> values;
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+    }
+    CPXchgobj(cplexEnv(), _prob, values.size(),
+              &indices.front(), &values.front());
+
+  }
+
+  void CplexBase::_getObjCoeffs(InsertIterator b) const
+  {
+    int num = CPXgetnumcols(cplexEnv(), _prob);
+    std::vector<Value> x(num);
+
+    CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
+    for (int i = 0; i < num; ++i) {
+      if (x[i] != 0.0) {
+        *b = std::make_pair(i, x[i]);
+        ++b;
+      }
+    }
+  }
+
+  void CplexBase::_setObjCoeff(int i, Value obj_coef)
+  {
+    CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
+  }
+
+  CplexBase::Value CplexBase::_getObjCoeff(int i) const
+  {
+    Value x;
+    CPXgetobj(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  void CplexBase::_setSense(CplexBase::Sense sense) {
+    switch (sense) {
+    case MIN:
+      CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
+      break;
+    case MAX:
+      CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
+      break;
+    }
+  }
+
+  CplexBase::Sense CplexBase::_getSense() const {
+    switch (CPXgetobjsen(cplexEnv(), _prob)) {
+    case CPX_MIN:
+      return MIN;
+    case CPX_MAX:
+      return MAX;
+    default:
+      LEMON_ASSERT(false, "Invalid sense");
+      return CplexBase::Sense();
+    }
+  }
+
+  void CplexBase::_clear() {
+    CPXfreeprob(cplexEnv(),&_prob);
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+    rows.clear();
+    cols.clear();
+  }
+
+  // CplexLp members
+
+  CplexLp::CplexLp()
+    : LpBase(), CplexBase(), LpSolver() {}
+
+  CplexLp::CplexLp(const CplexEnv& env)
+    : LpBase(), CplexBase(env), LpSolver() {}
+
+  CplexLp::CplexLp(const CplexLp& other)
+    : LpBase(), CplexBase(other), LpSolver() {}
+
+  CplexLp::~CplexLp() {}
+
+  CplexLp* CplexLp::_newSolver() const { return new CplexLp; }
+  CplexLp* CplexLp::_cloneSolver() const {return new CplexLp(*this); }
+
+  const char* CplexLp::_solverName() const { return "CplexLp"; }
+
+  void CplexLp::_clear_temporals() {
+    _col_status.clear();
+    _row_status.clear();
+    _primal_ray.clear();
+    _dual_ray.clear();
+  }
+
+  // The routine returns zero unless an error occurred during the
+  // optimization. Examples of errors include exhausting available
+  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
+  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
+  // user-specified CPLEX limit, or proving the model infeasible or
+  // unbounded, are not considered errors. Note that a zero return
+  // value does not necessarily mean that a solution exists. Use query
+  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
+  // further information about the status of the optimization.
+  CplexLp::SolveExitStatus CplexLp::convertStatus(int status) {
+#if CPX_VERSION >= 800
+    if (status == 0) {
+      switch (CPXgetstat(cplexEnv(), _prob)) {
+      case CPX_STAT_OPTIMAL:
+      case CPX_STAT_INFEASIBLE:
+      case CPX_STAT_UNBOUNDED:
+        return SOLVED;
+      default:
+        return UNSOLVED;
+      }
+    } else {
+      return UNSOLVED;
+    }
+#else
+    if (status == 0) {
+      //We want to exclude some cases
+      switch (CPXgetstat(cplexEnv(), _prob)) {
+      case CPX_OBJ_LIM:
+      case CPX_IT_LIM_FEAS:
+      case CPX_IT_LIM_INFEAS:
+      case CPX_TIME_LIM_FEAS:
+      case CPX_TIME_LIM_INFEAS:
+        return UNSOLVED;
+      default:
+        return SOLVED;
+      }
+    } else {
+      return UNSOLVED;
+    }
+#endif
+  }
+
+  CplexLp::SolveExitStatus CplexLp::_solve() {
+    _clear_temporals();
+    return convertStatus(CPXlpopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solvePrimal() {
+    _clear_temporals();
+    return convertStatus(CPXprimopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solveDual() {
+    _clear_temporals();
+    return convertStatus(CPXdualopt(cplexEnv(), _prob));
+  }
+
+  CplexLp::SolveExitStatus CplexLp::solveBarrier() {
+    _clear_temporals();
+    return convertStatus(CPXbaropt(cplexEnv(), _prob));
+  }
+
+  CplexLp::Value CplexLp::_getPrimal(int i) const {
+    Value x;
+    CPXgetx(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  CplexLp::Value CplexLp::_getDual(int i) const {
+    Value y;
+    CPXgetpi(cplexEnv(), _prob, &y, i, i);
+    return y;
+  }
+
+  CplexLp::Value CplexLp::_getPrimalValue() const {
+    Value objval;
+    CPXgetobjval(cplexEnv(), _prob, &objval);
+    return objval;
+  }
+
+  CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
+    if (_col_status.empty()) {
+      _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
+      CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
+    }
+    switch (_col_status[i]) {
+    case CPX_BASIC:
+      return BASIC;
+    case CPX_FREE_SUPER:
+      return FREE;
+    case CPX_AT_LOWER:
+      return LOWER;
+    case CPX_AT_UPPER:
+      return UPPER;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return CplexLp::VarStatus();
+    }
+  }
+
+  CplexLp::VarStatus CplexLp::_getRowStatus(int i) const {
+    if (_row_status.empty()) {
+      _row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
+      CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
+    }
+    switch (_row_status[i]) {
+    case CPX_BASIC:
+      return BASIC;
+    case CPX_AT_LOWER:
+      {
+        char s;
+        CPXgetsense(cplexEnv(), _prob, &s, i, i);
+        return s != 'L' ? LOWER : UPPER;
+      }
+    case CPX_AT_UPPER:
+      return UPPER;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return CplexLp::VarStatus();
+    }
+  }
+
+  CplexLp::Value CplexLp::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
+      CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
+    }
+    return _primal_ray[i];
+  }
+
+  CplexLp::Value CplexLp::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+
+    }
+    return _dual_ray[i];
+  }
+
+  //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
+  // This table lists the statuses, returned by the CPXgetstat()
+  // routine, for solutions to LP problems or mixed integer problems. If
+  // no solution exists, the return value is zero.
+
+  // For Simplex, Barrier
+  // 1          CPX_OPTIMAL
+  //          Optimal solution found
+  // 2          CPX_INFEASIBLE
+  //          Problem infeasible
+  // 3    CPX_UNBOUNDED
+  //          Problem unbounded
+  // 4          CPX_OBJ_LIM
+  //          Objective limit exceeded in Phase II
+  // 5          CPX_IT_LIM_FEAS
+  //          Iteration limit exceeded in Phase II
+  // 6          CPX_IT_LIM_INFEAS
+  //          Iteration limit exceeded in Phase I
+  // 7          CPX_TIME_LIM_FEAS
+  //          Time limit exceeded in Phase II
+  // 8          CPX_TIME_LIM_INFEAS
+  //          Time limit exceeded in Phase I
+  // 9          CPX_NUM_BEST_FEAS
+  //          Problem non-optimal, singularities in Phase II
+  // 10         CPX_NUM_BEST_INFEAS
+  //          Problem non-optimal, singularities in Phase I
+  // 11         CPX_OPTIMAL_INFEAS
+  //          Optimal solution found, unscaled infeasibilities
+  // 12         CPX_ABORT_FEAS
+  //          Aborted in Phase II
+  // 13         CPX_ABORT_INFEAS
+  //          Aborted in Phase I
+  // 14          CPX_ABORT_DUAL_INFEAS
+  //          Aborted in barrier, dual infeasible
+  // 15          CPX_ABORT_PRIM_INFEAS
+  //          Aborted in barrier, primal infeasible
+  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
+  //          Aborted in barrier, primal and dual infeasible
+  // 17          CPX_ABORT_PRIM_DUAL_FEAS
+  //          Aborted in barrier, primal and dual feasible
+  // 18          CPX_ABORT_CROSSOVER
+  //          Aborted in crossover
+  // 19          CPX_INForUNBD
+  //          Infeasible or unbounded
+  // 20   CPX_PIVOT
+  //       User pivot used
+  //
+  //     Ezeket hova tegyem:
+  // ??case CPX_ABORT_DUAL_INFEAS
+  // ??case CPX_ABORT_CROSSOVER
+  // ??case CPX_INForUNBD
+  // ??case CPX_PIVOT
+
+  //Some more interesting stuff:
+
+  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
+  // 0 Automatic
+  // 1 Primal Simplex
+  // 2 Dual Simplex
+  // 3 Network Simplex
+  // 4 Standard Barrier
+  // Default: 0
+  // Description: Method for linear optimization.
+  // Determines which algorithm is used when CPXlpopt() (or "optimize"
+  // in the Interactive Optimizer) is called. Currently the behavior of
+  // the "Automatic" setting is that CPLEX simply invokes the dual
+  // simplex method, but this capability may be expanded in the future
+  // so that CPLEX chooses the method based on problem characteristics
+#if CPX_VERSION < 900
+  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
+    int lpmethod;
+    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
+    if (lpmethod==2){
+      if (stat==CPX_UNBOUNDED){
+        stat=CPX_INFEASIBLE;
+      }
+      else{
+        if (stat==CPX_INFEASIBLE)
+          stat=CPX_UNBOUNDED;
+      }
+    }
+  }
+#else
+  void statusSwitch(CPXENVptr,int&){}
+#endif
+
+  CplexLp::ProblemType CplexLp::_getPrimalType() const {
+    // Unboundedness not treated well: the following is from cplex 9.0 doc
+    // About Unboundedness
+
+    // The treatment of models that are unbounded involves a few
+    // subtleties. Specifically, a declaration of unboundedness means that
+    // ILOG CPLEX has determined that the model has an unbounded
+    // ray. Given any feasible solution x with objective z, a multiple of
+    // the unbounded ray can be added to x to give a feasible solution
+    // with objective z-1 (or z+1 for maximization models). Thus, if a
+    // feasible solution exists, then the optimal objective is
+    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
+    // a feasible solution exists. Users can call the routine CPXsolninfo
+    // to determine whether ILOG CPLEX has also concluded that the model
+    // has a feasible solution.
+
+    int stat = CPXgetstat(cplexEnv(), _prob);
+#if CPX_VERSION >= 800
+    switch (stat)
+      {
+      case CPX_STAT_OPTIMAL:
+        return OPTIMAL;
+      case CPX_STAT_UNBOUNDED:
+        return UNBOUNDED;
+      case CPX_STAT_INFEASIBLE:
+        return INFEASIBLE;
+      default:
+        return UNDEFINED;
+      }
+#else
+    statusSwitch(cplexEnv(),stat);
+    //CPXgetstat(cplexEnv(), _prob);
+    //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
+    switch (stat) {
+    case 0:
+      return UNDEFINED; //Undefined
+    case CPX_OPTIMAL://Optimal
+      return OPTIMAL;
+    case CPX_UNBOUNDED://Unbounded
+      return INFEASIBLE;//In case of dual simplex
+      //return UNBOUNDED;
+    case CPX_INFEASIBLE://Infeasible
+      //    case CPX_IT_LIM_INFEAS:
+      //     case CPX_TIME_LIM_INFEAS:
+      //     case CPX_NUM_BEST_INFEAS:
+      //     case CPX_OPTIMAL_INFEAS:
+      //     case CPX_ABORT_INFEAS:
+      //     case CPX_ABORT_PRIM_INFEAS:
+      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
+      return UNBOUNDED;//In case of dual simplex
+      //return INFEASIBLE;
+      //     case CPX_OBJ_LIM:
+      //     case CPX_IT_LIM_FEAS:
+      //     case CPX_TIME_LIM_FEAS:
+      //     case CPX_NUM_BEST_FEAS:
+      //     case CPX_ABORT_FEAS:
+      //     case CPX_ABORT_PRIM_DUAL_FEAS:
+      //       return FEASIBLE;
+    default:
+      return UNDEFINED; //Everything else comes here
+      //FIXME error
+    }
+#endif
+  }
+
+  //9.0-as cplex verzio statusai
+  // CPX_STAT_ABORT_DUAL_OBJ_LIM
+  // CPX_STAT_ABORT_IT_LIM
+  // CPX_STAT_ABORT_OBJ_LIM
+  // CPX_STAT_ABORT_PRIM_OBJ_LIM
+  // CPX_STAT_ABORT_TIME_LIM
+  // CPX_STAT_ABORT_USER
+  // CPX_STAT_FEASIBLE_RELAXED
+  // CPX_STAT_INFEASIBLE
+  // CPX_STAT_INForUNBD
+  // CPX_STAT_NUM_BEST
+  // CPX_STAT_OPTIMAL
+  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
+  // CPX_STAT_OPTIMAL_INFEAS
+  // CPX_STAT_OPTIMAL_RELAXED
+  // CPX_STAT_UNBOUNDED
+
+  CplexLp::ProblemType CplexLp::_getDualType() const {
+    int stat = CPXgetstat(cplexEnv(), _prob);
+#if CPX_VERSION >= 800
+    switch (stat) {
+    case CPX_STAT_OPTIMAL:
+      return OPTIMAL;
+    case CPX_STAT_UNBOUNDED:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+#else
+    statusSwitch(cplexEnv(),stat);
+    switch (stat) {
+    case 0:
+      return UNDEFINED; //Undefined
+    case CPX_OPTIMAL://Optimal
+      return OPTIMAL;
+    case CPX_UNBOUNDED:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED; //Everything else comes here
+      //FIXME error
+    }
+#endif
+  }
+
+  // CplexMip members
+
+  CplexMip::CplexMip()
+    : LpBase(), CplexBase(), MipSolver() {
+
+#if CPX_VERSION < 800
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
+#else
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
+#endif
+  }
+
+  CplexMip::CplexMip(const CplexEnv& env)
+    : LpBase(), CplexBase(env), MipSolver() {
+
+#if CPX_VERSION < 800
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
+#else
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
+#endif
+
+  }
+
+  CplexMip::CplexMip(const CplexMip& other)
+    : LpBase(), CplexBase(other), MipSolver() {}
+
+  CplexMip::~CplexMip() {}
+
+  CplexMip* CplexMip::_newSolver() const { return new CplexMip; }
+  CplexMip* CplexMip::_cloneSolver() const {return new CplexMip(*this); }
+
+  const char* CplexMip::_solverName() const { return "CplexMip"; }
+
+  void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) {
+
+    // Note If a variable is to be changed to binary, a call to CPXchgbds
+    // should also be made to change the bounds to 0 and 1.
+
+    switch (col_type){
+    case INTEGER: {
+      const char t = 'I';
+      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
+    } break;
+    case REAL: {
+      const char t = 'C';
+      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
+    } break;
+    default:
+      break;
+    }
+  }
+
+  CplexMip::ColTypes CplexMip::_getColType(int i) const {
+    char t;
+    CPXgetctype (cplexEnv(), _prob, &t, i, i);
+    switch (t) {
+    case 'I':
+      return INTEGER;
+    case 'C':
+      return REAL;
+    default:
+      LEMON_ASSERT(false, "Invalid column type");
+      return ColTypes();
+    }
+
+  }
+
+  CplexMip::SolveExitStatus CplexMip::_solve() {
+    int status;
+    status = CPXmipopt (cplexEnv(), _prob);
+    if (status==0)
+      return SOLVED;
+    else
+      return UNSOLVED;
+
+  }
+
+
+  CplexMip::ProblemType CplexMip::_getType() const {
+
+    int stat = CPXgetstat(cplexEnv(), _prob);
+
+    //Fortunately, MIP statuses did not change for cplex 8.0
+    switch (stat) {
+    case CPXMIP_OPTIMAL:
+      // Optimal integer solution has been found.
+    case CPXMIP_OPTIMAL_TOL:
+      // Optimal soluton with the tolerance defined by epgap or epagap has
+      // been found.
+      return OPTIMAL;
+      //This also exists in later issues
+      //    case CPXMIP_UNBOUNDED:
+      //return UNBOUNDED;
+      case CPXMIP_INFEASIBLE:
+        return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+    //Unboundedness not treated well: the following is from cplex 9.0 doc
+    // About Unboundedness
+
+    // The treatment of models that are unbounded involves a few
+    // subtleties. Specifically, a declaration of unboundedness means that
+    // ILOG CPLEX has determined that the model has an unbounded
+    // ray. Given any feasible solution x with objective z, a multiple of
+    // the unbounded ray can be added to x to give a feasible solution
+    // with objective z-1 (or z+1 for maximization models). Thus, if a
+    // feasible solution exists, then the optimal objective is
+    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
+    // a feasible solution exists. Users can call the routine CPXsolninfo
+    // to determine whether ILOG CPLEX has also concluded that the model
+    // has a feasible solution.
+  }
+
+  CplexMip::Value CplexMip::_getSol(int i) const {
+    Value x;
+    CPXgetmipx(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  CplexMip::Value CplexMip::_getSolValue() const {
+    Value objval;
+    CPXgetmipobjval(cplexEnv(), _prob, &objval);
+    return objval;
+  }
+
+} //namespace lemon
+
Index: lemon/cplex.h
===================================================================
--- lemon/cplex.h	(revision 485)
+++ lemon/cplex.h	(revision 485)
@@ -0,0 +1,256 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_CPLEX_H
+#define LEMON_CPLEX_H
+
+///\file
+///\brief Header of the LEMON-CPLEX lp solver interface.
+
+#include <lemon/lp_base.h>
+
+struct cpxenv;
+struct cpxlp;
+
+namespace lemon {
+
+  /// \brief Reference counted wrapper around cpxenv pointer
+  ///
+  /// The cplex uses environment object which is responsible for
+  /// checking the proper license usage. This class provides a simple
+  /// interface for share the environment object between different
+  /// problems.
+  class CplexEnv {
+    friend class CplexBase;
+  private:
+    cpxenv* _env;
+    mutable int* _cnt;
+
+  public:
+
+    /// \brief This exception is thrown when the license check is not
+    /// sufficient
+    class LicenseError : public Exception {
+      friend class CplexEnv;
+    private:
+
+      LicenseError(int status);
+      char _message[510];
+
+    public:
+
+      /// The short error message
+      virtual const char* what() const throw() {
+        return _message;
+      }
+    };
+
+    /// Constructor
+    CplexEnv();
+    /// Shallow copy constructor
+    CplexEnv(const CplexEnv&);
+    /// Shallow assignement
+    CplexEnv& operator=(const CplexEnv&);
+    /// Destructor
+    virtual ~CplexEnv();
+
+  protected:
+
+    cpxenv* cplexEnv() { return _env; }
+    const cpxenv* cplexEnv() const { return _env; }
+  };
+
+  /// \brief Base interface for the CPLEX LP and MIP solver
+  ///
+  /// This class implements the common interface of the CPLEX LP and
+  /// MIP solvers.  
+  /// \ingroup lp_group
+  class CplexBase : virtual public LpBase {
+  protected:
+
+    CplexEnv _env;
+    cpxlp* _prob;
+
+    CplexBase();
+    CplexBase(const CplexEnv&);
+    CplexBase(const CplexBase &);
+    virtual ~CplexBase();
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+  private:
+    void _set_row_bounds(int i, Value lb, Value ub);
+  protected:
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual void _clear();
+
+  public:
+
+    /// Returns the used \c CplexEnv instance
+    const CplexEnv& env() const { return _env; }
+    ///
+    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
+
+    cpxlp* cplexLp() { return _prob; }
+    const cpxlp* cplexLp() const { return _prob; }
+
+  };
+
+  /// \brief Interface for the CPLEX LP solver
+  ///
+  /// This class implements an interface for the CPLEX LP solver.
+  ///\ingroup lp_group
+  class CplexLp : public CplexBase, public LpSolver {
+  public:
+    /// \e
+    CplexLp();
+    /// \e
+    CplexLp(const CplexEnv&);
+    /// \e
+    CplexLp(const CplexLp&);
+    /// \e
+    virtual ~CplexLp();
+
+  private:
+
+    // these values cannot retrieved element by element
+    mutable std::vector<int> _col_status;
+    mutable std::vector<int> _row_status;
+
+    mutable std::vector<Value> _primal_ray;
+    mutable std::vector<Value> _dual_ray;
+
+    void _clear_temporals();
+
+    SolveExitStatus convertStatus(int status);
+
+  protected:
+
+    virtual CplexLp* _cloneSolver() const;
+    virtual CplexLp* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+    virtual Value _getPrimalValue() const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+  public:
+
+    /// Solve with primal simplex method
+    SolveExitStatus solvePrimal();
+
+    /// Solve with dual simplex method
+    SolveExitStatus solveDual();
+
+    /// Solve with barrier method
+    SolveExitStatus solveBarrier();
+
+  };
+
+  /// \brief Interface for the CPLEX MIP solver
+  ///
+  /// This class implements an interface for the CPLEX MIP solver.
+  ///\ingroup lp_group
+  class CplexMip : public CplexBase, public MipSolver {
+  public:
+    /// \e
+    CplexMip();
+    /// \e
+    CplexMip(const CplexEnv&);
+    /// \e
+    CplexMip(const CplexMip&);
+    /// \e
+    virtual ~CplexMip();
+
+  protected:
+
+    virtual CplexMip* _cloneSolver() const;
+    virtual CplexMip* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_CPLEX_H
+
Index: lemon/dfs.h
===================================================================
--- lemon/dfs.h	(revision 438)
+++ lemon/dfs.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: lemon/dijkstra.h
===================================================================
--- lemon/dijkstra.h	(revision 424)
+++ lemon/dijkstra.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: lemon/dim2.h
===================================================================
--- lemon/dim2.h	(revision 314)
+++ lemon/dim2.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: lemon/dimacs.h
===================================================================
--- lemon/dimacs.h	(revision 403)
+++ lemon/dimacs.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).
@@ -335,5 +335,5 @@
     typedef typename Digraph::ArcIt ArcIt;
 
-    if(!comment.empty()) 
+    if(!comment.empty())
       os << "c " << comment << std::endl;
     os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
Index: lemon/elevator.h
===================================================================
--- lemon/elevator.h	(revision 398)
+++ lemon/elevator.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: lemon/error.h
===================================================================
--- lemon/error.h	(revision 291)
+++ lemon/error.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: lemon/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 372)
+++ lemon/full_graph.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: lemon/glpk.cc
===================================================================
--- lemon/glpk.cc	(revision 485)
+++ lemon/glpk.cc	(revision 485)
@@ -0,0 +1,952 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
+
+#include <lemon/glpk.h>
+#include <glpk.h>
+
+#include <lemon/assert.h>
+
+namespace lemon {
+
+  // GlpkBase members
+
+  GlpkBase::GlpkBase() : LpBase() {
+    lp = glp_create_prob();
+    glp_create_index(lp);
+  }
+
+  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
+    lp = glp_create_prob();
+    glp_copy_prob(lp, other.lp, GLP_ON);
+    glp_create_index(lp);
+    rows = other.rows;
+    cols = other.cols;
+  }
+
+  GlpkBase::~GlpkBase() {
+    glp_delete_prob(lp);
+  }
+
+  int GlpkBase::_addCol() {
+    int i = glp_add_cols(lp, 1);
+    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  int GlpkBase::_addRow() {
+    int i = glp_add_rows(lp, 1);
+    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  void GlpkBase::_eraseCol(int i) {
+    int ca[2];
+    ca[1] = i;
+    glp_del_cols(lp, 1, ca);
+  }
+
+  void GlpkBase::_eraseRow(int i) {
+    int ra[2];
+    ra[1] = i;
+    glp_del_rows(lp, 1, ra);
+  }
+
+  void GlpkBase::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+
+  void GlpkBase::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void GlpkBase::_getColName(int c, std::string& name) const {
+    const char *str = glp_get_col_name(lp, c);
+    if (str) name = str;
+    else name.clear();
+  }
+
+  void GlpkBase::_setColName(int c, const std::string & name) {
+    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
+
+  }
+
+  int GlpkBase::_colByName(const std::string& name) const {
+    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
+    return k > 0 ? k : -1;
+  }
+
+  void GlpkBase::_getRowName(int r, std::string& name) const {
+    const char *str = glp_get_row_name(lp, r);
+    if (str) name = str;
+    else name.clear();
+  }
+
+  void GlpkBase::_setRowName(int r, const std::string & name) {
+    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
+
+  }
+
+  int GlpkBase::_rowByName(const std::string& name) const {
+    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
+    return k > 0 ? k : -1;
+  }
+
+  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    indexes.push_back(0);
+    values.push_back(0);
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    glp_set_mat_row(lp, i, values.size() - 1,
+                    &indexes.front(), &values.front());
+  }
+
+  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
+    int length = glp_get_mat_row(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i <= length; ++i) {
+      *b = std::make_pair(indexes[i], values[i]);
+      ++b;
+    }
+  }
+
+  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
+                                     ExprIterator e) {
+
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    indexes.push_back(0);
+    values.push_back(0);
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    glp_set_mat_col(lp, ix, values.size() - 1,
+                    &indexes.front(), &values.front());
+  }
+
+  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
+    int length = glp_get_mat_col(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i  <= length; ++i) {
+      *b = std::make_pair(indexes[i], values[i]);
+      ++b;
+    }
+  }
+
+  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
+
+    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
+
+      int length = glp_get_mat_row(lp, ix, 0, 0);
+
+      std::vector<int> indexes(length + 2);
+      std::vector<Value> values(length + 2);
+
+      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+      //The following code does not suppose that the elements of the
+      //array indexes are sorted
+      bool found = false;
+      for (int i = 1; i  <= length; ++i) {
+        if (indexes[i] == jx) {
+          found = true;
+          values[i] = value;
+          break;
+        }
+      }
+      if (!found) {
+        ++length;
+        indexes[length] = jx;
+        values[length] = value;
+      }
+
+      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
+
+    } else {
+
+      int length = glp_get_mat_col(lp, jx, 0, 0);
+
+      std::vector<int> indexes(length + 2);
+      std::vector<Value> values(length + 2);
+
+      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
+
+      //The following code does not suppose that the elements of the
+      //array indexes are sorted
+      bool found = false;
+      for (int i = 1; i <= length; ++i) {
+        if (indexes[i] == ix) {
+          found = true;
+          values[i] = value;
+          break;
+        }
+      }
+      if (!found) {
+        ++length;
+        indexes[length] = ix;
+        values[length] = value;
+      }
+
+      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
+
+    int length = glp_get_mat_row(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i  <= length; ++i) {
+      if (indexes[i] == jx) {
+        return values[i];
+      }
+    }
+
+    return 0;
+  }
+
+  void GlpkBase::_setColLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+
+    int b = glp_get_col_type(lp, i);
+    double up = glp_get_col_ub(lp, i);
+    if (lo == -INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_UP:
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
+    int b = glp_get_col_type(lp, i);
+    switch (b) {
+    case GLP_LO:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_col_lb(lp, i);
+    default:
+      return -INF;
+    }
+  }
+
+  void GlpkBase::_setColUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+
+    int b = glp_get_col_type(lp, i);
+    double lo = glp_get_col_lb(lp, i);
+    if (up == INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        break;
+      case GLP_UP:
+        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_UP:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_LO:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
+    int b = glp_get_col_type(lp, i);
+      switch (b) {
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        return glp_get_col_ub(lp, i);
+      default:
+        return INF;
+      }
+  }
+
+  void GlpkBase::_setRowLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+
+    int b = glp_get_row_type(lp, i);
+    double up = glp_get_row_ub(lp, i);
+    if (lo == -INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_UP:
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
+    int b = glp_get_row_type(lp, i);
+    switch (b) {
+    case GLP_LO:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_row_lb(lp, i);
+    default:
+      return -INF;
+    }
+  }
+
+  void GlpkBase::_setRowUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+
+    int b = glp_get_row_type(lp, i);
+    double lo = glp_get_row_lb(lp, i);
+    if (up == INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        break;
+      case GLP_UP:
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_UP:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_LO:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
+    int b = glp_get_row_type(lp, i);
+    switch (b) {
+    case GLP_UP:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_row_ub(lp, i);
+    default:
+      return INF;
+    }
+  }
+
+  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
+      glp_set_obj_coef(lp, i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      glp_set_obj_coef(lp, it->first, it->second);
+    }
+  }
+
+  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
+    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
+      Value val = glp_get_obj_coef(lp, i);
+      if (val != 0.0) {
+        *b = std::make_pair(i, val);
+        ++b;
+      }
+    }
+  }
+
+  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
+    //i = 0 means the constant term (shift)
+    glp_set_obj_coef(lp, i, obj_coef);
+  }
+
+  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
+    //i = 0 means the constant term (shift)
+    return glp_get_obj_coef(lp, i);
+  }
+
+  void GlpkBase::_setSense(GlpkBase::Sense sense) {
+    switch (sense) {
+    case MIN:
+      glp_set_obj_dir(lp, GLP_MIN);
+      break;
+    case MAX:
+      glp_set_obj_dir(lp, GLP_MAX);
+      break;
+    }
+  }
+
+  GlpkBase::Sense GlpkBase::_getSense() const {
+    switch(glp_get_obj_dir(lp)) {
+    case GLP_MIN:
+      return MIN;
+    case GLP_MAX:
+      return MAX;
+    default:
+      LEMON_ASSERT(false, "Wrong sense");
+      return GlpkBase::Sense();
+    }
+  }
+
+  void GlpkBase::_clear() {
+    glp_erase_prob(lp);
+    rows.clear();
+    cols.clear();
+  }
+
+  // GlpkLp members
+
+  GlpkLp::GlpkLp()
+    : LpBase(), GlpkBase(), LpSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  GlpkLp::GlpkLp(const GlpkLp& other)
+    : LpBase(other), GlpkBase(other), LpSolver(other) {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  GlpkLp* GlpkLp::_newSolver() const { return new GlpkLp; }
+  GlpkLp* GlpkLp::_cloneSolver() const { return new GlpkLp(*this); }
+
+  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
+
+  void GlpkLp::_clear_temporals() {
+    _primal_ray.clear();
+    _dual_ray.clear();
+  }
+
+  GlpkLp::SolveExitStatus GlpkLp::_solve() {
+    return solvePrimal();
+  }
+
+  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
+    _clear_temporals();
+
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
+    _clear_temporals();
+
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+    smcp.meth = GLP_DUAL;
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
+    return glp_get_col_prim(lp, i);
+  }
+
+  GlpkLp::Value GlpkLp::_getDual(int i) const {
+    return glp_get_row_dual(lp, i);
+  }
+
+  GlpkLp::Value GlpkLp::_getPrimalValue() const {
+    return glp_get_obj_val(lp);
+  }
+
+  GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
+    switch (glp_get_col_stat(lp, i)) {
+    case GLP_BS:
+      return BASIC;
+    case GLP_UP:
+      return UPPER;
+    case GLP_LO:
+      return LOWER;
+    case GLP_NF:
+      return FREE;
+    case GLP_NS:
+      return FIXED;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return GlpkLp::VarStatus();
+    }
+  }
+
+  GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const {
+    switch (glp_get_row_stat(lp, i)) {
+    case GLP_BS:
+      return BASIC;
+    case GLP_UP:
+      return UPPER;
+    case GLP_LO:
+      return LOWER;
+    case GLP_NF:
+      return FREE;
+    case GLP_NS:
+      return FIXED;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return GlpkLp::VarStatus();
+    }
+  }
+
+  GlpkLp::Value GlpkLp::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      int row_num = glp_get_num_rows(lp);
+      int col_num = glp_get_num_cols(lp);
+
+      _primal_ray.resize(col_num + 1, 0.0);
+
+      int index = glp_get_unbnd_ray(lp);
+      if (index != 0) {
+        // The primal ray is found in primal simplex second phase
+        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
+                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
+                     "Wrong primal ray");
+
+        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
+
+        if (index > row_num) {
+          _primal_ray[index - row_num] = 1.0;
+          if (glp_get_col_dual(lp, index - row_num) > 0) {
+            negate = !negate;
+          }
+        } else {
+          if (glp_get_row_dual(lp, index) > 0) {
+            negate = !negate;
+          }
+        }
+
+        std::vector<int> ray_indexes(row_num + 1);
+        std::vector<Value> ray_values(row_num + 1);
+        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
+                                          &ray_values.front());
+
+        for (int i = 1; i <= ray_length; ++i) {
+          if (ray_indexes[i] > row_num) {
+            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
+          }
+        }
+
+        if (negate) {
+          for (int i = 1; i <= col_num; ++i) {
+            _primal_ray[i] = - _primal_ray[i];
+          }
+        }
+      } else {
+        for (int i = 1; i <= col_num; ++i) {
+          _primal_ray[i] = glp_get_col_prim(lp, i);
+        }
+      }
+    }
+    return _primal_ray[i];
+  }
+
+  GlpkLp::Value GlpkLp::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+      int row_num = glp_get_num_rows(lp);
+
+      _dual_ray.resize(row_num + 1, 0.0);
+
+      int index = glp_get_unbnd_ray(lp);
+      if (index != 0) {
+        // The dual ray is found in dual simplex second phase
+        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
+                      glp_get_col_stat(lp, index - row_num)) == GLP_BS,
+
+                     "Wrong dual ray");
+
+        int idx;
+        bool negate = false;
+
+        if (index > row_num) {
+          idx = glp_get_col_bind(lp, index - row_num);
+          if (glp_get_col_prim(lp, index - row_num) >
+              glp_get_col_ub(lp, index - row_num)) {
+            negate = true;
+          }
+        } else {
+          idx = glp_get_row_bind(lp, index);
+          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
+            negate = true;
+          }
+        }
+
+        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
+
+        glp_btran(lp, &_dual_ray.front());
+      } else {
+        double eps = 1e-7;
+        // The dual ray is found in primal simplex first phase
+        // We assume that the glpk minimizes the slack to get feasible solution
+        for (int i = 1; i <= row_num; ++i) {
+          int index = glp_get_bhead(lp, i);
+          if (index <= row_num) {
+            double res = glp_get_row_prim(lp, index);
+            if (res > glp_get_row_ub(lp, index) + eps) {
+              _dual_ray[i] = -1;
+            } else if (res < glp_get_row_lb(lp, index) - eps) {
+              _dual_ray[i] = 1;
+            } else {
+              _dual_ray[i] = 0;
+            }
+            _dual_ray[i] *= glp_get_rii(lp, index);
+          } else {
+            double res = glp_get_col_prim(lp, index - row_num);
+            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
+              _dual_ray[i] = -1;
+            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
+              _dual_ray[i] = 1;
+            } else {
+              _dual_ray[i] = 0;
+            }
+            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
+          }
+        }
+
+        glp_btran(lp, &_dual_ray.front());
+
+        for (int i = 1; i <= row_num; ++i) {
+          _dual_ray[i] /= glp_get_rii(lp, i);
+        }
+      }
+    }
+    return _dual_ray[i];
+  }
+
+  GlpkLp::ProblemType GlpkLp::_getPrimalType() const {
+    if (glp_get_status(lp) == GLP_OPT)
+      return OPTIMAL;
+    switch (glp_get_prim_stat(lp)) {
+    case GLP_UNDEF:
+      return UNDEFINED;
+    case GLP_FEAS:
+    case GLP_INFEAS:
+      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    default:
+      LEMON_ASSERT(false, "Wrong primal type");
+      return  GlpkLp::ProblemType();
+    }
+  }
+
+  GlpkLp::ProblemType GlpkLp::_getDualType() const {
+    if (glp_get_status(lp) == GLP_OPT)
+      return OPTIMAL;
+    switch (glp_get_dual_stat(lp)) {
+    case GLP_UNDEF:
+      return UNDEFINED;
+    case GLP_FEAS:
+    case GLP_INFEAS:
+      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    default:
+      LEMON_ASSERT(false, "Wrong primal type");
+      return  GlpkLp::ProblemType();
+    }
+  }
+
+  void GlpkLp::presolver(bool b) {
+    lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
+  }
+
+  void GlpkLp::messageLevel(MessageLevel m) {
+    _message_level = m;
+  }
+
+  // GlpkMip members
+
+  GlpkMip::GlpkMip()
+    : LpBase(), GlpkBase(), MipSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  GlpkMip::GlpkMip(const GlpkMip& other)
+    : LpBase(), GlpkBase(other), MipSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
+    switch (col_type) {
+    case INTEGER:
+      glp_set_col_kind(lp, i, GLP_IV);
+      break;
+    case REAL:
+      glp_set_col_kind(lp, i, GLP_CV);
+      break;
+    }
+  }
+
+  GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
+    switch (glp_get_col_kind(lp, i)) {
+    case GLP_IV:
+    case GLP_BV:
+      return INTEGER;
+    default:
+      return REAL;
+    }
+
+  }
+
+  GlpkMip::SolveExitStatus GlpkMip::_solve() {
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+    smcp.meth = GLP_DUAL;
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
+
+    glp_iocp iocp;
+    glp_init_iocp(&iocp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      iocp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      iocp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      iocp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      iocp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+
+    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+
+  GlpkMip::ProblemType GlpkMip::_getType() const {
+    switch (glp_get_status(lp)) {
+    case GLP_OPT:
+      switch (glp_mip_status(lp)) {
+      case GLP_UNDEF:
+        return UNDEFINED;
+      case GLP_NOFEAS:
+        return INFEASIBLE;
+      case GLP_FEAS:
+        return FEASIBLE;
+      case GLP_OPT:
+        return OPTIMAL;
+      default:
+        LEMON_ASSERT(false, "Wrong problem type.");
+        return GlpkMip::ProblemType();
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    case GLP_INFEAS:
+    case GLP_FEAS:
+      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    default:
+      LEMON_ASSERT(false, "Wrong problem type.");
+      return GlpkMip::ProblemType();
+    }
+  }
+
+  GlpkMip::Value GlpkMip::_getSol(int i) const {
+    return glp_mip_col_val(lp, i);
+  }
+
+  GlpkMip::Value GlpkMip::_getSolValue() const {
+    return glp_mip_obj_val(lp);
+  }
+
+  GlpkMip* GlpkMip::_newSolver() const { return new GlpkMip; }
+  GlpkMip* GlpkMip::_cloneSolver() const {return new GlpkMip(*this); }
+
+  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
+
+  void GlpkMip::messageLevel(MessageLevel m) {
+    _message_level = m;
+  }
+
+} //END OF NAMESPACE LEMON
Index: lemon/glpk.h
===================================================================
--- lemon/glpk.h	(revision 485)
+++ lemon/glpk.h	(revision 485)
@@ -0,0 +1,259 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_GLPK_H
+#define LEMON_GLPK_H
+
+///\file
+///\brief Header of the LEMON-GLPK lp solver interface.
+///\ingroup lp_group
+
+#include <lemon/lp_base.h>
+
+// forward declaration
+#ifndef _GLP_PROB
+#define _GLP_PROB
+typedef struct { double _prob; } glp_prob;
+/* LP/MIP problem object */
+#endif
+
+namespace lemon {
+
+
+  /// \brief Base interface for the GLPK LP and MIP solver
+  ///
+  /// This class implements the common interface of the GLPK LP and MIP solver.
+  /// \ingroup lp_group
+  class GlpkBase : virtual public LpBase {
+  protected:
+
+    typedef glp_prob LPX;
+    glp_prob* lp;
+
+    GlpkBase();
+    GlpkBase(const GlpkBase&);
+    virtual ~GlpkBase();
+
+  protected:
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense);
+    virtual Sense _getSense() const;
+
+    virtual void _clear();
+
+  public:
+
+    ///Pointer to the underlying GLPK data structure.
+    LPX *lpx() {return lp;}
+    ///Const pointer to the underlying GLPK data structure.
+    const LPX *lpx() const {return lp;}
+
+    ///Returns the constraint identifier understood by GLPK.
+    int lpxRow(Row r) const { return rows(id(r)); }
+
+    ///Returns the variable identifier understood by GLPK.
+    int lpxCol(Col c) const { return cols(id(c)); }
+
+  };
+
+  /// \brief Interface for the GLPK LP solver
+  ///
+  /// This class implements an interface for the GLPK LP solver.
+  ///\ingroup lp_group
+  class GlpkLp : public GlpkBase, public LpSolver {
+  public:
+
+    ///\e
+    GlpkLp();
+    ///\e
+    GlpkLp(const GlpkLp&);
+
+  private:
+
+    mutable std::vector<double> _primal_ray;
+    mutable std::vector<double> _dual_ray;
+
+    void _clear_temporals();
+
+  protected:
+
+    virtual GlpkLp* _cloneSolver() const;
+    virtual GlpkLp* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    ///\todo It should be clarified
+    ///
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+  public:
+
+    ///Solve with primal simplex
+    SolveExitStatus solvePrimal();
+
+    ///Solve with dual simplex
+    SolveExitStatus solveDual();
+
+    ///Turns on or off the presolver
+
+    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
+    ///
+    ///The presolver is off by default.
+    void presolver(bool b);
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// error messages only
+      MESSAGE_ERROR_MESSAGE = 1,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 2,
+      /// full output (includes informational messages)
+      MESSAGE_FULL_OUTPUT = 3
+    };
+
+  private:
+
+    MessageLevel _message_level;
+
+  public:
+
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+  };
+
+  /// \brief Interface for the GLPK MIP solver
+  ///
+  /// This class implements an interface for the GLPK MIP solver.
+  ///\ingroup lp_group
+  class GlpkMip : public GlpkBase, public MipSolver {
+  public:
+
+    ///\e
+    GlpkMip();
+    ///\e
+    GlpkMip(const GlpkMip&);
+
+  protected:
+
+    virtual GlpkMip* _cloneSolver() const;
+    virtual GlpkMip* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// error messages only
+      MESSAGE_ERROR_MESSAGE = 1,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 2,
+      /// full output (includes informational messages)
+      MESSAGE_FULL_OUTPUT = 3
+    };
+
+  private:
+
+    MessageLevel _message_level;
+
+  public:
+
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+  };
+
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_GLPK_H
+
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 313)
+++ lemon/graph_to_eps.h	(revision 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: lemon/grid_graph.h
===================================================================
--- lemon/grid_graph.h	(revision 372)
+++ lemon/grid_graph.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: lemon/hao_orlin.h
===================================================================
--- lemon/hao_orlin.h	(revision 428)
+++ lemon/hao_orlin.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).
@@ -239,5 +239,5 @@
           if (reached[t]) continue;
           _sets.push_front(std::list<int>());
-          
+
           queue[qlast++] = t;
           reached.set(t, true);
@@ -539,5 +539,5 @@
           if (reached[t]) continue;
           _sets.push_front(std::list<int>());
-          
+
           queue[qlast++] = t;
           reached.set(t, true);
Index: lemon/hypercube_graph.h
===================================================================
--- lemon/hypercube_graph.h	(revision 385)
+++ lemon/hypercube_graph.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: lemon/kruskal.h
===================================================================
--- lemon/kruskal.h	(revision 220)
+++ lemon/kruskal.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: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 319)
+++ lemon/lgf_reader.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).
@@ -871,5 +871,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -1700,5 +1702,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -2227,5 +2231,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -2568,5 +2574,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 319)
+++ lemon/lgf_writer.h	(revision 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: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 341)
+++ lemon/list_graph.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: lemon/lp.h
===================================================================
--- lemon/lp.h	(revision 485)
+++ lemon/lp.h	(revision 485)
@@ -0,0 +1,93 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_H
+#define LEMON_LP_H
+
+#include<lemon/config.h>
+
+
+#ifdef HAVE_GLPK
+#include <lemon/glpk.h>
+#elif HAVE_CPLEX
+#include <lemon/cplex.h>
+#elif HAVE_SOPLEX
+#include <lemon/soplex.h>
+#elif HAVE_CLP
+#include <lemon/clp.h>
+#endif
+
+///\file
+///\brief Defines a default LP solver
+///\ingroup lp_group
+namespace lemon {
+
+#ifdef DOXYGEN
+  ///The default LP solver identifier
+
+  ///The default LP solver identifier.
+  ///\ingroup lp_group
+  ///
+  ///Currently, the possible values are \c GLPK, \c CPLEX,
+  ///\c SOPLEX or \c CLP
+#define LEMON_DEFAULT_LP SOLVER
+  ///The default LP solver
+
+  ///The default LP solver.
+  ///\ingroup lp_group
+  ///
+  ///Currently, it is either \c GlpkLp, \c CplexLp, \c SoplexLp or \c ClpLp
+  typedef GlpkLp Lp;
+
+  ///The default MIP solver identifier
+
+  ///The default MIP solver identifier.
+  ///\ingroup lp_group
+  ///
+  ///Currently, the possible values are \c GLPK or \c CPLEX
+#define LEMON_DEFAULT_MIP SOLVER
+  ///The default MIP solver.
+
+  ///The default MIP solver.
+  ///\ingroup lp_group
+  ///
+  ///Currently, it is either \c GlpkMip or \c CplexMip
+  typedef GlpkMip Mip;
+#else
+#ifdef HAVE_GLPK
+# define LEMON_DEFAULT_LP GLPK
+  typedef GlpkLp Lp;
+# define LEMON_DEFAULT_MIP GLPK
+  typedef GlpkMip Mip;
+#elif HAVE_CPLEX
+# define LEMON_DEFAULT_LP CPLEX
+  typedef CplexLp Lp;
+# define LEMON_DEFAULT_MIP CPLEX
+  typedef CplexMip Mip;
+#elif HAVE_SOPLEX
+# define DEFAULT_LP SOPLEX
+  typedef SoplexLp Lp;
+#elif HAVE_CLP
+# define DEFAULT_LP CLP
+  typedef ClpLp Lp;  
+#endif
+#endif
+
+} //namespace lemon
+
+#endif //LEMON_LP_H
Index: lemon/lp_base.cc
===================================================================
--- lemon/lp_base.cc	(revision 482)
+++ lemon/lp_base.cc	(revision 482)
@@ -0,0 +1,28 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\file
+///\brief The implementation of the LP solver interface.
+
+#include <lemon/lp_base.h>
+namespace lemon {
+
+  const LpBase::Value LpBase::INF = std::numeric_limits<Value>::infinity();
+  const LpBase::Value LpBase::NaN = std::numeric_limits<Value>::quiet_NaN();
+
+} //namespace lemon
Index: lemon/lp_base.h
===================================================================
--- lemon/lp_base.h	(revision 482)
+++ lemon/lp_base.h	(revision 482)
@@ -0,0 +1,2080 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_BASE_H
+#define LEMON_LP_BASE_H
+
+#include<iostream>
+#include<vector>
+#include<map>
+#include<limits>
+#include<lemon/math.h>
+
+#include<lemon/error.h>
+#include<lemon/assert.h>
+
+#include<lemon/core.h>
+#include<lemon/bits/solver_bits.h>
+
+///\file
+///\brief The interface of the LP solver interface.
+///\ingroup lp_group
+namespace lemon {
+
+  ///Common base class for LP and MIP solvers
+
+  ///Usually this class is not used directly, please use one of the concrete
+  ///implementations of the solver interface.
+  ///\ingroup lp_group
+  class LpBase {
+
+  protected:
+
+    _solver_bits::VarIndex rows;
+    _solver_bits::VarIndex cols;
+
+  public:
+
+    ///Possible outcomes of an LP solving procedure
+    enum SolveExitStatus {
+      ///This means that the problem has been successfully solved: either
+      ///an optimal solution has been found or infeasibility/unboundedness
+      ///has been proved.
+      SOLVED = 0,
+      ///Any other case (including the case when some user specified
+      ///limit has been exceeded)
+      UNSOLVED = 1
+    };
+
+    ///Direction of the optimization
+    enum Sense {
+      /// Minimization
+      MIN,
+      /// Maximization
+      MAX
+    };
+
+    ///The floating point type used by the solver
+    typedef double Value;
+    ///The infinity constant
+    static const Value INF;
+    ///The not a number constant
+    static const Value NaN;
+
+    friend class Col;
+    friend class ColIt;
+    friend class Row;
+    friend class RowIt;
+
+    ///Refer to a column of the LP.
+
+    ///This type is used to refer to a column of the LP.
+    ///
+    ///Its value remains valid and correct even after the addition or erase of
+    ///other columns.
+    ///
+    ///\note This class is similar to other Item types in LEMON, like
+    ///Node and Arc types in digraph.
+    class Col {
+      friend class LpBase;
+    protected:
+      int _id;
+      explicit Col(int id) : _id(id) {}
+    public:
+      typedef Value ExprValue;
+      typedef True LpCol;
+      /// Default constructor
+      
+      /// \warning The default constructor sets the Col to an
+      /// undefined value.
+      Col() {}
+      /// Invalid constructor \& conversion.
+      
+      /// This constructor initializes the Col to be invalid.
+      /// \sa Invalid for more details.      
+      Col(const Invalid&) : _id(-1) {}
+      /// Equality operator
+
+      /// Two \ref Col "Col"s are equal if and only if they point to
+      /// the same LP column or both are invalid.
+      bool operator==(Col c) const  {return _id == c._id;}
+      /// Inequality operator
+
+      /// \sa operator==(Col c)
+      ///
+      bool operator!=(Col c) const  {return _id != c._id;}
+      /// Artificial ordering operator.
+
+      /// To allow the use of this object in std::map or similar
+      /// associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(Col c) const  {return _id < c._id;}
+    };
+
+    ///Iterator for iterate over the columns of an LP problem
+
+    /// Its usage is quite simple, for example you can count the number
+    /// of columns in an LP \c lp:
+    ///\code
+    /// int count=0;
+    /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
+    ///\endcode
+    class ColIt : public Col {
+      const LpBase *_solver;
+    public:
+      /// Default constructor
+      
+      /// \warning The default constructor sets the iterator
+      /// to an undefined value.
+      ColIt() {}
+      /// Sets the iterator to the first Col
+      
+      /// Sets the iterator to the first Col.
+      ///
+      ColIt(const LpBase &solver) : _solver(&solver)
+      {
+        _solver->cols.firstItem(_id);
+      }
+      /// Invalid constructor \& conversion
+      
+      /// Initialize the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ColIt(const Invalid&) : Col(INVALID) {}
+      /// Next column
+      
+      /// Assign the iterator to the next column.
+      ///
+      ColIt &operator++()
+      {
+        _solver->cols.nextItem(_id);
+        return *this;
+      }
+    };
+
+    /// \brief Returns the ID of the column.
+    static int id(const Col& col) { return col._id; }
+    /// \brief Returns the column with the given ID.
+    ///
+    /// \pre The argument should be a valid column ID in the LP problem.
+    static Col colFromId(int id) { return Col(id); }
+
+    ///Refer to a row of the LP.
+
+    ///This type is used to refer to a row of the LP.
+    ///
+    ///Its value remains valid and correct even after the addition or erase of
+    ///other rows.
+    ///
+    ///\note This class is similar to other Item types in LEMON, like
+    ///Node and Arc types in digraph.
+    class Row {
+      friend class LpBase;
+    protected:
+      int _id;
+      explicit Row(int id) : _id(id) {}
+    public:
+      typedef Value ExprValue;
+      typedef True LpRow;
+      /// Default constructor
+      
+      /// \warning The default constructor sets the Row to an
+      /// undefined value.
+      Row() {}
+      /// Invalid constructor \& conversion.
+      
+      /// This constructor initializes the Row to be invalid.
+      /// \sa Invalid for more details.      
+      Row(const Invalid&) : _id(-1) {}
+      /// Equality operator
+
+      /// Two \ref Row "Row"s are equal if and only if they point to
+      /// the same LP row or both are invalid.
+      bool operator==(Row r) const  {return _id == r._id;}
+      /// Inequality operator
+      
+      /// \sa operator==(Row r)
+      ///
+      bool operator!=(Row r) const  {return _id != r._id;}
+      /// Artificial ordering operator.
+
+      /// To allow the use of this object in std::map or similar
+      /// associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(Row r) const  {return _id < r._id;}
+    };
+
+    ///Iterator for iterate over the rows of an LP problem
+
+    /// Its usage is quite simple, for example you can count the number
+    /// of rows in an LP \c lp:
+    ///\code
+    /// int count=0;
+    /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
+    ///\endcode
+    class RowIt : public Row {
+      const LpBase *_solver;
+    public:
+      /// Default constructor
+      
+      /// \warning The default constructor sets the iterator
+      /// to an undefined value.
+      RowIt() {}
+      /// Sets the iterator to the first Row
+      
+      /// Sets the iterator to the first Row.
+      ///
+      RowIt(const LpBase &solver) : _solver(&solver)
+      {
+        _solver->rows.firstItem(_id);
+      }
+      /// Invalid constructor \& conversion
+      
+      /// Initialize the iterator to be invalid.
+      /// \sa Invalid for more details.
+      RowIt(const Invalid&) : Row(INVALID) {}
+      /// Next row
+      
+      /// Assign the iterator to the next row.
+      ///
+      RowIt &operator++()
+      {
+        _solver->rows.nextItem(_id);
+        return *this;
+      }
+    };
+
+    /// \brief Returns the ID of the row.
+    static int id(const Row& row) { return row._id; }
+    /// \brief Returns the row with the given ID.
+    ///
+    /// \pre The argument should be a valid row ID in the LP problem.
+    static Row rowFromId(int id) { return Row(id); }
+
+  public:
+
+    ///Linear expression of variables and a constant component
+
+    ///This data structure stores a linear expression of the variables
+    ///(\ref Col "Col"s) and also has a constant component.
+    ///
+    ///There are several ways to access and modify the contents of this
+    ///container.
+    ///\code
+    ///e[v]=5;
+    ///e[v]+=12;
+    ///e.erase(v);
+    ///\endcode
+    ///or you can also iterate through its elements.
+    ///\code
+    ///double s=0;
+    ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
+    ///  s+=*i * primal(i);
+    ///\endcode
+    ///(This code computes the primal value of the expression).
+    ///- Numbers (<tt>double</tt>'s)
+    ///and variables (\ref Col "Col"s) directly convert to an
+    ///\ref Expr and the usual linear operations are defined, so
+    ///\code
+    ///v+w
+    ///2*v-3.12*(v-w/2)+2
+    ///v*2.1+(3*v+(v*12+w+6)*3)/2
+    ///\endcode
+    ///are valid expressions.
+    ///The usual assignment operations are also defined.
+    ///\code
+    ///e=v+w;
+    ///e+=2*v-3.12*(v-w/2)+2;
+    ///e*=3.4;
+    ///e/=5;
+    ///\endcode
+    ///- The constant member can be set and read by dereference
+    ///  operator (unary *)
+    ///
+    ///\code
+    ///*e=12;
+    ///double c=*e;
+    ///\endcode
+    ///
+    ///\sa Constr
+    class Expr {
+      friend class LpBase;
+    public:
+      /// The key type of the expression
+      typedef LpBase::Col Key;
+      /// The value type of the expression
+      typedef LpBase::Value Value;
+
+    protected:
+      Value const_comp;
+      std::map<int, Value> comps;
+
+    public:
+      typedef True SolverExpr;
+      /// Default constructor
+      
+      /// Construct an empty expression, the coefficients and
+      /// the constant component are initialized to zero.
+      Expr() : const_comp(0) {}
+      /// Construct an expression from a column
+
+      /// Construct an expression, which has a term with \c c variable
+      /// and 1.0 coefficient.
+      Expr(const Col &c) : const_comp(0) {
+        typedef std::map<int, Value>::value_type pair_type;
+        comps.insert(pair_type(id(c), 1));
+      }
+      /// Construct an expression from a constant
+
+      /// Construct an expression, which's constant component is \c v.
+      ///
+      Expr(const Value &v) : const_comp(v) {}
+      /// Returns the coefficient of the column
+      Value operator[](const Col& c) const {
+        std::map<int, Value>::const_iterator it=comps.find(id(c));
+        if (it != comps.end()) {
+          return it->second;
+        } else {
+          return 0;
+        }
+      }
+      /// Returns the coefficient of the column
+      Value& operator[](const Col& c) {
+        return comps[id(c)];
+      }
+      /// Sets the coefficient of the column
+      void set(const Col &c, const Value &v) {
+        if (v != 0.0) {
+          typedef std::map<int, Value>::value_type pair_type;
+          comps.insert(pair_type(id(c), v));
+        } else {
+          comps.erase(id(c));
+        }
+      }
+      /// Returns the constant component of the expression
+      Value& operator*() { return const_comp; }
+      /// Returns the constant component of the expression
+      const Value& operator*() const { return const_comp; }
+      /// \brief Removes the coefficients which's absolute value does
+      /// not exceed \c epsilon. It also sets to zero the constant
+      /// component, if it does not exceed epsilon in absolute value.
+      void simplify(Value epsilon = 0.0) {
+        std::map<int, Value>::iterator it=comps.begin();
+        while (it != comps.end()) {
+          std::map<int, Value>::iterator jt=it;
+          ++jt;
+          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
+          it=jt;
+        }
+        if (std::fabs(const_comp) <= epsilon) const_comp = 0;
+      }
+
+      void simplify(Value epsilon = 0.0) const {
+        const_cast<Expr*>(this)->simplify(epsilon);
+      }
+
+      ///Sets all coefficients and the constant component to 0.
+      void clear() {
+        comps.clear();
+        const_comp=0;
+      }
+
+      ///Compound assignment
+      Expr &operator+=(const Expr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]+=it->second;
+        const_comp+=e.const_comp;
+        return *this;
+      }
+      ///Compound assignment
+      Expr &operator-=(const Expr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]-=it->second;
+        const_comp-=e.const_comp;
+        return *this;
+      }
+      ///Multiply with a constant
+      Expr &operator*=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second*=v;
+        const_comp*=v;
+        return *this;
+      }
+      ///Division with a constant
+      Expr &operator/=(const Value &c) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second/=c;
+        const_comp/=c;
+        return *this;
+      }
+
+      ///Iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * primal(i);
+      ///\endcode
+      class CoeffIt {
+      private:
+
+        std::map<int, Value>::iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        CoeffIt(Expr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the column of the term
+        operator Col() const {
+          return colFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        Value& operator*() { return _it->second; }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        CoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+      /// Const iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
+      ///  s+=*i * primal(i);
+      ///\endcode
+      class ConstCoeffIt {
+      private:
+
+        std::map<int, Value>::const_iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        ConstCoeffIt(const Expr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the column of the term
+        operator Col() const {
+          return colFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        ConstCoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+    };
+
+    ///Linear constraint
+
+    ///This data stucture represents a linear constraint in the LP.
+    ///Basically it is a linear expression with a lower or an upper bound
+    ///(or both). These parts of the constraint can be obtained by the member
+    ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
+    ///respectively.
+    ///There are two ways to construct a constraint.
+    ///- You can set the linear expression and the bounds directly
+    ///  by the functions above.
+    ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
+    ///  are defined between expressions, or even between constraints whenever
+    ///  it makes sense. Therefore if \c e and \c f are linear expressions and
+    ///  \c s and \c t are numbers, then the followings are valid expressions
+    ///  and thus they can be used directly e.g. in \ref addRow() whenever
+    ///  it makes sense.
+    ///\code
+    ///  e<=s
+    ///  e<=f
+    ///  e==f
+    ///  s<=e<=t
+    ///  e>=t
+    ///\endcode
+    ///\warning The validity of a constraint is checked only at run
+    ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
+    ///compile, but will fail an assertion.
+    class Constr
+    {
+    public:
+      typedef LpBase::Expr Expr;
+      typedef Expr::Key Key;
+      typedef Expr::Value Value;
+
+    protected:
+      Expr _expr;
+      Value _lb,_ub;
+    public:
+      ///\e
+      Constr() : _expr(), _lb(NaN), _ub(NaN) {}
+      ///\e
+      Constr(Value lb, const Expr &e, Value ub) :
+        _expr(e), _lb(lb), _ub(ub) {}
+      Constr(const Expr &e) :
+        _expr(e), _lb(NaN), _ub(NaN) {}
+      ///\e
+      void clear()
+      {
+        _expr.clear();
+        _lb=_ub=NaN;
+      }
+
+      ///Reference to the linear expression
+      Expr &expr() { return _expr; }
+      ///Cont reference to the linear expression
+      const Expr &expr() const { return _expr; }
+      ///Reference to the lower bound.
+
+      ///\return
+      ///- \ref INF "INF": the constraint is lower unbounded.
+      ///- \ref NaN "NaN": lower bound has not been set.
+      ///- finite number: the lower bound
+      Value &lowerBound() { return _lb; }
+      ///The const version of \ref lowerBound()
+      const Value &lowerBound() const { return _lb; }
+      ///Reference to the upper bound.
+
+      ///\return
+      ///- \ref INF "INF": the constraint is upper unbounded.
+      ///- \ref NaN "NaN": upper bound has not been set.
+      ///- finite number: the upper bound
+      Value &upperBound() { return _ub; }
+      ///The const version of \ref upperBound()
+      const Value &upperBound() const { return _ub; }
+      ///Is the constraint lower bounded?
+      bool lowerBounded() const {
+        return _lb != -INF && !std::isnan(_lb);
+      }
+      ///Is the constraint upper bounded?
+      bool upperBounded() const {
+        return _ub != INF && !std::isnan(_ub);
+      }
+
+    };
+
+    ///Linear expression of rows
+
+    ///This data structure represents a column of the matrix,
+    ///thas is it strores a linear expression of the dual variables
+    ///(\ref Row "Row"s).
+    ///
+    ///There are several ways to access and modify the contents of this
+    ///container.
+    ///\code
+    ///e[v]=5;
+    ///e[v]+=12;
+    ///e.erase(v);
+    ///\endcode
+    ///or you can also iterate through its elements.
+    ///\code
+    ///double s=0;
+    ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
+    ///  s+=*i;
+    ///\endcode
+    ///(This code computes the sum of all coefficients).
+    ///- Numbers (<tt>double</tt>'s)
+    ///and variables (\ref Row "Row"s) directly convert to an
+    ///\ref DualExpr and the usual linear operations are defined, so
+    ///\code
+    ///v+w
+    ///2*v-3.12*(v-w/2)
+    ///v*2.1+(3*v+(v*12+w)*3)/2
+    ///\endcode
+    ///are valid \ref DualExpr dual expressions.
+    ///The usual assignment operations are also defined.
+    ///\code
+    ///e=v+w;
+    ///e+=2*v-3.12*(v-w/2);
+    ///e*=3.4;
+    ///e/=5;
+    ///\endcode
+    ///
+    ///\sa Expr
+    class DualExpr {
+      friend class LpBase;
+    public:
+      /// The key type of the expression
+      typedef LpBase::Row Key;
+      /// The value type of the expression
+      typedef LpBase::Value Value;
+
+    protected:
+      std::map<int, Value> comps;
+
+    public:
+      typedef True SolverExpr;
+      /// Default constructor
+      
+      /// Construct an empty expression, the coefficients are
+      /// initialized to zero.
+      DualExpr() {}
+      /// Construct an expression from a row
+
+      /// Construct an expression, which has a term with \c r dual
+      /// variable and 1.0 coefficient.
+      DualExpr(const Row &r) {
+        typedef std::map<int, Value>::value_type pair_type;
+        comps.insert(pair_type(id(r), 1));
+      }
+      /// Returns the coefficient of the row
+      Value operator[](const Row& r) const {
+        std::map<int, Value>::const_iterator it = comps.find(id(r));
+        if (it != comps.end()) {
+          return it->second;
+        } else {
+          return 0;
+        }
+      }
+      /// Returns the coefficient of the row
+      Value& operator[](const Row& r) {
+        return comps[id(r)];
+      }
+      /// Sets the coefficient of the row
+      void set(const Row &r, const Value &v) {
+        if (v != 0.0) {
+          typedef std::map<int, Value>::value_type pair_type;
+          comps.insert(pair_type(id(r), v));
+        } else {
+          comps.erase(id(r));
+        }
+      }
+      /// \brief Removes the coefficients which's absolute value does
+      /// not exceed \c epsilon. 
+      void simplify(Value epsilon = 0.0) {
+        std::map<int, Value>::iterator it=comps.begin();
+        while (it != comps.end()) {
+          std::map<int, Value>::iterator jt=it;
+          ++jt;
+          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
+          it=jt;
+        }
+      }
+
+      void simplify(Value epsilon = 0.0) const {
+        const_cast<DualExpr*>(this)->simplify(epsilon);
+      }
+
+      ///Sets all coefficients to 0.
+      void clear() {
+        comps.clear();
+      }
+      ///Compound assignment
+      DualExpr &operator+=(const DualExpr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]+=it->second;
+        return *this;
+      }
+      ///Compound assignment
+      DualExpr &operator-=(const DualExpr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]-=it->second;
+        return *this;
+      }
+      ///Multiply with a constant
+      DualExpr &operator*=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second*=v;
+        return *this;
+      }
+      ///Division with a constant
+      DualExpr &operator/=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second/=v;
+        return *this;
+      }
+
+      ///Iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * dual(i);
+      ///\endcode
+      class CoeffIt {
+      private:
+
+        std::map<int, Value>::iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        CoeffIt(DualExpr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the row of the term
+        operator Row() const {
+          return rowFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        Value& operator*() { return _it->second; }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        CoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+      ///Iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * dual(i);
+      ///\endcode
+      class ConstCoeffIt {
+      private:
+
+        std::map<int, Value>::const_iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        ConstCoeffIt(const DualExpr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the row of the term
+        operator Row() const {
+          return rowFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        ConstCoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+    };
+
+
+  protected:
+
+    class InsertIterator {
+    private:
+
+      std::map<int, Value>& _host;
+      const _solver_bits::VarIndex& _index;
+
+    public:
+
+      typedef std::output_iterator_tag iterator_category;
+      typedef void difference_type;
+      typedef void value_type;
+      typedef void reference;
+      typedef void pointer;
+
+      InsertIterator(std::map<int, Value>& host,
+                   const _solver_bits::VarIndex& index)
+        : _host(host), _index(index) {}
+
+      InsertIterator& operator=(const std::pair<int, Value>& value) {
+        typedef std::map<int, Value>::value_type pair_type;
+        _host.insert(pair_type(_index[value.first], value.second));
+        return *this;
+      }
+
+      InsertIterator& operator*() { return *this; }
+      InsertIterator& operator++() { return *this; }
+      InsertIterator operator++(int) { return *this; }
+
+    };
+
+    class ExprIterator {
+    private:
+      std::map<int, Value>::const_iterator _host_it;
+      const _solver_bits::VarIndex& _index;
+    public:
+
+      typedef std::bidirectional_iterator_tag iterator_category;
+      typedef std::ptrdiff_t difference_type;
+      typedef const std::pair<int, Value> value_type;
+      typedef value_type reference;
+
+      class pointer {
+      public:
+        pointer(value_type& _value) : value(_value) {}
+        value_type* operator->() { return &value; }
+      private:
+        value_type value;
+      };
+
+      ExprIterator(const std::map<int, Value>::const_iterator& host_it,
+                   const _solver_bits::VarIndex& index)
+        : _host_it(host_it), _index(index) {}
+
+      reference operator*() {
+        return std::make_pair(_index(_host_it->first), _host_it->second);
+      }
+
+      pointer operator->() {
+        return pointer(operator*());
+      }
+
+      ExprIterator& operator++() { ++_host_it; return *this; }
+      ExprIterator operator++(int) {
+        ExprIterator tmp(*this); ++_host_it; return tmp;
+      }
+
+      ExprIterator& operator--() { --_host_it; return *this; }
+      ExprIterator operator--(int) {
+        ExprIterator tmp(*this); --_host_it; return tmp;
+      }
+
+      bool operator==(const ExprIterator& it) const {
+        return _host_it == it._host_it;
+      }
+
+      bool operator!=(const ExprIterator& it) const {
+        return _host_it != it._host_it;
+      }
+
+    };
+
+  protected:
+
+    //Abstract virtual functions
+    virtual LpBase* _newSolver() const = 0;
+    virtual LpBase* _cloneSolver() const = 0;
+
+    virtual int _addColId(int col) { return cols.addIndex(col); }
+    virtual int _addRowId(int row) { return rows.addIndex(row); }
+
+    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
+    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
+
+    virtual int _addCol() = 0;
+    virtual int _addRow() = 0;
+
+    virtual void _eraseCol(int col) = 0;
+    virtual void _eraseRow(int row) = 0;
+
+    virtual void _getColName(int col, std::string& name) const = 0;
+    virtual void _setColName(int col, const std::string& name) = 0;
+    virtual int _colByName(const std::string& name) const = 0;
+
+    virtual void _getRowName(int row, std::string& name) const = 0;
+    virtual void _setRowName(int row, const std::string& name) = 0;
+    virtual int _rowByName(const std::string& name) const = 0;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
+    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
+    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
+
+    virtual void _setCoeff(int row, int col, Value value) = 0;
+    virtual Value _getCoeff(int row, int col) const = 0;
+
+    virtual void _setColLowerBound(int i, Value value) = 0;
+    virtual Value _getColLowerBound(int i) const = 0;
+
+    virtual void _setColUpperBound(int i, Value value) = 0;
+    virtual Value _getColUpperBound(int i) const = 0;
+
+    virtual void _setRowLowerBound(int i, Value value) = 0;
+    virtual Value _getRowLowerBound(int i) const = 0;
+
+    virtual void _setRowUpperBound(int i, Value value) = 0;
+    virtual Value _getRowUpperBound(int i) const = 0;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
+    virtual void _getObjCoeffs(InsertIterator b) const = 0;
+
+    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
+    virtual Value _getObjCoeff(int i) const = 0;
+
+    virtual void _setSense(Sense) = 0;
+    virtual Sense _getSense() const = 0;
+
+    virtual void _clear() = 0;
+
+    virtual const char* _solverName() const = 0;
+
+    //Own protected stuff
+
+    //Constant component of the objective function
+    Value obj_const_comp;
+
+    LpBase() : rows(), cols(), obj_const_comp(0) {}
+
+  public:
+
+    /// Virtual destructor
+    virtual ~LpBase() {}
+
+    ///Creates a new LP problem
+    LpBase* newSolver() {return _newSolver();}
+    ///Makes a copy of the LP problem
+    LpBase* cloneSolver() {return _cloneSolver();}
+
+    ///Gives back the name of the solver.
+    const char* solverName() const {return _solverName();}
+
+    ///\name Build up and modify the LP
+
+    ///@{
+
+    ///Add a new empty column (i.e a new variable) to the LP
+    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
+
+    ///\brief Adds several new columns (i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument and fills
+    ///its elements with new columns (i.e. variables)
+    ///\param t can be
+    ///- a standard STL compatible iterable container with
+    ///\ref Col as its \c values_type like
+    ///\code
+    ///std::vector<LpBase::Col>
+    ///std::list<LpBase::Col>
+    ///\endcode
+    ///- a standard STL compatible iterable container with
+    ///\ref Col as its \c mapped_type like
+    ///\code
+    ///std::map<AnyType,LpBase::Col>
+    ///\endcode
+    ///- an iterable lemon \ref concepts::WriteMap "write map" like
+    ///\code
+    ///ListGraph::NodeMap<LpBase::Col>
+    ///ListGraph::ArcMap<LpBase::Col>
+    ///\endcode
+    ///\return The number of the created column.
+#ifdef DOXYGEN
+    template<class T>
+    int addColSet(T &t) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,int>::type
+    addColSet(T &t,dummy<0> = 0) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       int>::type
+    addColSet(T &t,dummy<1> = 1) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        i->second=addCol();
+        s++;
+      }
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       int>::type
+    addColSet(T &t,dummy<2> = 2) {
+      int s=0;
+      for(typename T::MapIt i(t); i!=INVALID; ++i)
+        {
+          i.set(addCol());
+          s++;
+        }
+      return s;
+    }
+#endif
+
+    ///Set a column (i.e a dual constraint) of the LP
+
+    ///\param c is the column to be modified
+    ///\param e is a dual linear expression (see \ref DualExpr)
+    ///a better one.
+    void col(Col c, const DualExpr &e) {
+      e.simplify();
+      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), cols),
+                    ExprIterator(e.comps.end(), cols));
+    }
+
+    ///Get a column (i.e a dual constraint) of the LP
+
+    ///\param c is the column to get
+    ///\return the dual expression associated to the column
+    DualExpr col(Col c) const {
+      DualExpr e;
+      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
+      return e;
+    }
+
+    ///Add a new column to the LP
+
+    ///\param e is a dual linear expression (see \ref DualExpr)
+    ///\param o is the corresponding component of the objective
+    ///function. It is 0 by default.
+    ///\return The created column.
+    Col addCol(const DualExpr &e, Value o = 0) {
+      Col c=addCol();
+      col(c,e);
+      objCoeff(c,o);
+      return c;
+    }
+
+    ///Add a new empty row (i.e a new constraint) to the LP
+
+    ///This function adds a new empty row (i.e a new constraint) to the LP.
+    ///\return The created row
+    Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
+
+    ///\brief Add several new rows (i.e constraints) at once
+    ///
+    ///This magic function takes a container as its argument and fills
+    ///its elements with new row (i.e. variables)
+    ///\param t can be
+    ///- a standard STL compatible iterable container with
+    ///\ref Row as its \c values_type like
+    ///\code
+    ///std::vector<LpBase::Row>
+    ///std::list<LpBase::Row>
+    ///\endcode
+    ///- a standard STL compatible iterable container with
+    ///\ref Row as its \c mapped_type like
+    ///\code
+    ///std::map<AnyType,LpBase::Row>
+    ///\endcode
+    ///- an iterable lemon \ref concepts::WriteMap "write map" like
+    ///\code
+    ///ListGraph::NodeMap<LpBase::Row>
+    ///ListGraph::ArcMap<LpBase::Row>
+    ///\endcode
+    ///\return The number of rows created.
+#ifdef DOXYGEN
+    template<class T>
+    int addRowSet(T &t) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpRow,int>::type
+    addRowSet(T &t, dummy<0> = 0) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
+    addRowSet(T &t, dummy<1> = 1) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        i->second=addRow();
+        s++;
+      }
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
+    addRowSet(T &t, dummy<2> = 2) {
+      int s=0;
+      for(typename T::MapIt i(t); i!=INVALID; ++i)
+        {
+          i.set(addRow());
+          s++;
+        }
+      return s;
+    }
+#endif
+
+    ///Set a row (i.e a constraint) of the LP
+
+    ///\param r is the row to be modified
+    ///\param l is lower bound (-\ref INF means no bound)
+    ///\param e is a linear expression (see \ref Expr)
+    ///\param u is the upper bound (\ref INF means no bound)
+    void row(Row r, Value l, const Expr &e, Value u) {
+      e.simplify();
+      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
+                    ExprIterator(e.comps.end(), cols));
+      _setRowLowerBound(rows(id(r)),l - *e);
+      _setRowUpperBound(rows(id(r)),u - *e);
+    }
+
+    ///Set a row (i.e a constraint) of the LP
+
+    ///\param r is the row to be modified
+    ///\param c is a linear expression (see \ref Constr)
+    void row(Row r, const Constr &c) {
+      row(r, c.lowerBounded()?c.lowerBound():-INF,
+          c.expr(), c.upperBounded()?c.upperBound():INF);
+    }
+
+
+    ///Get a row (i.e a constraint) of the LP
+
+    ///\param r is the row to get
+    ///\return the expression associated to the row
+    Expr row(Row r) const {
+      Expr e;
+      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
+      return e;
+    }
+
+    ///Add a new row (i.e a new constraint) to the LP
+
+    ///\param l is the lower bound (-\ref INF means no bound)
+    ///\param e is a linear expression (see \ref Expr)
+    ///\param u is the upper bound (\ref INF means no bound)
+    ///\return The created row.
+    Row addRow(Value l,const Expr &e, Value u) {
+      Row r=addRow();
+      row(r,l,e,u);
+      return r;
+    }
+
+    ///Add a new row (i.e a new constraint) to the LP
+
+    ///\param c is a linear expression (see \ref Constr)
+    ///\return The created row.
+    Row addRow(const Constr &c) {
+      Row r=addRow();
+      row(r,c);
+      return r;
+    }
+    ///Erase a column (i.e a variable) from the LP
+
+    ///\param c is the column to be deleted
+    void erase(Col c) {
+      _eraseCol(cols(id(c)));
+      _eraseColId(cols(id(c)));
+    }
+    ///Erase a row (i.e a constraint) from the LP
+
+    ///\param r is the row to be deleted
+    void erase(Row r) {
+      _eraseRow(rows(id(r)));
+      _eraseRowId(rows(id(r)));
+    }
+
+    /// Get the name of a column
+
+    ///\param c is the coresponding column
+    ///\return The name of the colunm
+    std::string colName(Col c) const {
+      std::string name;
+      _getColName(cols(id(c)), name);
+      return name;
+    }
+
+    /// Set the name of a column
+
+    ///\param c is the coresponding column
+    ///\param name The name to be given
+    void colName(Col c, const std::string& name) {
+      _setColName(cols(id(c)), name);
+    }
+
+    /// Get the column by its name
+
+    ///\param name The name of the column
+    ///\return the proper column or \c INVALID
+    Col colByName(const std::string& name) const {
+      int k = _colByName(name);
+      return k != -1 ? Col(cols[k]) : Col(INVALID);
+    }
+
+    /// Get the name of a row
+
+    ///\param r is the coresponding row
+    ///\return The name of the row
+    std::string rowName(Row r) const {
+      std::string name;
+      _getRowName(rows(id(r)), name);
+      return name;
+    }
+
+    /// Set the name of a row
+
+    ///\param r is the coresponding row
+    ///\param name The name to be given
+    void rowName(Row r, const std::string& name) {
+      _setRowName(rows(id(r)), name);
+    }
+
+    /// Get the row by its name
+
+    ///\param name The name of the row
+    ///\return the proper row or \c INVALID
+    Row rowByName(const std::string& name) const {
+      int k = _rowByName(name);
+      return k != -1 ? Row(rows[k]) : Row(INVALID);
+    }
+
+    /// Set an element of the coefficient matrix of the LP
+
+    ///\param r is the row of the element to be modified
+    ///\param c is the column of the element to be modified
+    ///\param val is the new value of the coefficient
+    void coeff(Row r, Col c, Value val) {
+      _setCoeff(rows(id(r)),cols(id(c)), val);
+    }
+
+    /// Get an element of the coefficient matrix of the LP
+
+    ///\param r is the row of the element
+    ///\param c is the column of the element
+    ///\return the corresponding coefficient
+    Value coeff(Row r, Col c) const {
+      return _getCoeff(rows(id(r)),cols(id(c)));
+    }
+
+    /// Set the lower bound of a column (i.e a variable)
+
+    /// The lower bound of a variable (column) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void colLowerBound(Col c, Value value) {
+      _setColLowerBound(cols(id(c)),value);
+    }
+
+    /// Get the lower bound of a column (i.e a variable)
+
+    /// This function returns the lower bound for column (variable) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The lower bound for column \c c
+    Value colLowerBound(Col c) const {
+      return _getColLowerBound(cols(id(c)));
+    }
+
+    ///\brief Set the lower bound of  several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    ///The lower bound of a variable (column) has to be given by an
+    ///extended number of type Value, i.e. a finite number of type
+    ///Value or -\ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colLowerBound(T &t, Value value) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,void>::type
+    colLowerBound(T &t, Value value,dummy<0> = 0) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colLowerBound(*i, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       void>::type
+    colLowerBound(T &t, Value value,dummy<1> = 1) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colLowerBound(i->second, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       void>::type
+    colLowerBound(T &t, Value value,dummy<2> = 2) {
+      for(typename T::MapIt i(t); i!=INVALID; ++i){
+        colLowerBound(*i, value);
+      }
+    }
+#endif
+
+    /// Set the upper bound of a column (i.e a variable)
+
+    /// The upper bound of a variable (column) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    void colUpperBound(Col c, Value value) {
+      _setColUpperBound(cols(id(c)),value);
+    };
+
+    /// Get the upper bound of a column (i.e a variable)
+
+    /// This function returns the upper bound for column (variable) \c c
+    /// (this might be \ref INF as well).
+    /// \return The upper bound for column \c c
+    Value colUpperBound(Col c) const {
+      return _getColUpperBound(cols(id(c)));
+    }
+
+    ///\brief Set the upper bound of  several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    ///The upper bound of a variable (column) has to be given by an
+    ///extended number of type Value, i.e. a finite number of type
+    ///Value or \ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colUpperBound(T &t, Value value) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,void>::type
+    colUpperBound(T &t, Value value,dummy<0> = 0) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colUpperBound(*i, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       void>::type
+    colUpperBound(T &t, Value value,dummy<1> = 1) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colUpperBound(i->second, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       void>::type
+    colUpperBound(T &t, Value value,dummy<2> = 2) {
+      for(typename T::MapIt i(t); i!=INVALID; ++i){
+        colUpperBound(*i, value);
+      }
+    }
+#endif
+
+    /// Set the lower and the upper bounds of a column (i.e a variable)
+
+    /// The lower and the upper bounds of
+    /// a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value, -\ref INF or \ref INF.
+    void colBounds(Col c, Value lower, Value upper) {
+      _setColLowerBound(cols(id(c)),lower);
+      _setColUpperBound(cols(id(c)),upper);
+    }
+
+    ///\brief Set the lower and the upper bound of several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    /// The lower and the upper bounds of
+    /// a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value, -\ref INF or \ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colBounds(T &t, Value lower, Value upper) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,void>::type
+    colBounds(T &t, Value lower, Value upper,dummy<0> = 0) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colBounds(*i, lower, upper);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol, void>::type
+    colBounds(T &t, Value lower, Value upper,dummy<1> = 1) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colBounds(i->second, lower, upper);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol, void>::type
+    colBounds(T &t, Value lower, Value upper,dummy<2> = 2) {
+      for(typename T::MapIt i(t); i!=INVALID; ++i){
+        colBounds(*i, lower, upper);
+      }
+    }
+#endif
+
+    /// Set the lower bound of a row (i.e a constraint)
+
+    /// The lower bound of a constraint (row) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void rowLowerBound(Row r, Value value) {
+      _setRowLowerBound(rows(id(r)),value);
+    }
+
+    /// Get the lower bound of a row (i.e a constraint)
+
+    /// This function returns the lower bound for row (constraint) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The lower bound for row \c r
+    Value rowLowerBound(Row r) const {
+      return _getRowLowerBound(rows(id(r)));
+    }
+
+    /// Set the upper bound of a row (i.e a constraint)
+
+    /// The upper bound of a constraint (row) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void rowUpperBound(Row r, Value value) {
+      _setRowUpperBound(rows(id(r)),value);
+    }
+
+    /// Get the upper bound of a row (i.e a constraint)
+
+    /// This function returns the upper bound for row (constraint) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The upper bound for row \c r
+    Value rowUpperBound(Row r) const {
+      return _getRowUpperBound(rows(id(r)));
+    }
+
+    ///Set an element of the objective function
+    void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
+
+    ///Get an element of the objective function
+    Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
+
+    ///Set the objective function
+
+    ///\param e is a linear expression of type \ref Expr.
+    ///
+    void obj(const Expr& e) {
+      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
+                    ExprIterator(e.comps.end(), cols));
+      obj_const_comp = *e;
+    }
+
+    ///Get the objective function
+
+    ///\return the objective function as a linear expression of type
+    ///Expr.
+    Expr obj() const {
+      Expr e;
+      _getObjCoeffs(InsertIterator(e.comps, cols));
+      *e = obj_const_comp;
+      return e;
+    }
+
+
+    ///Set the direction of optimization
+    void sense(Sense sense) { _setSense(sense); }
+
+    ///Query the direction of the optimization
+    Sense sense() const {return _getSense(); }
+
+    ///Set the sense to maximization
+    void max() { _setSense(MAX); }
+
+    ///Set the sense to maximization
+    void min() { _setSense(MIN); }
+
+    ///Clears the problem
+    void clear() { _clear(); }
+
+    ///@}
+
+  };
+
+  /// Addition
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(a);
+    tmp+=b;
+    return tmp;
+  }
+  ///Substraction
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(a);
+    tmp-=b;
+    return tmp;
+  }
+  ///Multiply with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
+    LpBase::Expr tmp(a);
+    tmp*=b;
+    return tmp;
+  }
+
+  ///Multiply with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(b);
+    tmp*=a;
+    return tmp;
+  }
+  ///Divide with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
+    LpBase::Expr tmp(a);
+    tmp/=b;
+    return tmp;
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, f - e, LpBase::INF);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Value &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(e, f, LpBase::NaN);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(- LpBase::INF, e, f);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, e - f, LpBase::INF);
+  }
+
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Value &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(LpBase::NaN, f, e);
+  }
+
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(f, e, LpBase::INF);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator==(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(f, e, f);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator==(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, f - e, 0);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Value &n,
+                                   const LpBase::Constr &c) {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(std::isnan(tmp.lowerBound()), "Wrong LP constraint");
+    tmp.lowerBound()=n;
+    return tmp;
+  }
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Constr &c,
+                                   const LpBase::Value &n)
+  {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(std::isnan(tmp.upperBound()), "Wrong LP constraint");
+    tmp.upperBound()=n;
+    return tmp;
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Value &n,
+                                   const LpBase::Constr &c) {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(std::isnan(tmp.upperBound()), "Wrong LP constraint");
+    tmp.upperBound()=n;
+    return tmp;
+  }
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Constr &c,
+                                   const LpBase::Value &n)
+  {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(std::isnan(tmp.lowerBound()), "Wrong LP constraint");
+    tmp.lowerBound()=n;
+    return tmp;
+  }
+
+  ///Addition
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(a);
+    tmp+=b;
+    return tmp;
+  }
+  ///Substraction
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(a);
+    tmp-=b;
+    return tmp;
+  }
+  ///Multiply with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
+                                    const LpBase::Value &b) {
+    LpBase::DualExpr tmp(a);
+    tmp*=b;
+    return tmp;
+  }
+
+  ///Multiply with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator*(const LpBase::Value &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(b);
+    tmp*=a;
+    return tmp;
+  }
+  ///Divide with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
+                                    const LpBase::Value &b) {
+    LpBase::DualExpr tmp(a);
+    tmp/=b;
+    return tmp;
+  }
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Common base class for LP solvers
+  ///
+  /// This class is an abstract base class for LP solvers. This class
+  /// provides a full interface for set and modify an LP problem,
+  /// solve it and retrieve the solution. You can use one of the
+  /// descendants as a concrete implementation, or the \c Lp
+  /// default LP solver. However, if you would like to handle LP
+  /// solvers as reference or pointer in a generic way, you can use
+  /// this class directly.
+  class LpSolver : virtual public LpBase {
+  public:
+
+    /// The problem types for primal and dual problems
+    enum ProblemType {
+      ///Feasible solution hasn't been found (but may exist).
+      UNDEFINED = 0,
+      ///The problem has no feasible solution
+      INFEASIBLE = 1,
+      ///Feasible solution found
+      FEASIBLE = 2,
+      ///Optimal solution exists and found
+      OPTIMAL = 3,
+      ///The cost function is unbounded
+      UNBOUNDED = 4
+    };
+
+    ///The basis status of variables
+    enum VarStatus {
+      /// The variable is in the basis
+      BASIC, 
+      /// The variable is free, but not basic
+      FREE,
+      /// The variable has active lower bound 
+      LOWER,
+      /// The variable has active upper bound
+      UPPER,
+      /// The variable is non-basic and fixed
+      FIXED
+    };
+
+  protected:
+
+    virtual SolveExitStatus _solve() = 0;
+
+    virtual Value _getPrimal(int i) const = 0;
+    virtual Value _getDual(int i) const = 0;
+
+    virtual Value _getPrimalRay(int i) const = 0;
+    virtual Value _getDualRay(int i) const = 0;
+
+    virtual Value _getPrimalValue() const = 0;
+
+    virtual VarStatus _getColStatus(int i) const = 0;
+    virtual VarStatus _getRowStatus(int i) const = 0;
+
+    virtual ProblemType _getPrimalType() const = 0;
+    virtual ProblemType _getDualType() const = 0;
+
+  public:
+
+    ///\name Solve the LP
+
+    ///@{
+
+    ///\e Solve the LP problem at hand
+    ///
+    ///\return The result of the optimization procedure. Possible
+    ///values and their meanings can be found in the documentation of
+    ///\ref SolveExitStatus.
+    SolveExitStatus solve() { return _solve(); }
+
+    ///@}
+
+    ///\name Obtain the solution
+
+    ///@{
+
+    /// The type of the primal problem
+    ProblemType primalType() const {
+      return _getPrimalType();
+    }
+
+    /// The type of the dual problem
+    ProblemType dualType() const {
+      return _getDualType();
+    }
+
+    /// Return the primal value of the column
+
+    /// Return the primal value of the column.
+    /// \pre The problem is solved.
+    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
+
+    /// Return the primal value of the expression
+
+    /// Return the primal value of the expression, i.e. the dot
+    /// product of the primal solution and the expression.
+    /// \pre The problem is solved.
+    Value primal(const Expr& e) const {
+      double res = *e;
+      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
+        res += *c * primal(c);
+      }
+      return res;
+    }
+    /// Returns a component of the primal ray
+    
+    /// The primal ray is solution of the modified primal problem,
+    /// where we change each finite bound to 0, and we looking for a
+    /// negative objective value in case of minimization, and positive
+    /// objective value for maximization. If there is such solution,
+    /// that proofs the unsolvability of the dual problem, and if a
+    /// feasible primal solution exists, then the unboundness of
+    /// primal problem.
+    ///
+    /// \pre The problem is solved and the dual problem is infeasible.
+    /// \note Some solvers does not provide primal ray calculation
+    /// functions.
+    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
+
+    /// Return the dual value of the row
+
+    /// Return the dual value of the row.
+    /// \pre The problem is solved.
+    Value dual(Row r) const { return _getDual(rows(id(r))); }
+
+    /// Return the dual value of the dual expression
+
+    /// Return the dual value of the dual expression, i.e. the dot
+    /// product of the dual solution and the dual expression.
+    /// \pre The problem is solved.
+    Value dual(const DualExpr& e) const {
+      double res = 0.0;
+      for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
+        res += *r * dual(r);
+      }
+      return res;
+    }
+
+    /// Returns a component of the dual ray
+    
+    /// The dual ray is solution of the modified primal problem, where
+    /// we change each finite bound to 0 (i.e. the objective function
+    /// coefficients in the primal problem), and we looking for a
+    /// ositive objective value. If there is such solution, that
+    /// proofs the unsolvability of the primal problem, and if a
+    /// feasible dual solution exists, then the unboundness of
+    /// dual problem.
+    ///
+    /// \pre The problem is solved and the primal problem is infeasible.
+    /// \note Some solvers does not provide dual ray calculation
+    /// functions.
+    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
+
+    /// Return the basis status of the column
+
+    /// \see VarStatus
+    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
+
+    /// Return the basis status of the row
+
+    /// \see VarStatus
+    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
+
+    ///The value of the objective function
+
+    ///\return
+    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
+    /// of the primal problem, depending on whether we minimize or maximize.
+    ///- \ref NaN if no primal solution is found.
+    ///- The (finite) objective value if an optimal solution is found.
+    Value primal() const { return _getPrimalValue()+obj_const_comp;}
+    ///@}
+
+    LpSolver* newSolver() {return _newSolver();}
+    LpSolver* cloneSolver() {return _cloneSolver();}
+
+  protected:
+
+    virtual LpSolver* _newSolver() const = 0;
+    virtual LpSolver* _cloneSolver() const = 0;
+  };
+
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Common base class for MIP solvers
+  ///
+  /// This class is an abstract base class for MIP solvers. This class
+  /// provides a full interface for set and modify an MIP problem,
+  /// solve it and retrieve the solution. You can use one of the
+  /// descendants as a concrete implementation, or the \c Lp
+  /// default MIP solver. However, if you would like to handle MIP
+  /// solvers as reference or pointer in a generic way, you can use
+  /// this class directly.
+  class MipSolver : virtual public LpBase {
+  public:
+
+    /// The problem types for MIP problems
+    enum ProblemType {
+      ///Feasible solution hasn't been found (but may exist).
+      UNDEFINED = 0,
+      ///The problem has no feasible solution
+      INFEASIBLE = 1,
+      ///Feasible solution found
+      FEASIBLE = 2,
+      ///Optimal solution exists and found
+      OPTIMAL = 3,
+      ///The cost function is unbounded
+      ///
+      ///The Mip or at least the relaxed problem is unbounded
+      UNBOUNDED = 4
+    };
+
+    ///\name Solve the MIP
+
+    ///@{
+
+    /// Solve the MIP problem at hand
+    ///
+    ///\return The result of the optimization procedure. Possible
+    ///values and their meanings can be found in the documentation of
+    ///\ref SolveExitStatus.
+    SolveExitStatus solve() { return _solve(); }
+
+    ///@}
+
+    ///\name Setting column type
+    ///@{
+
+    ///Possible variable (column) types (e.g. real, integer, binary etc.)
+    enum ColTypes {
+      ///Continuous variable (default)
+      REAL = 0,
+      ///Integer variable
+      INTEGER = 1
+    };
+
+    ///Sets the type of the given column to the given type
+
+    ///Sets the type of the given column to the given type.
+    ///
+    void colType(Col c, ColTypes col_type) {
+      _setColType(cols(id(c)),col_type);
+    }
+
+    ///Gives back the type of the column.
+
+    ///Gives back the type of the column.
+    ///
+    ColTypes colType(Col c) const {
+      return _getColType(cols(id(c)));
+    }
+    ///@}
+
+    ///\name Obtain the solution
+
+    ///@{
+
+    /// The type of the MIP problem
+    ProblemType type() const {
+      return _getType();
+    }
+
+    /// Return the value of the row in the solution
+
+    ///  Return the value of the row in the solution.
+    /// \pre The problem is solved.
+    Value sol(Col c) const { return _getSol(cols(id(c))); }
+
+    /// Return the value of the expression in the solution
+
+    /// Return the value of the expression in the solution, i.e. the
+    /// dot product of the solution and the expression.
+    /// \pre The problem is solved.
+    Value sol(const Expr& e) const {
+      double res = *e;
+      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
+        res += *c * sol(c);
+      }
+      return res;
+    }
+    ///The value of the objective function
+    
+    ///\return
+    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
+    /// of the problem, depending on whether we minimize or maximize.
+    ///- \ref NaN if no primal solution is found.
+    ///- The (finite) objective value if an optimal solution is found.
+    Value solValue() const { return _getSolValue()+obj_const_comp;}
+    ///@}
+
+  protected:
+
+    virtual SolveExitStatus _solve() = 0;
+    virtual ColTypes _getColType(int col) const = 0;
+    virtual void _setColType(int col, ColTypes col_type) = 0;
+    virtual ProblemType _getType() const = 0;
+    virtual Value _getSol(int i) const = 0;
+    virtual Value _getSolValue() const = 0;
+
+  public:
+
+    MipSolver* newSolver() {return _newSolver();}
+    MipSolver* cloneSolver() {return _cloneSolver();}
+
+  protected:
+
+    virtual MipSolver* _newSolver() const = 0;
+    virtual MipSolver* _cloneSolver() const = 0;
+  };
+
+
+
+} //namespace lemon
+
+#endif //LEMON_LP_BASE_H
Index: lemon/lp_skeleton.cc
===================================================================
--- lemon/lp_skeleton.cc	(revision 482)
+++ lemon/lp_skeleton.cc	(revision 482)
@@ -0,0 +1,134 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/lp_skeleton.h>
+
+///\file
+///\brief A skeleton file to implement LP solver interfaces
+namespace lemon {
+
+  int SkeletonSolverBase::_addCol()
+  {
+    return ++col_num;
+  }
+
+  int SkeletonSolverBase::_addRow()
+  {
+    return ++row_num;
+  }
+
+  void SkeletonSolverBase::_eraseCol(int) {}
+  void SkeletonSolverBase::_eraseRow(int) {}
+
+  void SkeletonSolverBase::_getColName(int, std::string &) const {}
+  void SkeletonSolverBase::_setColName(int, const std::string &) {}
+  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
+
+  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
+  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
+  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
+
+  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
+
+  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
+
+  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
+  { return 0; }
+
+  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
+
+  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setSense(Sense) {}
+  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
+  { return MIN; }
+
+  void SkeletonSolverBase::_clear() {
+    row_num = col_num = 0;
+  }
+
+  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
+
+  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
+
+  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
+
+  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
+  { return UNDEFINED; }
+
+  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
+  { return UNDEFINED; }
+
+  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
+  { return BASIC; }
+
+  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
+  { return BASIC; }
+
+  LpSkeleton* LpSkeleton::_newSolver() const
+  { return static_cast<LpSkeleton*>(0); }
+
+  LpSkeleton* LpSkeleton::_cloneSolver() const
+  { return static_cast<LpSkeleton*>(0); }
+
+  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
+
+  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
+  { return SOLVED; }
+
+  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
+  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
+
+  MipSkeleton::ProblemType MipSkeleton::_getType() const
+  { return UNDEFINED; }
+
+  MipSkeleton* MipSkeleton::_newSolver() const
+  { return static_cast<MipSkeleton*>(0); }
+
+  MipSkeleton* MipSkeleton::_cloneSolver() const
+  { return static_cast<MipSkeleton*>(0); }
+
+  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
+
+} //namespace lemon
+
Index: lemon/lp_skeleton.h
===================================================================
--- lemon/lp_skeleton.h	(revision 482)
+++ lemon/lp_skeleton.h	(revision 482)
@@ -0,0 +1,229 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_LP_SKELETON
+#define LEMON_LP_SKELETON
+
+#include <lemon/lp_base.h>
+
+///\file
+///\brief A skeleton file to implement LP solver interfaces
+namespace lemon {
+
+  ///A skeleton class to implement LP solver interfaces
+  class SkeletonSolverBase : public virtual LpBase {
+    int col_num,row_num;
+
+  protected:
+
+    SkeletonSolverBase()
+      : col_num(-1), row_num(-1) {}
+
+    /// \e
+    virtual int _addCol();
+    /// \e
+    virtual int _addRow();
+    /// \e
+    virtual void _eraseCol(int i);
+    /// \e
+    virtual void _eraseRow(int i);
+
+    /// \e
+    virtual void _getColName(int col, std::string& name) const;
+    /// \e
+    virtual void _setColName(int col, const std::string& name);
+    /// \e
+    virtual int _colByName(const std::string& name) const;
+
+    /// \e
+    virtual void _getRowName(int row, std::string& name) const;
+    /// \e
+    virtual void _setRowName(int row, const std::string& name);
+    /// \e
+    virtual int _rowByName(const std::string& name) const;
+
+    /// \e
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+    /// \e
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    /// Set one element of the coefficient matrix
+    virtual void _setCoeff(int row, int col, Value value);
+
+    /// Get one element of the coefficient matrix
+    virtual Value _getCoeff(int row, int col) const;
+
+    /// The lower bound of a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual void _setColLowerBound(int i, Value value);
+    /// \e
+
+    /// The lower bound of a variable (column) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual Value _getColLowerBound(int i) const;
+
+    /// The upper bound of a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual void _setColUpperBound(int i, Value value);
+    /// \e
+
+    /// The upper bound of a variable (column) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual Value _getColUpperBound(int i) const;
+
+    /// The lower bound of a constraint (row) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual void _setRowLowerBound(int i, Value value);
+    /// \e
+
+    /// The lower bound of a constraint (row) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual Value _getRowLowerBound(int i) const;
+
+    /// The upper bound of a constraint (row) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual void _setRowUpperBound(int i, Value value);
+    /// \e
+
+    /// The upper bound of a constraint (row) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual Value _getRowUpperBound(int i) const;
+
+    /// \e
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    /// \e
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    /// \e
+    virtual Value _getObjCoeff(int i) const;
+
+    ///\e
+    virtual void _setSense(Sense);
+    ///\e
+    virtual Sense _getSense() const;
+
+    ///\e
+    virtual void _clear();
+
+  };
+
+  /// \brief Interface for a skeleton LP solver
+  ///
+  /// This class implements an interface for a skeleton LP solver.
+  ///\ingroup lp_group
+  class LpSkeleton : public SkeletonSolverBase, public LpSolver {
+  public:
+    LpSkeleton() : SkeletonSolverBase(), LpSolver() {}
+
+  protected:
+
+    ///\e
+    virtual SolveExitStatus _solve();
+
+    ///\e
+    virtual Value _getPrimal(int i) const;
+    ///\e
+    virtual Value _getDual(int i) const;
+
+    ///\e
+    virtual Value _getPrimalValue() const;
+
+    ///\e
+    virtual Value _getPrimalRay(int i) const;
+    ///\e
+    virtual Value _getDualRay(int i) const;
+
+    ///\e
+    virtual ProblemType _getPrimalType() const;
+    ///\e
+    virtual ProblemType _getDualType() const;
+
+    ///\e
+    virtual VarStatus _getColStatus(int i) const;
+    ///\e
+    virtual VarStatus _getRowStatus(int i) const;
+
+    ///\e
+    virtual LpSkeleton* _newSolver() const;
+    ///\e
+    virtual LpSkeleton* _cloneSolver() const;
+    ///\e
+    virtual const char* _solverName() const;
+
+  };
+
+  /// \brief Interface for a skeleton MIP solver
+  ///
+  /// This class implements an interface for a skeleton MIP solver.
+  ///\ingroup lp_group
+  class MipSkeleton : public SkeletonSolverBase, public MipSolver {
+  public:
+    MipSkeleton() : SkeletonSolverBase(), MipSolver() {}
+
+  protected:
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual SolveExitStatus _solve();
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual Value _getSol(int i) const;
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual Value _getSolValue() const;
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual ProblemType _getType() const;
+
+    ///\e
+    virtual MipSkeleton* _newSolver() const;
+
+    ///\e
+    virtual MipSkeleton* _cloneSolver() const;
+    ///\e
+    virtual const char* _solverName() const;
+
+  };
+
+} //namespace lemon
+
+#endif // LEMON_LP_SKELETON
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 314)
+++ lemon/maps.h	(revision 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: lemon/math.h
===================================================================
--- lemon/math.h	(revision 209)
+++ lemon/math.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: lemon/max_matching.h
===================================================================
--- lemon/max_matching.h	(revision 342)
+++ lemon/max_matching.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).
@@ -417,5 +417,5 @@
     /// \ref init(), \ref greedyInit() or \ref matchingInit()
     /// functions first, then you can start the algorithm with the \ref
-    /// startParse() or startDense() functions.
+    /// startSparse() or startDense() functions.
 
     ///@{
Index: lemon/nauty_reader.h
===================================================================
--- lemon/nauty_reader.h	(revision 371)
+++ lemon/nauty_reader.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: lemon/path.h
===================================================================
--- lemon/path.h	(revision 313)
+++ lemon/path.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: lemon/preflow.h
===================================================================
--- lemon/preflow.h	(revision 437)
+++ lemon/preflow.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: lemon/radix_sort.h
===================================================================
--- lemon/radix_sort.h	(revision 467)
+++ lemon/radix_sort.h	(revision 467)
@@ -0,0 +1,487 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef RADIX_SORT_H
+#define RADIX_SORT_H
+
+/// \ingroup auxalg
+/// \file
+/// \brief Radix sort
+///
+/// Linear time sorting algorithms
+
+#include <vector>
+#include <limits>
+#include <iterator>
+#include <algorithm>
+
+namespace lemon {
+
+  namespace _radix_sort_bits {
+
+    template <typename Value>
+    struct Identity {
+      const Value& operator()(const Value& val) {
+        return val;
+      }
+    };
+
+
+    template <typename Value, typename Iterator, typename Functor>
+    Iterator radixSortPartition(Iterator first, Iterator last,
+                                Functor functor, Value mask) {
+      while (first != last && !(functor(*first) & mask)) {
+        ++first;
+      }
+      if (first == last) {
+        return first;
+      }
+      --last;
+      while (first != last && (functor(*last) & mask)) {
+        --last;
+      }
+      if (first == last) {
+        return first;
+      }
+      std::iter_swap(first, last);
+      ++first;
+      if (!(first < last)) {
+        return first;
+      }
+      while (true) {
+        while (!(functor(*first) & mask)) {
+          ++first;
+        }
+        --last;
+        while (functor(*last) & mask) {
+          --last;
+        }
+        if (!(first < last)) {
+          return first;
+        }
+        std::iter_swap(first, last);
+        ++first;
+      }
+    }
+
+    template <typename Iterator, typename Functor>
+    Iterator radixSortSignPartition(Iterator first, Iterator last,
+                                    Functor functor) {
+      while (first != last && functor(*first) < 0) {
+        ++first;
+      }
+      if (first == last) {
+        return first;
+      }
+      --last;
+      while (first != last && functor(*last) >= 0) {
+        --last;
+      }
+      if (first == last) {
+        return first;
+      }
+      std::iter_swap(first, last);
+      ++first;
+      if (!(first < last)) {
+        return first;
+      }
+      while (true) {
+        while (functor(*first) < 0) {
+          ++first;
+        }
+        --last;
+        while (functor(*last) >= 0) {
+          --last;
+        }
+        if (!(first < last)) {
+          return first;
+        }
+        std::iter_swap(first, last);
+        ++first;
+      }
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixIntroSort(Iterator first, Iterator last,
+                        Functor functor, Value mask) {
+      while (mask != 0 && last - first > 1) {
+        Iterator cut = radixSortPartition(first, last, functor, mask);
+        mask >>= 1;
+        radixIntroSort(first, cut, functor, mask);
+        first = cut;
+      }
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixSignedSort(Iterator first, Iterator last, Functor functor) {
+
+      Iterator cut = radixSortSignPartition(first, last, functor);
+
+      Value mask;
+      int max_digit;
+      Iterator it;
+
+      mask = ~0; max_digit = 0;
+      for (it = first; it != cut; ++it) {
+        while ((mask & functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1;
+        }
+      }
+      radixIntroSort(first, cut, functor, 1 << max_digit);
+
+      mask = 0; max_digit = 0;
+      for (it = cut; it != last; ++it) {
+        while ((mask | functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1; mask |= 1;
+        }
+      }
+      radixIntroSort(cut, last, functor, 1 << max_digit);
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixUnsignedSort(Iterator first, Iterator last, Functor functor) {
+
+      Value mask = 0;
+      int max_digit = 0;
+
+      Iterator it;
+      for (it = first; it != last; ++it) {
+        while ((mask | functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1; mask |= 1;
+        }
+      }
+      radixIntroSort(first, last, functor, 1 << max_digit);
+    }
+
+
+    template <typename Value,
+              bool sign = std::numeric_limits<Value>::is_signed >
+    struct RadixSortSelector {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        radixSignedSort<Value>(first, last, functor);
+      }
+    };
+
+    template <typename Value>
+    struct RadixSortSelector<Value, false> {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        radixUnsignedSort<Value>(first, last, functor);
+      }
+    };
+
+  }
+
+  /// \ingroup auxalg
+  ///
+  /// \brief Sorts the STL compatible range into ascending order.
+  ///
+  /// The \c radixSort sorts an STL compatible range into ascending
+  /// order.  The radix sort algorithm can sort items which are mapped
+  /// to integers with an adaptable unary function \c functor and the
+  /// order will be ascending according to these mapped values.
+  ///
+  /// It is also possible to use a normal function instead
+  /// of the functor object. If the functor is not given it will use
+  /// the identity function instead.
+  ///
+  /// This is a special quick sort algorithm where the pivot
+  /// values to split the items are choosen to be \f$ 2^k \f$ for each \c k.
+  /// Therefore, the time complexity of the
+  /// algorithm is \f$ O(\log(c)n) \f$ and it uses \f$ O(\log(c)) \f$,
+  /// additional space, where \c c is the maximal value and \c n is the
+  /// number of the items in the container.
+  ///
+  /// \param first The begin of the given range.
+  /// \param last The end of the given range.
+  /// \param functor An adaptible unary function or a normal function
+  /// which maps the items to any integer type which can be either
+  /// signed or unsigned.
+  ///
+  /// \sa stableRadixSort()
+  template <typename Iterator, typename Functor>
+  void radixSort(Iterator first, Iterator last, Functor functor) {
+    using namespace _radix_sort_bits;
+    typedef typename Functor::result_type Value;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator>
+  void radixSort(Iterator first, Iterator last) {
+    using namespace _radix_sort_bits;
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    RadixSortSelector<Value>::sort(first, last, Identity<Value>());
+  }
+
+  namespace _radix_sort_bits {
+
+    template <typename Value>
+    unsigned char valueByte(Value value, int byte) {
+      return value >> (std::numeric_limits<unsigned char>::digits * byte);
+    }
+
+    template <typename Functor, typename Key>
+    void stableRadixIntroSort(Key *first, Key *last, Key *target,
+                              int byte, Functor functor) {
+      const int size =
+        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
+      std::vector<int> counter(size);
+      for (int i = 0; i < size; ++i) {
+        counter[i] = 0;
+      }
+      Key *it = first;
+      while (first != last) {
+        ++counter[valueByte(functor(*first), byte)];
+        ++first;
+      }
+      int prev, num = 0;
+      for (int i = 0; i < size; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      while (it != last) {
+        target[counter[valueByte(functor(*it), byte)]++] = *it;
+        ++it;
+      }
+    }
+
+    template <typename Functor, typename Key>
+    void signedStableRadixIntroSort(Key *first, Key *last, Key *target,
+                                    int byte, Functor functor) {
+      const int size =
+        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
+      std::vector<int> counter(size);
+      for (int i = 0; i < size; ++i) {
+        counter[i] = 0;
+      }
+      Key *it = first;
+      while (first != last) {
+        counter[valueByte(functor(*first), byte)]++;
+        ++first;
+      }
+      int prev, num = 0;
+      for (int i = size / 2; i < size; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      for (int i = 0; i < size / 2; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      while (it != last) {
+        target[counter[valueByte(functor(*it), byte)]++] = *it;
+        ++it;
+      }
+    }
+
+
+    template <typename Value, typename Iterator, typename Functor>
+    void stableRadixSignedSort(Iterator first, Iterator last, Functor functor) {
+      if (first == last) return;
+      typedef typename std::iterator_traits<Iterator>::value_type Key;
+      typedef std::allocator<Key> Allocator;
+      Allocator allocator;
+
+      int length = std::distance(first, last);
+      Key* buffer = allocator.allocate(2 * length);
+      try {
+        bool dir = true;
+        std::copy(first, last, buffer);
+        for (int i = 0; i < int(sizeof(Value)) - 1; ++i) {
+          if (dir) {
+            stableRadixIntroSort(buffer, buffer + length, buffer + length,
+                                 i, functor);
+          } else {
+            stableRadixIntroSort(buffer + length, buffer + 2 * length, buffer,
+                                 i, functor);
+          }
+          dir = !dir;
+        }
+        if (dir) {
+          signedStableRadixIntroSort(buffer, buffer + length, buffer + length,
+                                     sizeof(Value) - 1, functor);
+          std::copy(buffer + length, buffer + 2 * length, first);
+        }        else {
+          signedStableRadixIntroSort(buffer + length, buffer + 2 * length,
+                                     buffer, sizeof(Value) - 1, functor);
+          std::copy(buffer, buffer + length, first);
+        }
+      } catch (...) {
+        allocator.deallocate(buffer, 2 * length);
+        throw;
+      }
+      allocator.deallocate(buffer, 2 * length);
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void stableRadixUnsignedSort(Iterator first, Iterator last,
+                                 Functor functor) {
+      if (first == last) return;
+      typedef typename std::iterator_traits<Iterator>::value_type Key;
+      typedef std::allocator<Key> Allocator;
+      Allocator allocator;
+
+      int length = std::distance(first, last);
+      Key *buffer = allocator.allocate(2 * length);
+      try {
+        bool dir = true;
+        std::copy(first, last, buffer);
+        for (int i = 0; i < int(sizeof(Value)); ++i) {
+          if (dir) {
+            stableRadixIntroSort(buffer, buffer + length,
+                                 buffer + length, i, functor);
+          } else {
+            stableRadixIntroSort(buffer + length, buffer + 2 * length,
+                                 buffer, i, functor);
+          }
+          dir = !dir;
+        }
+        if (dir) {
+          std::copy(buffer, buffer + length, first);
+        }        else {
+          std::copy(buffer + length, buffer + 2 * length, first);
+        }
+      } catch (...) {
+        allocator.deallocate(buffer, 2 * length);
+        throw;
+      }
+      allocator.deallocate(buffer, 2 * length);
+    }
+
+
+
+    template <typename Value,
+              bool sign = std::numeric_limits<Value>::is_signed >
+    struct StableRadixSortSelector {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        stableRadixSignedSort<Value>(first, last, functor);
+      }
+    };
+
+    template <typename Value>
+    struct StableRadixSortSelector<Value, false> {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        stableRadixUnsignedSort<Value>(first, last, functor);
+      }
+    };
+
+  }
+
+  /// \ingroup auxalg
+  ///
+  /// \brief Sorts the STL compatible range into ascending order in a stable
+  /// way.
+  ///
+  /// This function sorts an STL compatible range into ascending
+  /// order according to an integer mapping in the same as radixSort() does.
+  ///
+  /// This sorting algorithm is stable, i.e. the order of two equal
+  /// elements remains the same after the sorting.
+  ///
+  /// This sort algorithm  use a radix forward sort on the
+  /// bytes of the integer number. The algorithm sorts the items
+  /// byte-by-byte. First, it counts how many times a byte value occurs
+  /// in the container, then it copies the corresponding items to
+  /// another container in asceding order in \c O(n) time.
+  ///
+  /// The time complexity of the algorithm is \f$ O(\log(c)n) \f$ and
+  /// it uses \f$ O(n) \f$, additional space, where \c c is the
+  /// maximal value and \c n is the number of the items in the
+  /// container.
+  ///
+
+  /// \param first The begin of the given range.
+  /// \param last The end of the given range.
+  /// \param functor An adaptible unary function or a normal function
+  /// which maps the items to any integer type which can be either
+  /// signed or unsigned.
+  /// \sa radixSort()
+  template <typename Iterator, typename Functor>
+  void stableRadixSort(Iterator first, Iterator last, Functor functor) {
+    using namespace _radix_sort_bits;
+    typedef typename Functor::result_type Value;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator>
+  void stableRadixSort(Iterator first, Iterator last) {
+    using namespace _radix_sort_bits;
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    StableRadixSortSelector<Value>::sort(first, last, Identity<Value>());
+  }
+
+}
+
+#endif
Index: lemon/random.cc
===================================================================
--- lemon/random.cc	(revision 209)
+++ lemon/random.cc	(revision 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: lemon/random.h
===================================================================
--- lemon/random.h	(revision 392)
+++ lemon/random.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: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 388)
+++ lemon/smart_graph.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: lemon/soplex.cc
===================================================================
--- lemon/soplex.cc	(revision 485)
+++ lemon/soplex.cc	(revision 485)
@@ -0,0 +1,423 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <lemon/soplex.h>
+
+#include <soplex/soplex.h>
+
+
+///\file
+///\brief Implementation of the LEMON-SOPLEX lp solver interface.
+namespace lemon {
+
+  SoplexLp::SoplexLp() {
+    soplex = new soplex::SoPlex;
+  }
+
+  SoplexLp::~SoplexLp() {
+    delete soplex;
+  }
+
+  SoplexLp::SoplexLp(const SoplexLp& lp) {
+    rows = lp.rows;
+    cols = lp.cols;
+
+    soplex = new soplex::SoPlex;
+    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
+
+    _col_names = lp._col_names;
+    _col_names_ref = lp._col_names_ref;
+
+    _row_names = lp._row_names;
+    _row_names_ref = lp._row_names_ref;
+
+  }
+
+  void SoplexLp::_clear_temporals() {
+    _primal_values.clear();
+    _dual_values.clear();
+  }
+
+  SoplexLp* SoplexLp::_newSolver() const {
+    SoplexLp* newlp = new SoplexLp();
+    return newlp;
+  }
+
+  SoplexLp* SoplexLp::_cloneSolver() const {
+    SoplexLp* newlp = new SoplexLp(*this);
+    return newlp;
+  }
+
+  const char* SoplexLp::_solverName() const { return "SoplexLp"; }
+
+  int SoplexLp::_addCol() {
+    soplex::LPCol c;
+    c.setLower(-soplex::infinity);
+    c.setUpper(soplex::infinity);
+    soplex->addCol(c);
+
+    _col_names.push_back(std::string());
+
+    return soplex->nCols() - 1;
+  }
+
+  int SoplexLp::_addRow() {
+    soplex::LPRow r;
+    r.setLhs(-soplex::infinity);
+    r.setRhs(soplex::infinity);
+    soplex->addRow(r);
+
+    _row_names.push_back(std::string());
+
+    return soplex->nRows() - 1;
+  }
+
+
+  void SoplexLp::_eraseCol(int i) {
+    soplex->removeCol(i);
+    _col_names_ref.erase(_col_names[i]);
+    _col_names[i] = _col_names.back();
+    _col_names_ref[_col_names.back()] = i;
+    _col_names.pop_back();
+  }
+
+  void SoplexLp::_eraseRow(int i) {
+    soplex->removeRow(i);
+    _row_names_ref.erase(_row_names[i]);
+    _row_names[i] = _row_names.back();
+    _row_names_ref[_row_names.back()] = i;
+    _row_names.pop_back();
+  }
+
+  void SoplexLp::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.relocateIndex(i, cols.maxIndex());
+  }
+  void SoplexLp::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.relocateIndex(i, rows.maxIndex());
+  }
+
+  void SoplexLp::_getColName(int c, std::string &name) const {
+    name = _col_names[c];
+  }
+
+  void SoplexLp::_setColName(int c, const std::string &name) {
+    _col_names_ref.erase(_col_names[c]);
+    _col_names[c] = name;
+    if (!name.empty()) {
+      _col_names_ref.insert(std::make_pair(name, c));
+    }
+  }
+
+  int SoplexLp::_colByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it =
+      _col_names_ref.find(name);
+    if (it != _col_names_ref.end()) {
+      return it->second;
+    } else {
+      return -1;
+    }
+  }
+
+  void SoplexLp::_getRowName(int r, std::string &name) const {
+    name = _row_names[r];
+  }
+
+  void SoplexLp::_setRowName(int r, const std::string &name) {
+    _row_names_ref.erase(_row_names[r]);
+    _row_names[r] = name;
+    if (!name.empty()) {
+      _row_names_ref.insert(std::make_pair(name, r));
+    }
+  }
+
+  int SoplexLp::_rowByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it =
+      _row_names_ref.find(name);
+    if (it != _row_names_ref.end()) {
+      return it->second;
+    } else {
+      return -1;
+    }
+  }
+
+
+  void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      soplex->changeElement(i, j, 0.0);
+    }
+    for(ExprIterator it = b; it != e; ++it) {
+      soplex->changeElement(i, it->first, it->second);
+    }
+  }
+
+  void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const {
+    const soplex::SVector& vec = soplex->rowVector(i);
+    for (int k = 0; k < vec.size(); ++k) {
+      *b = std::make_pair(vec.index(k), vec.value(k));
+      ++b;
+    }
+  }
+
+  void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
+    for (int i = 0; i < soplex->nRows(); ++i) {
+      soplex->changeElement(i, j, 0.0);
+    }
+    for(ExprIterator it = b; it != e; ++it) {
+      soplex->changeElement(it->first, j, it->second);
+    }
+  }
+
+  void SoplexLp::_getColCoeffs(int i, InsertIterator b) const {
+    const soplex::SVector& vec = soplex->colVector(i);
+    for (int k = 0; k < vec.size(); ++k) {
+      *b = std::make_pair(vec.index(k), vec.value(k));
+      ++b;
+    }
+  }
+
+  void SoplexLp::_setCoeff(int i, int j, Value value) {
+    soplex->changeElement(i, j, value);
+  }
+
+  SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const {
+    return soplex->rowVector(i)[j];
+  }
+
+  void SoplexLp::_setColLowerBound(int i, Value value) {
+    LEMON_ASSERT(value != INF, "Invalid bound");
+    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
+  }
+
+  SoplexLp::Value SoplexLp::_getColLowerBound(int i) const {
+    double value = soplex->lower(i);
+    return value != -soplex::infinity ? value : -INF;
+  }
+
+  void SoplexLp::_setColUpperBound(int i, Value value) {
+    LEMON_ASSERT(value != -INF, "Invalid bound");
+    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
+  }
+
+  SoplexLp::Value SoplexLp::_getColUpperBound(int i) const {
+    double value = soplex->upper(i);
+    return value != soplex::infinity ? value : INF;
+  }
+
+  void SoplexLp::_setRowLowerBound(int i, Value lb) {
+    LEMON_ASSERT(lb != INF, "Invalid bound");
+    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
+  }
+
+  SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const {
+    double res = soplex->lhs(i);
+    return res == -soplex::infinity ? -INF : res;
+  }
+
+  void SoplexLp::_setRowUpperBound(int i, Value ub) {
+    LEMON_ASSERT(ub != -INF, "Invalid bound");
+    soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
+  }
+
+  SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const {
+    double res = soplex->rhs(i);
+    return res == soplex::infinity ? INF : res;
+  }
+
+  void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      soplex->changeObj(j, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      soplex->changeObj(it->first, it->second);
+    }
+  }
+
+  void SoplexLp::_getObjCoeffs(InsertIterator b) const {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      Value coef = soplex->obj(j);
+      if (coef != 0.0) {
+        *b = std::make_pair(j, coef);
+        ++b;
+      }
+    }
+  }
+
+  void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
+    soplex->changeObj(i, obj_coef);
+  }
+
+  SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
+    return soplex->obj(i);
+  }
+
+  SoplexLp::SolveExitStatus SoplexLp::_solve() {
+
+    _clear_temporals();
+
+    soplex::SPxSolver::Status status = soplex->solve();
+
+    switch (status) {
+    case soplex::SPxSolver::OPTIMAL:
+    case soplex::SPxSolver::INFEASIBLE:
+    case soplex::SPxSolver::UNBOUNDED:
+      return SOLVED;
+    default:
+      return UNSOLVED;
+    }
+  }
+
+  SoplexLp::Value SoplexLp::_getPrimal(int i) const {
+    if (_primal_values.empty()) {
+      _primal_values.resize(soplex->nCols());
+      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
+      soplex->getPrimal(pv);
+    }
+    return _primal_values[i];
+  }
+
+  SoplexLp::Value SoplexLp::_getDual(int i) const {
+    if (_dual_values.empty()) {
+      _dual_values.resize(soplex->nRows());
+      soplex::Vector dv(_dual_values.size(), &_dual_values.front());
+      soplex->getDual(dv);
+    }
+    return _dual_values[i];
+  }
+
+  SoplexLp::Value SoplexLp::_getPrimalValue() const {
+    return soplex->objValue();
+  }
+
+  SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const {
+    switch (soplex->getBasisColStatus(i)) {
+    case soplex::SPxSolver::BASIC:
+      return BASIC;
+    case soplex::SPxSolver::ON_UPPER:
+      return UPPER;
+    case soplex::SPxSolver::ON_LOWER:
+      return LOWER;
+    case soplex::SPxSolver::FIXED:
+      return FIXED;
+    case soplex::SPxSolver::ZERO:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return VarStatus();
+    }
+  }
+
+  SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const {
+    switch (soplex->getBasisRowStatus(i)) {
+    case soplex::SPxSolver::BASIC:
+      return BASIC;
+    case soplex::SPxSolver::ON_UPPER:
+      return UPPER;
+    case soplex::SPxSolver::ON_LOWER:
+      return LOWER;
+    case soplex::SPxSolver::FIXED:
+      return FIXED;
+    case soplex::SPxSolver::ZERO:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return VarStatus();
+    }
+  }
+
+  SoplexLp::Value SoplexLp::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      _primal_ray.resize(soplex->nCols());
+      soplex::Vector pv(_primal_ray.size(), &_primal_ray.front());
+      soplex->getDualfarkas(pv);
+    }
+    return _primal_ray[i];
+  }
+
+  SoplexLp::Value SoplexLp::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+      _dual_ray.resize(soplex->nRows());
+      soplex::Vector dv(_dual_ray.size(), &_dual_ray.front());
+      soplex->getDualfarkas(dv);
+    }
+    return _dual_ray[i];
+  }
+
+  SoplexLp::ProblemType SoplexLp::_getPrimalType() const {
+    switch (soplex->status()) {
+    case soplex::SPxSolver::OPTIMAL:
+      return OPTIMAL;
+    case soplex::SPxSolver::UNBOUNDED:
+      return UNBOUNDED;
+    case soplex::SPxSolver::INFEASIBLE:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+  }
+
+  SoplexLp::ProblemType SoplexLp::_getDualType() const {
+    switch (soplex->status()) {
+    case soplex::SPxSolver::OPTIMAL:
+      return OPTIMAL;
+    case soplex::SPxSolver::UNBOUNDED:
+      return UNBOUNDED;
+    case soplex::SPxSolver::INFEASIBLE:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+  }
+
+  void SoplexLp::_setSense(Sense sense) {
+    switch (sense) {
+    case MIN:
+      soplex->changeSense(soplex::SPxSolver::MINIMIZE);
+      break;
+    case MAX:
+      soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
+    }
+  }
+
+  SoplexLp::Sense SoplexLp::_getSense() const {
+    switch (soplex->spxSense()) {
+    case soplex::SPxSolver::MAXIMIZE:
+      return MAX;
+    case soplex::SPxSolver::MINIMIZE:
+      return MIN;
+    default:
+      LEMON_ASSERT(false, "Wrong sense.");
+      return SoplexLp::Sense();
+    }
+  }
+
+  void SoplexLp::_clear() {
+    soplex->clear();
+    _col_names.clear();
+    _col_names_ref.clear();
+    _row_names.clear();
+    _row_names_ref.clear();
+    cols.clear();
+    rows.clear();
+    _clear_temporals();
+  }
+
+} //namespace lemon
+
Index: lemon/soplex.h
===================================================================
--- lemon/soplex.h	(revision 485)
+++ lemon/soplex.h	(revision 485)
@@ -0,0 +1,151 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_SOPLEX_H
+#define LEMON_SOPLEX_H
+
+///\file
+///\brief Header of the LEMON-SOPLEX lp solver interface.
+
+#include <vector>
+#include <string>
+
+#include <lemon/lp_base.h>
+
+// Forward declaration
+namespace soplex {
+  class SoPlex;
+}
+
+namespace lemon {
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Interface for the SOPLEX solver
+  ///
+  /// This class implements an interface for the SoPlex LP solver.
+  /// The SoPlex library is an object oriented lp solver library
+  /// developed at the Konrad-Zuse-Zentrum für Informationstechnik
+  /// Berlin (ZIB). You can find detailed information about it at the
+  /// <tt>http://soplex.zib.de</tt> address.
+  class SoplexLp : public LpSolver {
+  private:
+
+    soplex::SoPlex* soplex;
+
+    std::vector<std::string> _col_names;
+    std::map<std::string, int> _col_names_ref;
+
+    std::vector<std::string> _row_names;
+    std::map<std::string, int> _row_names_ref;
+
+  private:
+
+    // these values cannot be retrieved element by element
+    mutable std::vector<Value> _primal_values;
+    mutable std::vector<Value> _dual_values;
+
+    mutable std::vector<Value> _primal_ray;
+    mutable std::vector<Value> _dual_ray;
+
+    void _clear_temporals();
+
+  public:
+
+    /// \e
+    SoplexLp();
+    /// \e
+    SoplexLp(const SoplexLp&);
+    /// \e
+    ~SoplexLp();
+
+  protected:
+
+    virtual SoplexLp* _newSolver() const;
+    virtual SoplexLp* _cloneSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+    virtual void _clear();
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_SOPLEX_H
+
Index: lemon/suurballe.h
===================================================================
--- lemon/suurballe.h	(revision 358)
+++ lemon/suurballe.h	(revision 463)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -52,5 +52,5 @@
   ///
   /// \note For finding node-disjoint paths this algorithm can be used
-  /// with \ref SplitDigraphAdaptor.
+  /// with \ref SplitNodes.
 #ifdef DOXYGEN
   template <typename Digraph, typename LengthMap>
@@ -77,5 +77,5 @@
 
   private:
-  
+
     /// \brief Special implementation of the Dijkstra algorithm
     /// for finding shortest paths in the residual network.
@@ -107,5 +107,5 @@
       // The processed (i.e. permanently labeled) nodes
       std::vector<Node> _proc_nodes;
-      
+
       Node _s;
       Node _t;
@@ -201,5 +201,5 @@
     // The length map
     const LengthMap &_length;
-    
+
     // Arc map of the current flow
     FlowMap *_flow;
@@ -269,5 +269,5 @@
     /// This function sets the potential map.
     ///
-    /// The potentials provide the dual solution of the underlying 
+    /// The potentials provide the dual solution of the underlying
     /// minimum cost flow problem.
     ///
@@ -331,5 +331,5 @@
       for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
 
-      _dijkstra = new ResidualDijkstra( _graph, *_flow, _length, 
+      _dijkstra = new ResidualDijkstra( _graph, *_flow, _length,
                                         *_potential, _pred,
                                         _source, _target );
@@ -371,5 +371,5 @@
       return _path_num;
     }
-    
+
     /// \brief Compute the paths from the flow.
     ///
Index: lemon/time_measure.h
===================================================================
--- lemon/time_measure.h	(revision 314)
+++ lemon/time_measure.h	(revision 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: lemon/tolerance.h
===================================================================
--- lemon/tolerance.h	(revision 280)
+++ lemon/tolerance.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: lemon/unionfind.h
===================================================================
--- lemon/unionfind.h	(revision 236)
+++ lemon/unionfind.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).
@@ -1178,7 +1178,8 @@
             if (nodes[nodes[jd].next].size < cmax) {
               pushLeft(nodes[jd].next, nodes[jd].left);
-              if (less(nodes[jd].left, nodes[jd].next)) {
-                nodes[nodes[jd].next].prio = nodes[nodes[jd].left].prio;
-                nodes[nodes[jd].next].item = nodes[nodes[jd].left].item;
+              if (less(jd, nodes[jd].next) ||
+                  nodes[jd].item == nodes[pd].item) {
+                nodes[nodes[jd].next].prio = nodes[jd].prio;
+                nodes[nodes[jd].next].item = nodes[jd].item;
               }
               popLeft(pd);
@@ -1189,7 +1190,8 @@
               popLeft(nodes[jd].next);
               pushRight(jd, ld);
-              if (less(ld, nodes[jd].left)) {
+              if (less(ld, nodes[jd].left) ||
+                  nodes[ld].item == nodes[pd].item) {
                 nodes[jd].item = nodes[ld].item;
-                nodes[jd].prio = nodes[jd].prio;
+                nodes[jd].prio = nodes[ld].prio;
               }
               if (nodes[nodes[jd].next].item == nodes[ld].item) {
@@ -1220,7 +1222,8 @@
             if (nodes[nodes[jd].prev].size < cmax) {
               pushRight(nodes[jd].prev, nodes[jd].right);
-              if (less(nodes[jd].right, nodes[jd].prev)) {
-                nodes[nodes[jd].prev].prio = nodes[nodes[jd].right].prio;
-                nodes[nodes[jd].prev].item = nodes[nodes[jd].right].item;
+              if (less(jd, nodes[jd].prev) ||
+                  nodes[jd].item == nodes[pd].item) {
+                nodes[nodes[jd].prev].prio = nodes[jd].prio;
+                nodes[nodes[jd].prev].item = nodes[jd].item;
               }
               popRight(pd);
@@ -1231,7 +1234,8 @@
               popRight(nodes[jd].prev);
               pushLeft(jd, ld);
-              if (less(ld, nodes[jd].right)) {
+              if (less(ld, nodes[jd].right) ||
+                  nodes[ld].item == nodes[pd].item) {
                 nodes[jd].item = nodes[ld].item;
-                nodes[jd].prio = nodes[jd].prio;
+                nodes[jd].prio = nodes[ld].prio;
               }
               if (nodes[nodes[jd].prev].item == nodes[ld].item) {
@@ -1251,9 +1255,4 @@
       return comp(nodes[id].prio, nodes[jd].prio);
     }
-
-    bool equal(int id, int jd) const {
-      return !less(id, jd) && !less(jd, id);
-    }
-
 
   public:
@@ -1401,5 +1400,12 @@
               push(new_id, right_id);
               pushRight(new_id, ~(classes[r].parent));
-              setPrio(new_id);
+
+              if (less(~classes[r].parent, right_id)) {
+                nodes[new_id].item = nodes[~classes[r].parent].item;
+                nodes[new_id].prio = nodes[~classes[r].parent].prio;
+              } else {
+                nodes[new_id].item = nodes[right_id].item;
+                nodes[new_id].prio = nodes[right_id].prio;
+              }
 
               id = nodes[id].parent;
@@ -1441,5 +1447,12 @@
               push(new_id, left_id);
               pushLeft(new_id, ~(classes[l].parent));
-              setPrio(new_id);
+
+              if (less(~classes[l].parent, left_id)) {
+                nodes[new_id].item = nodes[~classes[l].parent].item;
+                nodes[new_id].prio = nodes[~classes[l].parent].prio;
+              } else {
+                nodes[new_id].item = nodes[left_id].item;
+                nodes[new_id].prio = nodes[left_id].prio;
+              }
 
               id = nodes[id].parent;
