# HG changeset patch
# User Alpar Juttner <alpar@cs.elte.hu>
# Date 1382812662 -7200
#      Sat Oct 26 20:37:42 2013 +0200
# Node ID 81d113c593ef2fe691f5cc7ad2842a114fdb837f
# Parent  ce896fa7fd65d16cb390579f12f57249aeb874a4
Extended run time checking in debug mode, WIP (#462)

diff --git a/lemon/bits/graph_extender.h b/lemon/bits/graph_extender.h
--- a/lemon/bits/graph_extender.h
+++ b/lemon/bits/graph_extender.h
@@ -56,12 +56,12 @@
       return Parent::maxArcId();
     }
 
-    static Node fromId(int id, Node) {
-      return Parent::nodeFromId(id);
+    Node fromId(int id, Node) const {
+      return this->nodeFromId(id);
     }
 
-    static Arc fromId(int id, Arc) {
-      return Parent::arcFromId(id);
+    Arc fromId(int id, Arc) const {
+      return this->arcFromId(id);
     }
 
     Node oppositeNode(const Node &node, const Arc &arc) const {
@@ -355,15 +355,15 @@
       return Parent::maxEdgeId();
     }
 
-    static Node fromId(int id, Node) {
+    Node fromId(int id, Node) const {
       return Parent::nodeFromId(id);
     }
 
-    static Arc fromId(int id, Arc) {
+    Arc fromId(int id, Arc) const {
       return Parent::arcFromId(id);
     }
 
-    static Edge fromId(int id, Edge) {
+    Edge fromId(int id, Edge) const {
       return Parent::edgeFromId(id);
     }
 
@@ -791,15 +791,15 @@
       return Parent::maxEdgeId();
     }
 
-    static Node fromId(int id, Node) {
+    Node fromId(int id, Node) const {
       return Parent::nodeFromId(id);
     }
 
-    static Arc fromId(int id, Arc) {
+    Arc fromId(int id, Arc) const {
       return Parent::arcFromId(id);
     }
 
-    static Edge fromId(int id, Edge) {
+    fromId(int id, Edge) const {
       return Parent::edgeFromId(id);
     }
 
diff --git a/lemon/list_graph.h b/lemon/list_graph.h
--- a/lemon/list_graph.h
+++ b/lemon/list_graph.h
@@ -67,15 +67,56 @@
       friend class ListDigraph;
     protected:
 
+#ifdef LEMON_ENABLE_DEBUG
+      const Digraph *graph;
+#endif
       int id;
-      explicit Node(int pid) { id = pid;}
-
+
+      void set(const Digraph *g, int pid)
+      {
+#ifdef LEMON_ENABLE_DEBUG
+        graph=g;
+#else
+        ignore_unused_variable_warning(g);
+#endif
+        id = pid;
+      }
+
+      explicit Node(const Digraph *g, int pid) { set(g,pid); }
+
+      void check_initialized() const {
+        LEMON_DEBUG(graph || id == -1, "Node used uninitialized");
+      }     
+      void check_comparable(const Node &node) const {
+        check_initialized();
+        node.check_initialized();
+        LEMON_DEBUG(!graph || !node.graph || graph == node.graph,
+                    "Compare nodes pointing to different graphs");
+      }
     public:
-      Node() {}
-      Node (Invalid) { id = -1; }
-      bool operator==(const Node& node) const {return id == node.id;}
-      bool operator!=(const Node& node) const {return id != node.id;}
-      bool operator<(const Node& node) const {return id < node.id;}
+      Node()
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL), id(-2)
+#endif
+      {}
+      Node (Invalid)
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL)
+#endif
+      { id = -1; }
+      bool operator==(const Node& node) const
+      {
+        check_comparable(node);
+        return id == node.id;
+      }
+      bool operator!=(const Node& node) const {
+        check_comparable(node);
+        return id != node.id;
+      }
+      bool operator<(const Node& node) const {
+        check_comparable(node);
+        return id < node.id;
+      }
     };
 
     class Arc {
@@ -83,19 +124,78 @@
       friend class ListDigraph;
     protected:
 
+#ifdef LEMON_ENABLE_DEBUG
+      const Digraph *graph;
+#endif
       int id;
-      explicit Arc(int pid) { id = pid;}
+      
+      void set(const Digraph *g, int pid)
+      {
+#ifdef LEMON_ENABLE_DEBUG
+        graph=g;
+#else
+        ignore_unused_variable_warning(g);
+#endif
+        id = pid;
+      }
+
+      explicit Arc(const Digraph *g, int pid) { set(g,pid); }
+
+      void check_initialized() const {
+        LEMON_DEBUG(graph || id == -1, "Arc used uninitialized");
+      }     
+      void check_comparable(const Arc &arc) const {
+        check_initialized();
+        arc.check_initialized();
+        LEMON_DEBUG(!graph || !arc.graph || graph == arc.graph,
+                    "Compare arcs pointing to different graphs");
+      }
 
     public:
-      Arc() {}
-      Arc (Invalid) { id = -1; }
-      bool operator==(const Arc& arc) const {return id == arc.id;}
-      bool operator!=(const Arc& arc) const {return id != arc.id;}
-      bool operator<(const Arc& arc) const {return id < arc.id;}
+      Arc()
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL), id(-2)
+#endif
+      {}
+      Arc (Invalid)
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL)
+#endif
+      { id = -1; }
+      bool operator==(const Arc& arc) const {
+        check_comparable(arc);
+        return id == arc.id;
+      }
+      bool operator!=(const Arc& arc) const {
+        check_comparable(arc);
+        return id != arc.id;
+      }
+      bool operator<(const Arc& arc) const {
+        check_comparable(arc);
+        return id < arc.id;
+      }
     };
 
-
-
+  protected:
+    void check_mine(const Node &node) const 
+    {
+      ignore_unused_variable_warning(node);
+      LEMON_DEBUG(node.graph == this && 
+                  node.id >= 0 && node.id < static_cast<int>(nodes.size()) &&
+                  nodes[node.id].prev != -2,
+                  "Node points to a wrong graphs");
+    }
+    void check_mine(const Arc &arc) const
+    {
+      ignore_unused_variable_warning(arc);
+      LEMON_DEBUG(arc.graph == this &&
+                  arc.id >= 0 &&
+                  arc.id < static_cast<int>(arcs.size()) &&
+                  arcs[arc.id].prev_in != -2,
+                  "Arc points to a wrong graphs");
+    }
+    
+  public:
     ListDigraphBase()
       : nodes(), first_node(-1),
         first_free_node(-1), arcs(), first_free_arc(-1) {}
@@ -104,15 +204,24 @@
     int maxNodeId() const { return nodes.size()-1; }
     int maxArcId() const { return arcs.size()-1; }
 
-    Node source(Arc e) const { return Node(arcs[e.id].source); }
-    Node target(Arc e) const { return Node(arcs[e.id].target); }
+    Node source(Arc e) const
+    {
+      check_mine(e);
+      return Node(this,arcs[e.id].source);
+    }
+    Node target(Arc e) const
+    {
+      check_mine(e);
+      return Node(this,arcs[e.id].target);
+    }
 
 
     void first(Node& node) const {
-      node.id = first_node;
+      node.set(this, first_node);
     }
 
     void next(Node& node) const {
+      check_mine(node);
       node.id = nodes[node.id].next;
     }
 
@@ -122,10 +231,11 @@
       for(n = first_node;
           n != -1 && nodes[n].first_out == -1;
           n = nodes[n].next) {}
-      arc.id = (n == -1) ? -1 : nodes[n].first_out;
+      arc.set(this, (n == -1) ? -1 : nodes[n].first_out);
     }
 
     void next(Arc& arc) const {
+      check_mine(arc);
       if (arcs[arc.id].next_out != -1) {
         arc.id = arcs[arc.id].next_out;
       } else {
@@ -138,34 +248,45 @@
     }
 
     void firstOut(Arc &e, const Node& v) const {
-      e.id = nodes[v.id].first_out;
+      check_mine(v);
+      e.set(this, nodes[v.id].first_out);
     }
     void nextOut(Arc &e) const {
+      check_mine(e);
       e.id=arcs[e.id].next_out;
     }
 
     void firstIn(Arc &e, const Node& v) const {
-      e.id = nodes[v.id].first_in;
+      check_mine(v);
+      e.set(this,nodes[v.id].first_in);
     }
     void nextIn(Arc &e) const {
+      check_mine(e);
       e.id=arcs[e.id].next_in;
     }
 
 
-    static int id(Node v) { return v.id; }
-    static int id(Arc e) { return e.id; }
-
-    static Node nodeFromId(int id) { return Node(id);}
-    static Arc arcFromId(int id) { return Arc(id);}
+    int id(Node v) const { check_mine(v); /* TODO: INVALID? */ return v.id; }
+    int id(Arc e) const { check_mine(e);  /* TODO: INVALID? */ return e.id; }
+
+     //TODO: Check if id is valid.
+    Node nodeFromId(int id) const { return Node(this, id);} //TODO
+    Arc arcFromId(int id) const { return Arc(this, id);} //TODO
 
     bool valid(Node n) const {
-      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
-        nodes[n.id].prev != -2;
+      LEMON_DEBUG(n.graph == this || (n.graph == NULL && n.id == -1),
+                  "Node belongs to a different graph");
+      return ( n.id >= 0 &&
+               n.id < static_cast<int>(nodes.size()) &&
+               nodes[n.id].prev != -2 );
     }
 
-    bool valid(Arc a) const {
-      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
-        arcs[a.id].prev_in != -2;
+    bool valid(Arc a) const { 
+      LEMON_DEBUG(a.graph == this || (a.graph == NULL && a.id == -1),
+                  "Arc belongs to a different graph");
+      return ( a.id >= 0 &&
+               a.id < static_cast<int>(arcs.size()) &&
+               arcs[a.id].prev_in != -2 );
     }
 
     Node addNode() {
@@ -186,10 +307,12 @@
 
       nodes[n].first_in = nodes[n].first_out = -1;
 
-      return Node(n);
+      return Node(this, n);
     }
 
     Arc addArc(Node u, Node v) {
+      check_mine(u);
+      check_mine(v);
       int n;
 
       if (first_free_arc == -1) {
@@ -217,10 +340,11 @@
 
       nodes[u.id].first_out = nodes[v.id].first_in = n;
 
-      return Arc(n);
+      return Arc(this, n);
     }
 
     void erase(const Node& node) {
+      check_mine(node);
       int n = node.id;
 
       if(nodes[n].next != -1) {
@@ -240,6 +364,7 @@
     }
 
     void erase(const Arc& arc) {
+      check_mine(arc);
       int n = arc.id;
 
       if(arcs[n].next_in!=-1) {
@@ -277,6 +402,8 @@
   protected:
     void changeTarget(Arc e, Node n)
     {
+      check_mine(e);
+      check_mine(n);
       if(arcs[e.id].next_in != -1)
         arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
       if(arcs[e.id].prev_in != -1)
@@ -292,6 +419,8 @@
     }
     void changeSource(Arc e, Node n)
     {
+      check_mine(e);
+      check_mine(n);
       if(arcs[e.id].next_out != -1)
         arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
       if(arcs[e.id].prev_out != -1)
@@ -453,6 +582,8 @@
     ///feature.
     void contract(Node u, Node v, bool r = true)
     {
+      check_mine(u); 
+      check_mine(v); 
       for(OutArcIt e(*this,v);e!=INVALID;) {
         OutArcIt f=e;
         ++f;
@@ -485,6 +616,7 @@
     ///\warning This functionality cannot be used together with the
     ///Snapshot feature.
     Node split(Node n, bool connect = true) {
+      check_mine(n); 
       Node b = addNode();
       nodes[b.id].first_out=nodes[n.id].first_out;
       nodes[n.id].first_out=-1;
@@ -509,6 +641,7 @@
     ///\warning This functionality cannot be used together with the
     ///Snapshot feature.
     Node split(Arc a) {
+      check_mine(a); 
       Node v = addNode();
       addArc(v,target(a));
       changeTarget(a,v);
@@ -821,51 +954,210 @@
       friend class ListGraphBase;
     protected:
 
+#ifdef LEMON_ENABLE_DEBUG
+      const Graph *graph;
+#endif
       int id;
-      explicit Node(int pid) { id = pid;}
+
+      void set(const Graph *g, int pid)
+      {
+#ifdef LEMON_ENABLE_DEBUG
+        graph=g;
+#else
+        ignore_unused_variable_warning(g);
+#endif
+        id = pid;
+      }
+
+      explicit Node(const Graph *g, int pid) { set(g,pid); }
+
+      void check_initialized() const {
+        LEMON_DEBUG(graph || id == -1, "Node used uninitialized");
+      }     
+      void check_comparable(const Node &node) const {
+        check_initialized();
+        node.check_initialized();
+        LEMON_DEBUG(!graph || !node.graph || graph == node.graph,
+                    "Compare nodes pointing to different graphs");
+      }
 
     public:
-      Node() {}
-      Node (Invalid) { id = -1; }
-      bool operator==(const Node& node) const {return id == node.id;}
-      bool operator!=(const Node& node) const {return id != node.id;}
-      bool operator<(const Node& node) const {return id < node.id;}
+      Node()
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL), id(-2)
+#endif
+      {}
+      Node (Invalid)
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL)
+#endif
+      { id = -1; }
+      bool operator==(const Node& node) const
+      {
+        check_comparable(node);
+        return id == node.id;
+      }
+      bool operator!=(const Node& node) const {
+        check_comparable(node);
+        return id != node.id;
+      }
+      bool operator<(const Node& node) const {
+        check_comparable(node);
+        return id < node.id;
+      }
     };
 
+    class Arc;
+
     class Edge {
       friend class ListGraphBase;
+      friend class Arc;
     protected:
 
+#ifdef LEMON_ENABLE_DEBUG
+      const Graph *graph;
+#endif
       int id;
-      explicit Edge(int pid) { id = pid;}
+      
+      void set(const Graph *g, int pid)
+      {
+#ifdef LEMON_ENABLE_DEBUG
+        graph=g;
+#else
+        ignore_unused_variable_warning(g);
+#endif
+        id = pid;
+      }
+
+      explicit Edge(const Graph *g, int pid) { set(g,pid); }
+
+      void check_initialized() const {
+        LEMON_DEBUG(graph || id == -1, "Arc used uninitialized");
+      }     
+      void check_comparable(const Edge &edge) const {
+        check_initialized();
+        edge.check_initialized();
+        LEMON_DEBUG(!graph || !edge.graph || graph == edge.graph,
+                    "Compare arcs pointing to different graphs");
+      }
 
     public:
-      Edge() {}
-      Edge (Invalid) { id = -1; }
-      bool operator==(const Edge& edge) const {return id == edge.id;}
-      bool operator!=(const Edge& edge) const {return id != edge.id;}
-      bool operator<(const Edge& edge) const {return id < edge.id;}
+      Edge()
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL), id(-2)
+#endif
+      {}
+      Edge (Invalid)
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL)
+#endif
+      { id = -1; }
+      bool operator==(const Edge& edge) const {
+        check_comparable(edge);
+        return id == edge.id;
+      }
+      bool operator!=(const Edge& edge) const {
+        check_comparable(edge);
+        return id != edge.id;
+      }
+      bool operator<(const Edge& edge) const {
+        check_comparable(edge);
+        return id < edge.id;
+      }
     };
 
     class Arc {
       friend class ListGraphBase;
     protected:
 
+#ifdef LEMON_ENABLE_DEBUG
+      const Graph *graph;
+#endif
       int id;
-      explicit Arc(int pid) { id = pid;}
+
+      void set(const Graph *g, int pid)
+      {
+#ifdef LEMON_ENABLE_DEBUG
+        graph=g;
+#else
+        ignore_unused_variable_warning(g);
+#endif
+        id = pid;
+      }
+
+      explicit Arc(const Graph *g, int pid) { set(g,pid); }
+      
+      void check_initialized() const {
+        LEMON_DEBUG(graph || id == -1, "Arc used uninitialized");
+      }     
+      void check_comparable(const Arc &arc) const {
+        check_initialized();
+        arc.check_initialized();
+        LEMON_DEBUG(!graph || !arc.graph || graph == arc.graph,
+                    "Compare arcs pointing to different graphs");
+      }
 
     public:
       operator Edge() const {
-        return id != -1 ? edgeFromId(id / 2) : INVALID;
+#ifdef LEMON_ENABLE_DEBUG
+        return id != -1 ? Edge(graph, id / 2) : INVALID;
+#else
+        return id != -1 ? Edge(NULL , id / 2) : INVALID;
+#endif
       }
 
-      Arc() {}
-      Arc (Invalid) { id = -1; }
-      bool operator==(const Arc& arc) const {return id == arc.id;}
-      bool operator!=(const Arc& arc) const {return id != arc.id;}
-      bool operator<(const Arc& arc) const {return id < arc.id;}
+      Arc()
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL), id(-2)
+#endif
+      {}
+      Arc (Invalid)
+#ifdef LEMON_ENABLE_DEBUG
+        : graph(NULL)
+#endif
+      { id = -1; }
+      bool operator==(const Arc& arc) const {
+        check_comparable(arc);
+        return id == arc.id;
+      }
+      bool operator!=(const Arc& arc) const {
+        check_comparable(arc);
+        return id != arc.id;
+      }
+      bool operator<(const Arc& arc) const {
+        check_comparable(arc);
+        return id < arc.id;
+      }
     };
 
+
+  protected:
+    void check_mine(const Node &node) const 
+    {
+      ignore_unused_variable_warning(node);
+      LEMON_DEBUG(node.graph == this && 
+                  node.id >= 0 && node.id < static_cast<int>(nodes.size()) &&
+                  nodes[node.id].prev != -2,
+                  "Node points to a wrong graphs");
+    }
+    void check_mine(const Edge &edge) const //TODO
+    {
+      ignore_unused_variable_warning(edge);
+      LEMON_DEBUG(edge.id >= 0 &&
+              2 * edge.id < static_cast<int>(arcs.size()) &&
+                  arcs[2 * edge.id].prev_out != -2,
+                  "Edge points to a wrong graphs");
+    }
+    void check_mine(const Arc &arc) const //TODO
+    {
+      ignore_unused_variable_warning(arc);
+      LEMON_DEBUG(arc.id >= 0 &&
+                  arc.id < static_cast<int>(arcs.size()) &&
+                  arcs[arc.id].prev_out != -2,
+                  "Arc points to a wrong graphs");
+    }
+    
+  public:
     ListGraphBase()
       : nodes(), first_node(-1),
         first_free_node(-1), arcs(), first_free_arc(-1) {}
@@ -875,25 +1167,44 @@
     int maxEdgeId() const { return arcs.size() / 2 - 1; }
     int maxArcId() const { return arcs.size()-1; }
 
-    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
-    Node target(Arc e) const { return Node(arcs[e.id].target); }
-
-    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
-    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
-
-    static bool direction(Arc e) {
+    Node source(Arc e) const
+    {
+      check_mine(e);
+      return Node(this, arcs[e.id ^ 1].target);
+    }
+    Node target(Arc e) const
+    {
+      check_mine(e);
+      return Node(this, arcs[e.id].target);
+    }
+
+    Node u(Edge e) const
+    {
+      check_mine(e);
+      return Node(this, arcs[2 * e.id].target);
+    }
+    Node v(Edge e) const
+    {
+      check_mine(e);
+      return Node(this, arcs[2 * e.id + 1].target);
+    }
+
+    bool direction(Arc e) const {
+      check_mine(e);
       return (e.id & 1) == 1;
     }
 
-    static Arc direct(Edge e, bool d) {
-      return Arc(e.id * 2 + (d ? 1 : 0));
+    Arc direct(Edge e, bool d) const {
+      check_mine(e);
+      return Arc(this, e.id * 2 + (d ? 1 : 0));
     }
 
     void first(Node& node) const {
-      node.id = first_node;
+      node.set(this,first_node);
     }
 
     void next(Node& node) const {
+      check_mine(node);
       node.id = nodes[node.id].next;
     }
 
@@ -902,10 +1213,11 @@
       while (n != -1 && nodes[n].first_out == -1) {
         n = nodes[n].next;
       }
-      e.id = (n == -1) ? -1 : nodes[n].first_out;
+      e.set(this, (n == -1) ? -1 : nodes[n].first_out);
     }
 
     void next(Arc& e) const {
+      check_mine(e);
       if (arcs[e.id].next_out != -1) {
         e.id = arcs[e.id].next_out;
       } else {
@@ -919,21 +1231,24 @@
 
     void first(Edge& e) const {
       int n = first_node;
+      int eid;
       while (n != -1) {
-        e.id = nodes[n].first_out;
-        while ((e.id & 1) != 1) {
-          e.id = arcs[e.id].next_out;
+        eid = nodes[n].first_out;
+        while ((eid & 1) != 1) {
+          eid = arcs[eid].next_out;
         }
-        if (e.id != -1) {
-          e.id /= 2;
+        if (eid != -1) {
+          eid /= 2;
+          e.set(this,eid);
           return;
         }
         n = nodes[n].next;
       }
-      e.id = -1;
+      e.set(this,-1);
     }
 
     void next(Edge& e) const {
+      check_mine(e);
       int n = arcs[e.id * 2].target;
       e.id = arcs[(e.id * 2) | 1].next_out;
       while ((e.id & 1) != 1) {
@@ -959,32 +1274,46 @@
     }
 
     void firstOut(Arc &e, const Node& v) const {
-      e.id = nodes[v.id].first_out;
+      check_mine(v);
+      e.set(this, nodes[v.id].first_out);
     }
+
     void nextOut(Arc &e) const {
+      check_mine(e);
       e.id = arcs[e.id].next_out;
     }
 
     void firstIn(Arc &e, const Node& v) const {
-      e.id = ((nodes[v.id].first_out) ^ 1);
-      if (e.id == -2) e.id = -1;
+      check_mine(v);
+      int eid = ((nodes[v.id].first_out) ^ 1);
+      if (eid == -2) eid = -1;
+      e.set(this, eid);
     }
     void nextIn(Arc &e) const {
+      check_mine(e);
       e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
       if (e.id == -2) e.id = -1;
     }
 
     void firstInc(Edge &e, bool& d, const Node& v) const {
+      check_mine(v);
       int a = nodes[v.id].first_out;
-      if (a != -1 ) {
-        e.id = a / 2;
-        d = ((a & 1) == 1);
-      } else {
-        e.id = -1;
-        d = true;
-      }
+      // //GCC falsely report that eid is used uninitialized:
+      // int eid;
+      // if (a != -1 ) {
+      //   e.id = a / 2;
+      //   d = ((a & 1) == 1);
+      // } else {
+      //   e.id = -1;
+      //   d = true;
+      // }
+      int eid = (a != -1 ) ?
+        ( d = ((a & 1) == 1), a / 2 ) :
+        ( d = true, -1 );
+      e.set(this,eid);
     }
     void nextInc(Edge &e, bool& d) const {
+      check_mine(e);
       int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
       if (a != -1 ) {
         e.id = a / 2;
@@ -995,27 +1324,37 @@
       }
     }
 
-    static int id(Node v) { return v.id; }
-    static int id(Arc e) { return e.id; }
-    static int id(Edge e) { return e.id; }
-
-    static Node nodeFromId(int id) { return Node(id);}
-    static Arc arcFromId(int id) { return Arc(id);}
-    static Edge edgeFromId(int id) { return Edge(id);}
-
+    int id(Node v) const { check_mine(v); return v.id; }
+    int id(Arc e) const  { check_mine(e); return e.id; }
+    int id(Edge e) const { check_mine(e); return e.id; }
+    
+    //TODO: Check if id is valid.
+    Node nodeFromId(int id) const  { return Node(this, id);}
+    Arc arcFromId(int id) const { return Arc(this, id);}
+    Edge edgeFromId(int id) const { return Edge(this, id);}
+    
     bool valid(Node n) const {
-      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
-        nodes[n.id].prev != -2;
+      LEMON_DEBUG(n.graph == this || (n.graph == NULL && n.id == -1),
+                  "Node belongs to a different graph");
+      return ( n.id >= 0 &&
+               n.id < static_cast<int>(nodes.size()) &&
+               nodes[n.id].prev != -2);
     }
 
     bool valid(Arc a) const {
-      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
-        arcs[a.id].prev_out != -2;
+      LEMON_DEBUG(a.graph == this || (a.graph == NULL && a.id == -1),
+                  "Arc belongs to a different graph");
+      return ( a.id >= 0 &&
+               a.id < static_cast<int>(arcs.size()) &&
+               arcs[a.id].prev_out != -2);
     }
 
     bool valid(Edge e) const {
-      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
-        arcs[2 * e.id].prev_out != -2;
+      LEMON_DEBUG(e.graph == this || (e.graph == NULL && e.id == -1),
+                  "Arc belongs to a different graph");
+      return (e.id >= 0 &&
+              2 * e.id < static_cast<int>(arcs.size()) &&
+              arcs[2 * e.id].prev_out != -2);
     }
 
     Node addNode() {
@@ -1036,10 +1375,12 @@
 
       nodes[n].first_out = -1;
 
-      return Node(n);
+      return Node(this,n);
     }
 
     Edge addEdge(Node u, Node v) {
+      check_mine(u);
+      check_mine(v);
       int n;
 
       if (first_free_arc == -1) {
@@ -1068,10 +1409,11 @@
       arcs[n | 1].prev_out = -1;
       nodes[u.id].first_out = (n | 1);
 
-      return Edge(n / 2);
+      return Edge(this, n / 2);
     }
 
     void erase(const Node& node) {
+      check_mine(node);
       int n = node.id;
 
       if(nodes[n].next != -1) {
@@ -1090,6 +1432,7 @@
     }
 
     void erase(const Edge& edge) {
+      check_mine(edge);
       int n = edge.id * 2;
 
       if (arcs[n].next_out != -1) {
@@ -1128,6 +1471,8 @@
   protected:
 
     void changeV(Edge e, Node n) {
+      check_mine(e);
+      check_mine(n);
       if(arcs[2 * e.id].next_out != -1) {
         arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
       }
@@ -1149,6 +1494,8 @@
     }
 
     void changeU(Edge e, Node n) {
+      check_mine(e);
+      check_mine(n);
       if(arcs[(2 * e.id) | 1].next_out != -1) {
         arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
           arcs[(2 * e.id) | 1].prev_out;
@@ -1313,6 +1660,8 @@
     ///\warning This functionality cannot be used together with the
     ///Snapshot feature.
     void contract(Node a, Node b, bool r = true) {
+      check_mine(a); 
+      check_mine(b); 
       for(IncEdgeIt e(*this, b); e!=INVALID;) {
         IncEdgeIt f = e; ++f;
         if (r && runningNode(e) == a) {
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -35,6 +35,7 @@
   hao_orlin_test
   heap_test
   kruskal_test
+  lemon_debug_test
   lgf_reader_writer_test
   lgf_test
   maps_test
diff --git a/test/digraph_test.cc b/test/digraph_test.cc
--- a/test/digraph_test.cc
+++ b/test/digraph_test.cc
@@ -236,12 +236,10 @@
   checkGraphOutArcList(G, n1, 0);
   checkGraphOutArcList(G, n2, 0);
   checkGraphOutArcList(G, n3, 1);
-  checkGraphOutArcList(G, n4, 0);
 
   checkGraphInArcList(G, n1, 1);
   checkGraphInArcList(G, n2, 0);
   checkGraphInArcList(G, n3, 0);
-  checkGraphInArcList(G, n4, 0);
 
   checkGraphConArcList(G, 1);
 }
diff --git a/test/lemon_debug_test.cc b/test/lemon_debug_test.cc
new file mode 100644
--- /dev/null
+++ b/test/lemon_debug_test.cc
@@ -0,0 +1,100 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_ENABLE_DEBUG
+#define LEMON_ENABLE_DEBUG
+#endif
+#undef NDEBUG
+#define LEMON_ASSERT_CUSTOM
+#define LEMON_CUSTOM_ASSERT_HANDLER test_assert_handler
+
+#include <lemon/error.h>
+#include <sstream>
+
+class DebugException : public lemon::Exception
+{    
+public:
+  std::string _file;
+  int _line;
+  std::string _function;
+  std::string _message;
+  std::string _assertion;
+  std::string _what;
+  DebugException(const char* file, int line,
+                const char* function, const char* message,
+                const char* assertion)
+    : _file(file), _line(line), _function(function), _message(message),
+      _assertion(assertion)
+  {
+    std::ostringstream f;
+    f << _file <<  ':' << _line << ": " << _function << ": " << _assertion;
+    _what = f.str();
+  }
+
+  virtual const char* what() const throw() {
+    return _what.c_str();
+  }
+  virtual ~DebugException() throw() {}
+};
+
+void test_assert_handler(const char* file, int line,
+                         const char* function, const char* message,
+                         const char* assertion)
+{
+  throw DebugException(file, line, function, message, assertion);
+}
+
+#define LEMON_CUSTOM_ASSERT_HANDLER test_assert_handler
+
+#include <lemon/list_graph.h>
+#include "test_tools.h"
+
+using namespace lemon;
+
+int main()
+{
+  ListDigraph g,h;
+
+  ListDigraph::Node n = g.addNode();
+  ListDigraph::NodeMap<int> map(g);
+  ListDigraph::Node n2 = h.addNode();
+
+  map[n]=12;
+  
+  g.erase(n);
+  
+  try {
+    map[n]=13;
+    check(true, "It should'n pass");
+  } catch (DebugException &d) {
+    check(d._message == "Node points to a wrong graphs",
+          "Wrong exception is thrown");
+  }
+
+  try {
+    map[n2]=13;
+    check(true, "It should'n pass");
+  } catch (DebugException &d) {
+    check(d._message == "Node points to a wrong graphs",
+          "Wrong exception is thrown");
+  }
+
+  check(true, "Something is wrong.");
+
+  return 0;
+}
