Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 39)
+++ lemon/list_graph.h	(revision 57)
@@ -17,2 +17,1451 @@
  */
 
+#ifndef LEMON_LIST_GRAPH_H
+#define LEMON_LIST_GRAPH_H
+
+///\ingroup graphs
+///\file
+///\brief ListDigraph, ListGraph classes.
+
+#include <lemon/bits/graph_extender.h>
+
+#include <vector>
+#include <list>
+
+namespace lemon {
+
+  class ListDigraphBase {
+
+  protected:
+    struct NodeT {
+      int first_in, first_out;
+      int prev, next;
+    };
+ 
+    struct ArcT {
+      int target, source;
+      int prev_in, prev_out;
+      int next_in, next_out;
+    };
+
+    std::vector<NodeT> nodes;
+
+    int first_node;
+
+    int first_free_node;
+
+    std::vector<ArcT> arcs;
+
+    int first_free_arc;
+    
+  public:
+    
+    typedef ListDigraphBase Digraph;
+    
+    class Node {
+      friend class ListDigraphBase;
+    protected:
+
+      int id;
+      explicit Node(int pid) { id = pid;}
+
+    public:
+      Node() {}
+      Node (Invalid) { id = -1; }
+      bool operator==(const Node& node) const {return id == node.id;}
+      bool operator!=(const Node& node) const {return id != node.id;}
+      bool operator<(const Node& node) const {return id < node.id;}
+    };
+
+    class Arc {
+      friend class ListDigraphBase;
+    protected:
+
+      int id;
+      explicit Arc(int pid) { id = pid;}
+
+    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;}
+    };
+
+
+
+    ListDigraphBase()
+      : nodes(), first_node(-1),
+	first_free_node(-1), arcs(), first_free_arc(-1) {}
+
+    
+    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); }
+
+
+    void first(Node& node) const { 
+      node.id = first_node;
+    }
+
+    void next(Node& node) const {
+      node.id = nodes[node.id].next;
+    }
+
+
+    void first(Arc& e) const { 
+      int n;
+      for(n = first_node; 
+	  n!=-1 && nodes[n].first_in == -1; 
+	  n = nodes[n].next);
+      e.id = (n == -1) ? -1 : nodes[n].first_in;
+    }
+
+    void next(Arc& arc) const {
+      if (arcs[arc.id].next_in != -1) {
+	arc.id = arcs[arc.id].next_in;
+      } else {
+	int n;
+	for(n = nodes[arcs[arc.id].target].next;
+	  n!=-1 && nodes[n].first_in == -1; 
+	  n = nodes[n].next);
+	arc.id = (n == -1) ? -1 : nodes[n].first_in;
+      }      
+    }
+
+    void firstOut(Arc &e, const Node& v) const {
+      e.id = nodes[v.id].first_out;
+    }
+    void nextOut(Arc &e) const {
+      e.id=arcs[e.id].next_out;
+    }
+
+    void firstIn(Arc &e, const Node& v) const {
+      e.id = nodes[v.id].first_in;
+    }
+    void nextIn(Arc &e) const {
+      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);}
+
+    Node addNode() {     
+      int n;
+      
+      if(first_free_node==-1) {
+	n = nodes.size();
+	nodes.push_back(NodeT());
+      } else {
+	n = first_free_node;
+	first_free_node = nodes[n].next;
+      }
+      
+      nodes[n].next = first_node;
+      if(first_node != -1) nodes[first_node].prev = n;
+      first_node = n;
+      nodes[n].prev = -1;
+      
+      nodes[n].first_in = nodes[n].first_out = -1;
+      
+      return Node(n);
+    }
+    
+    Arc addArc(Node u, Node v) {
+      int n;      
+
+      if (first_free_arc == -1) {
+	n = arcs.size();
+	arcs.push_back(ArcT());
+      } else {
+	n = first_free_arc;
+	first_free_arc = arcs[n].next_in;
+      }
+      
+      arcs[n].source = u.id; 
+      arcs[n].target = v.id;
+
+      arcs[n].next_out = nodes[u.id].first_out;
+      if(nodes[u.id].first_out != -1) {
+	arcs[nodes[u.id].first_out].prev_out = n;
+      }
+      
+      arcs[n].next_in = nodes[v.id].first_in;
+      if(nodes[v.id].first_in != -1) {
+	arcs[nodes[v.id].first_in].prev_in = n;
+      }
+      
+      arcs[n].prev_in = arcs[n].prev_out = -1;
+	
+      nodes[u.id].first_out = nodes[v.id].first_in = n;
+
+      return Arc(n);
+    }
+    
+    void erase(const Node& node) {
+      int n = node.id;
+      
+      if(nodes[n].next != -1) {
+	nodes[nodes[n].next].prev = nodes[n].prev;
+      }
+      
+      if(nodes[n].prev != -1) {
+	nodes[nodes[n].prev].next = nodes[n].next;
+      } else {
+	first_node = nodes[n].next;
+      }
+      
+      nodes[n].next = first_free_node;
+      first_free_node = n;
+
+    }
+    
+    void erase(const Arc& arc) {
+      int n = arc.id;
+      
+      if(arcs[n].next_in!=-1) {
+	arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
+      }
+
+      if(arcs[n].prev_in!=-1) {
+	arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
+      } else {
+	nodes[arcs[n].target].first_in = arcs[n].next_in;
+      }
+
+      
+      if(arcs[n].next_out!=-1) {
+	arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
+      } 
+
+      if(arcs[n].prev_out!=-1) {
+	arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
+      } else {
+	nodes[arcs[n].source].first_out = arcs[n].next_out;
+      }
+      
+      arcs[n].next_in = first_free_arc;
+      first_free_arc = n;      
+
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_node = first_free_node = first_free_arc = -1;
+    }
+
+  protected:
+    void changeTarget(Arc e, Node 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)
+	arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
+      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
+      if (nodes[n.id].first_in != -1) {
+	arcs[nodes[n.id].first_in].prev_in = e.id;
+      }
+      arcs[e.id].target = n.id;
+      arcs[e.id].prev_in = -1;
+      arcs[e.id].next_in = nodes[n.id].first_in;
+      nodes[n.id].first_in = e.id;
+    }
+    void changeSource(Arc e, Node 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)
+	arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
+      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
+      if (nodes[n.id].first_out != -1) {
+	arcs[nodes[n.id].first_out].prev_out = e.id;
+      }
+      arcs[e.id].source = n.id;
+      arcs[e.id].prev_out = -1;
+      arcs[e.id].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = e.id;
+    }
+
+  };
+
+  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
+
+  /// \addtogroup digraphs
+  /// @{
+
+  ///A list digraph class.
+
+  ///This is a simple and fast digraph implementation.
+  ///
+  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
+  ///also provides several additional useful extra functionalities.
+  ///The most of the member functions and nested classes are
+  ///documented only in the concept class.
+  ///
+  ///An important extra feature of this digraph implementation is that
+  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
+  ///
+  ///\sa concepts::Digraph.
+
+  class ListDigraph : public ExtendedListDigraphBase {
+  private:
+    ///ListDigraph is \e not copy constructible. Use DigraphCopy() instead.
+    
+    ///ListDigraph is \e not copy constructible. Use DigraphCopy() instead.
+    ///
+    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
+    ///\brief Assignment of ListDigraph to another one is \e not allowed.
+    ///Use DigraphCopy() instead.
+
+    ///Assignment of ListDigraph to another one is \e not allowed.
+    ///Use DigraphCopy() instead.
+    void operator=(const ListDigraph &) {}
+  public:
+
+    typedef ExtendedListDigraphBase Parent;
+
+    /// Constructor
+    
+    /// Constructor.
+    ///
+    ListDigraph() {}
+
+    ///Add a new node to the digraph.
+    
+    /// \return the new node.
+    ///
+    Node addNode() { return Parent::addNode(); }
+
+    ///Add a new arc to the digraph.
+    
+    ///Add a new arc to the digraph with source node \c s
+    ///and target node \c t.
+    ///\return the new arc.
+    Arc addArc(const Node& s, const Node& t) { 
+      return Parent::addArc(s, t); 
+    }
+
+    /// Changes the target of \c e to \c n
+
+    /// Changes the target of \c e to \c n
+    ///
+    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
+    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
+    ///invalidated.
+    ///\warning This functionality cannot be used together with the Snapshot
+    ///feature.
+    void changeTarget(Arc e, Node n) { 
+      Parent::changeTarget(e,n); 
+    }
+    /// Changes the source of \c e to \c n
+
+    /// Changes the source of \c e to \c n
+    ///
+    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
+    ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
+    ///invalidated.
+    ///\warning This functionality cannot be used together with the Snapshot
+    ///feature.
+    void changeSource(Arc e, Node n) { 
+      Parent::changeSource(e,n);
+    }
+
+    /// Invert the direction of an arc.
+
+    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
+    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
+    ///invalidated.
+    ///\warning This functionality cannot be used together with the Snapshot
+    ///feature.
+    void reverseArc(Arc e) {
+      Node t=target(e);
+      changeTarget(e,source(e));
+      changeSource(e,t);
+    }
+
+    /// Using this it is possible to avoid the superfluous memory
+    /// allocation: if you know that the digraph you want to build will
+    /// be very large (e.g. it will contain millions of nodes and/or arcs)
+    /// then it is worth reserving space for this amount before starting
+    /// to build the digraph.
+    /// \sa reserveArc
+    void reserveNode(int n) { nodes.reserve(n); };
+
+    /// \brief Using this it is possible to avoid the superfluous memory
+    /// allocation.
+
+    /// Using this it is possible to avoid the superfluous memory
+    /// allocation: if you know that the digraph you want to build will
+    /// be very large (e.g. it will contain millions of nodes and/or arcs)
+    /// then it is worth reserving space for this amount before starting
+    /// to build the digraph.
+    /// \sa reserveNode
+    void reserveArc(int m) { arcs.reserve(m); };
+
+    ///Contract two nodes.
+
+    ///This function contracts two nodes.
+    ///
+    ///Node \p b will be removed but instead of deleting
+    ///incident arcs, they will be joined to \p a.
+    ///The last parameter \p r controls whether to remove loops. \c true
+    ///means that loops will be removed.
+    ///
+    ///\note The <tt>ArcIt</tt>s
+    ///referencing a moved arc remain
+    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
+    ///may be invalidated.
+    ///\warning This functionality cannot be used together with the Snapshot
+    ///feature.
+    void contract(Node a, Node b, bool r = true) 
+    {
+      for(OutArcIt e(*this,b);e!=INVALID;) {
+	OutArcIt f=e;
+	++f;
+	if(r && target(e)==a) erase(e);
+	else changeSource(e,a);
+	e=f;
+      }
+      for(InArcIt e(*this,b);e!=INVALID;) {
+	InArcIt f=e;
+	++f;
+	if(r && source(e)==a) erase(e);
+	else changeTarget(e,a);
+	e=f;
+      }
+      erase(b);
+    }
+
+    ///Split a node.
+
+    ///This function splits a node. First a new node is added to the digraph,
+    ///then the source of each outgoing arc of \c n is moved to this new node.
+    ///If \c connect is \c true (this is the default value), then a new arc
+    ///from \c n to the newly created node is also added.
+    ///\return The newly created node.
+    ///
+    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
+    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
+    ///be invalidated.  
+    ///
+    ///\warning This functionality cannot be used together with the
+    ///Snapshot feature.  \todo It could be implemented in a bit
+    ///faster way.
+    Node split(Node n, bool connect = true) {
+      Node b = addNode();
+      for(OutArcIt e(*this,n);e!=INVALID;) {
+ 	OutArcIt f=e;
+	++f;
+	changeSource(e,b);
+	e=f;
+      }
+      if (connect) addArc(n,b);
+      return b;
+    }
+      
+    ///Split an arc.
+
+    ///This function splits an arc. First a new node \c b is added to
+    ///the digraph, then the original arc is re-targeted to \c
+    ///b. Finally an arc from \c b to the original target is added.
+    ///\return The newly created node.  
+    ///\warning This functionality
+    ///cannot be used together with the Snapshot feature.
+    Node split(Arc e) {
+      Node b = addNode();
+      addArc(b,target(e));
+      changeTarget(e,b);
+      return b;
+    }
+      
+    /// \brief Class to make a snapshot of the digraph and restore
+    /// to it later.
+    ///
+    /// Class to make a snapshot of the digraph and to restore it
+    /// later.
+    ///
+    /// The newly added nodes and arcs can be removed using the
+    /// restore() function.
+    ///
+    /// \warning Arc and node deletions cannot be restored. This
+    /// events invalidate the snapshot. 
+    class Snapshot {
+    protected:
+
+      typedef Parent::NodeNotifier NodeNotifier;
+
+      class NodeObserverProxy : public NodeNotifier::ObserverBase {
+      public:
+
+        NodeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using NodeNotifier::ObserverBase::attach;
+        using NodeNotifier::ObserverBase::detach;
+        using NodeNotifier::ObserverBase::attached;
+        
+      protected:
+        
+        virtual void add(const Node& node) {
+          snapshot.addNode(node);
+        }
+        virtual void add(const std::vector<Node>& nodes) {
+          for (int i = nodes.size() - 1; i >= 0; ++i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void erase(const Node& node) {
+          snapshot.eraseNode(node);
+        }
+        virtual void erase(const std::vector<Node>& nodes) {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            snapshot.eraseNode(nodes[i]);
+          }
+        }
+        virtual void build() {
+          Node node;
+          std::vector<Node> nodes;
+          for (notifier()->first(node); node != INVALID; 
+               notifier()->next(node)) {
+            nodes.push_back(node);
+          }
+          for (int i = nodes.size() - 1; i >= 0; --i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void clear() {
+          Node node;
+          for (notifier()->first(node); node != INVALID; 
+               notifier()->next(node)) {
+            snapshot.eraseNode(node);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      class ArcObserverProxy : public ArcNotifier::ObserverBase {
+      public:
+
+        ArcObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using ArcNotifier::ObserverBase::attach;
+        using ArcNotifier::ObserverBase::detach;
+        using ArcNotifier::ObserverBase::attached;
+        
+      protected:
+
+        virtual void add(const Arc& arc) {
+          snapshot.addArc(arc);
+        }
+        virtual void add(const std::vector<Arc>& arcs) {
+          for (int i = arcs.size() - 1; i >= 0; ++i) {
+            snapshot.addArc(arcs[i]);
+          }
+        }
+        virtual void erase(const Arc& arc) {
+          snapshot.eraseArc(arc);
+        }
+        virtual void erase(const std::vector<Arc>& arcs) {
+          for (int i = 0; i < int(arcs.size()); ++i) {
+            snapshot.eraseArc(arcs[i]);
+          }
+        }
+        virtual void build() {
+          Arc arc;
+          std::vector<Arc> arcs;
+          for (notifier()->first(arc); arc != INVALID; 
+               notifier()->next(arc)) {
+            arcs.push_back(arc);
+          }
+          for (int i = arcs.size() - 1; i >= 0; --i) {
+            snapshot.addArc(arcs[i]);
+          }
+        }
+        virtual void clear() {
+          Arc arc;
+          for (notifier()->first(arc); arc != INVALID; 
+               notifier()->next(arc)) {
+            snapshot.eraseArc(arc);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+      
+      ListDigraph *digraph;
+
+      NodeObserverProxy node_observer_proxy;
+      ArcObserverProxy arc_observer_proxy;
+
+      std::list<Node> added_nodes;
+      std::list<Arc> added_arcs;
+
+
+      void addNode(const Node& node) {
+        added_nodes.push_front(node);        
+      }
+      void eraseNode(const Node& node) {
+        std::list<Node>::iterator it = 
+          std::find(added_nodes.begin(), added_nodes.end(), node);
+        if (it == added_nodes.end()) {
+          clear();
+          arc_observer_proxy.detach();
+          throw NodeNotifier::ImmediateDetach();
+        } else {
+          added_nodes.erase(it);
+        }
+      }
+
+      void addArc(const Arc& arc) {
+        added_arcs.push_front(arc);        
+      }
+      void eraseArc(const Arc& arc) {
+        std::list<Arc>::iterator it = 
+          std::find(added_arcs.begin(), added_arcs.end(), arc);
+        if (it == added_arcs.end()) {
+          clear();
+          node_observer_proxy.detach(); 
+          throw ArcNotifier::ImmediateDetach();
+        } else {
+          added_arcs.erase(it);
+        }        
+      }
+
+      void attach(ListDigraph &_digraph) {
+	digraph = &_digraph;
+	node_observer_proxy.attach(digraph->notifier(Node()));
+        arc_observer_proxy.attach(digraph->notifier(Arc()));
+      }
+            
+      void detach() {
+	node_observer_proxy.detach();
+	arc_observer_proxy.detach();
+      }
+
+      bool attached() const {
+        return node_observer_proxy.attached();
+      }
+
+      void clear() {
+        added_nodes.clear();
+        added_arcs.clear();        
+      }
+
+    public:
+
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// To actually make a snapshot you must call save().
+      Snapshot() 
+        : digraph(0), node_observer_proxy(*this), 
+          arc_observer_proxy(*this) {}
+      
+      /// \brief Constructor that immediately makes a snapshot.
+      ///      
+      /// This constructor immediately makes a snapshot of the digraph.
+      /// \param _digraph The digraph we make a snapshot of.
+      Snapshot(ListDigraph &_digraph) 
+        : node_observer_proxy(*this), 
+          arc_observer_proxy(*this) {
+	attach(_digraph);
+      }
+      
+      /// \brief Make a snapshot.
+      ///
+      /// Make a snapshot of the digraph.
+      ///
+      /// This function can be called more than once. In case of a repeated
+      /// call, the previous snapshot gets lost.
+      /// \param _digraph The digraph we make the snapshot of.
+      void save(ListDigraph &_digraph) {
+        if (attached()) {
+          detach();
+          clear();
+        }
+        attach(_digraph);
+      }
+      
+      /// \brief Undo the changes until the last snapshot.
+      // 
+      /// Undo the changes until the last snapshot created by save().
+      void restore() {
+	detach();
+	for(std::list<Arc>::iterator it = added_arcs.begin(); 
+            it != added_arcs.end(); ++it) {
+	  digraph->erase(*it);
+	}
+	for(std::list<Node>::iterator it = added_nodes.begin(); 
+            it != added_nodes.end(); ++it) {
+	  digraph->erase(*it);
+	}
+        clear();
+      }
+
+      /// \brief Gives back true when the snapshot is valid.
+      ///
+      /// Gives back true when the snapshot is valid.
+      bool valid() const {
+        return attached();
+      }
+    };
+    
+  };
+
+  ///@}
+
+  class ListGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      int prev, next;
+    };
+ 
+    struct ArcT {
+      int target;
+      int prev_out, next_out;
+    };
+
+    std::vector<NodeT> nodes;
+
+    int first_node;
+
+    int first_free_node;
+
+    std::vector<ArcT> arcs;
+
+    int first_free_arc;
+    
+  public:
+    
+    typedef ListGraphBase Digraph;
+
+    class Node;
+    class Arc;
+    class Edge;
+    
+    class Node {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Node(int pid) { id = pid;}
+
+    public:
+      Node() {}
+      Node (Invalid) { id = -1; }
+      bool operator==(const Node& node) const {return id == node.id;}
+      bool operator!=(const Node& node) const {return id != node.id;}
+      bool operator<(const Node& node) const {return id < node.id;}
+    };
+
+    class Edge {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Edge(int pid) { id = pid;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { id = -1; }
+      bool operator==(const Edge& arc) const {return id == arc.id;}
+      bool operator!=(const Edge& arc) const {return id != arc.id;}
+      bool operator<(const Edge& arc) const {return id < arc.id;}
+    };
+
+    class Arc {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Arc(int pid) { id = pid;}
+
+    public:
+      operator Edge() const { return edgeFromId(id / 2); }
+
+      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;}
+    };
+
+
+
+    ListGraphBase()
+      : nodes(), first_node(-1),
+	first_free_node(-1), arcs(), first_free_arc(-1) {}
+
+    
+    int maxNodeId() const { return nodes.size()-1; } 
+    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) {
+      return (e.id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e.id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const { 
+      node.id = first_node;
+    }
+
+    void next(Node& node) const {
+      node.id = nodes[node.id].next;
+    }
+
+    void first(Arc& e) const { 
+      int n = first_node;
+      while (n != -1 && nodes[n].first_out == -1) {
+        n = nodes[n].next;
+      }
+      e.id = (n == -1) ? -1 : nodes[n].first_out;
+    }
+
+    void next(Arc& e) const {
+      if (arcs[e.id].next_out != -1) {
+	e.id = arcs[e.id].next_out;
+      } else {
+	int n = nodes[arcs[e.id ^ 1].target].next;
+        while(n != -1 && nodes[n].first_out == -1) {
+          n = nodes[n].next;
+        }
+	e.id = (n == -1) ? -1 : nodes[n].first_out;
+      }      
+    }
+
+    void first(Edge& e) const { 
+      int n = first_node;
+      while (n != -1) {
+        e.id = nodes[n].first_out;
+        while ((e.id & 1) != 1) {
+          e.id = arcs[e.id].next_out;
+        }
+        if (e.id != -1) {
+          e.id /= 2;
+          return;
+        } 
+        n = nodes[n].next;
+      }
+      e.id = -1;
+    }
+
+    void next(Edge& e) const {
+      int n = arcs[e.id * 2].target;
+      e.id = arcs[(e.id * 2) | 1].next_out;
+      while ((e.id & 1) != 1) {
+        e.id = arcs[e.id].next_out;
+      }
+      if (e.id != -1) {
+        e.id /= 2;
+        return;
+      } 
+      n = nodes[n].next;
+      while (n != -1) {
+        e.id = nodes[n].first_out;
+        while ((e.id & 1) != 1) {
+          e.id = arcs[e.id].next_out;
+        }
+        if (e.id != -1) {
+          e.id /= 2;
+          return;
+        } 
+        n = nodes[n].next;
+      }
+      e.id = -1;
+    }
+
+    void firstOut(Arc &e, const Node& v) const {
+      e.id = nodes[v.id].first_out;
+    }
+    void nextOut(Arc &e) const {
+      e.id = arcs[e.id].next_out;
+    }
+
+    void firstIn(Arc &e, const Node& v) const {
+      e.id = ((nodes[v.id].first_out) ^ 1);
+      if (e.id == -2) e.id = -1;
+    }
+    void nextIn(Arc &e) const {
+      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
+      if (e.id == -2) e.id = -1;
+    }
+
+    void firstInc(Edge &e, bool& d, const Node& v) const {
+      int de = nodes[v.id].first_out;
+      if (de != -1 ) {
+        e.id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        e.id = -1;
+        d = true;
+      }
+    }
+    void nextInc(Edge &e, bool& d) const {
+      int de = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
+      if (de != -1 ) {
+        e.id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        e.id = -1;
+        d = true;
+      }
+    }
+    
+    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);}
+
+    Node addNode() {     
+      int n;
+      
+      if(first_free_node==-1) {
+	n = nodes.size();
+	nodes.push_back(NodeT());
+      } else {
+	n = first_free_node;
+	first_free_node = nodes[n].next;
+      }
+      
+      nodes[n].next = first_node;
+      if (first_node != -1) nodes[first_node].prev = n;
+      first_node = n;
+      nodes[n].prev = -1;
+      
+      nodes[n].first_out = -1;
+      
+      return Node(n);
+    }
+    
+    Edge addEdge(Node u, Node v) {
+      int n;      
+
+      if (first_free_arc == -1) {
+	n = arcs.size();
+	arcs.push_back(ArcT());
+	arcs.push_back(ArcT());
+      } else {
+	n = first_free_arc;
+	first_free_arc = arcs[n].next_out;
+      }
+      
+      arcs[n].target = u.id;
+      arcs[n | 1].target = v.id;
+
+      arcs[n].next_out = nodes[v.id].first_out;
+      if (nodes[v.id].first_out != -1) {
+	arcs[nodes[v.id].first_out].prev_out = n;
+      }      
+      arcs[n].prev_out = -1;
+      nodes[v.id].first_out = n;
+      
+      arcs[n | 1].next_out = nodes[u.id].first_out;
+      if (nodes[u.id].first_out != -1) {
+	arcs[nodes[u.id].first_out].prev_out = (n | 1);
+      }
+      arcs[n | 1].prev_out = -1;      
+      nodes[u.id].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+    
+    void erase(const Node& node) {
+      int n = node.id;
+      
+      if(nodes[n].next != -1) {
+	nodes[nodes[n].next].prev = nodes[n].prev;
+      }
+      
+      if(nodes[n].prev != -1) {
+	nodes[nodes[n].prev].next = nodes[n].next;
+      } else {
+	first_node = nodes[n].next;
+      }
+      
+      nodes[n].next = first_free_node;
+      first_free_node = n;
+
+    }
+    
+    void erase(const Edge& arc) {
+      int n = arc.id * 2;
+      
+      if (arcs[n].next_out != -1) {
+	arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
+      } 
+
+      if (arcs[n].prev_out != -1) {
+	arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
+      } else {
+	nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
+      }
+
+      if (arcs[n | 1].next_out != -1) {
+	arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
+      } 
+
+      if (arcs[n | 1].prev_out != -1) {
+	arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
+      } else {
+	nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
+      }
+      
+      arcs[n].next_out = first_free_arc;
+      first_free_arc = n;      
+
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_node = first_free_node = first_free_arc = -1;
+    }
+
+  protected:
+
+    void changeTarget(Edge e, Node n) {
+      if(arcs[2 * e.id].next_out != -1) {
+	arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
+      }
+      if(arcs[2 * e.id].prev_out != -1) {
+	arcs[arcs[2 * e.id].prev_out].next_out = 
+          arcs[2 * e.id].next_out;
+      } else {
+        nodes[arcs[(2 * e.id) | 1].target].first_out = 
+          arcs[2 * e.id].next_out;
+      }
+
+      if (nodes[n.id].first_out != -1) {
+	arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
+      }
+      arcs[(2 * e.id) | 1].target = n.id;
+      arcs[2 * e.id].prev_out = -1;
+      arcs[2 * e.id].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = 2 * e.id;
+    }
+
+    void changeSource(Edge e, Node n) {
+      if(arcs[(2 * e.id) | 1].next_out != -1) {
+	arcs[arcs[(2 * e.id) | 1].next_out].prev_out = 
+          arcs[(2 * e.id) | 1].prev_out;
+      }
+      if(arcs[(2 * e.id) | 1].prev_out != -1) {
+	arcs[arcs[(2 * e.id) | 1].prev_out].next_out = 
+          arcs[(2 * e.id) | 1].next_out;
+      } else {
+        nodes[arcs[2 * e.id].target].first_out = 
+          arcs[(2 * e.id) | 1].next_out;
+      }
+
+      if (nodes[n.id].first_out != -1) {
+	arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
+      }
+      arcs[2 * e.id].target = n.id;
+      arcs[(2 * e.id) | 1].prev_out = -1;
+      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
+      nodes[n.id].first_out = ((2 * e.id) | 1);
+    }
+
+  };
+
+//   typedef GraphExtender<UndirDigraphExtender<ListDigraphBase> > 
+//   ExtendedListGraphBase;
+
+  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
+
+
+
+  /// \addtogroup digraphs
+  /// @{
+
+  ///An undirected list digraph class.
+
+  ///This is a simple and fast undirected digraph implementation.
+  ///
+  ///An important extra feature of this digraph implementation is that
+  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
+  ///
+  ///It conforms to the
+  ///\ref concepts::Graph "Graph concept".
+  ///
+  ///\sa concepts::Graph.
+  ///
+  class ListGraph : public ExtendedListGraphBase {
+  private:
+    ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
+
+    ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
+    ///
+    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
+    ///\brief Assignment of ListGraph to another one is \e not allowed.
+    ///Use GraphCopy() instead.
+
+    ///Assignment of ListGraph to another one is \e not allowed.
+    ///Use GraphCopy() instead.
+    void operator=(const ListGraph &) {}
+  public:
+    /// Constructor
+    
+    /// Constructor.
+    ///
+    ListGraph() {}
+
+    typedef ExtendedListGraphBase Parent;
+
+    typedef Parent::OutArcIt IncArcIt;
+
+    /// \brief Add a new node to the digraph.
+    ///
+    /// \return the new node.
+    ///
+    Node addNode() { return Parent::addNode(); }
+
+    /// \brief Add a new edge to the digraph.
+    ///
+    /// Add a new arc to the digraph with source node \c s
+    /// and target node \c t.
+    /// \return the new edge.
+    Edge addEdge(const Node& s, const Node& t) { 
+      return Parent::addEdge(s, t); 
+    }
+    /// \brief Changes the source of \c e to \c n
+    ///
+    /// Changes the source of \c e to \c n
+    ///
+    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
+    ///referencing the changed arc remain
+    ///valid. However <tt>OutArcIt</tt>s are invalidated.
+    void changeSource(Edge e, Node n) { 
+      Parent::changeSource(e,n); 
+    }    
+    /// \brief Changes the target of \c e to \c n
+    ///
+    /// Changes the target of \c e to \c n
+    ///
+    /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
+    /// valid. However the other iterators may be invalidated.
+    void changeTarget(Edge e, Node n) { 
+      Parent::changeTarget(e,n); 
+    }
+    /// \brief Changes the source of \c e to \c n
+    ///
+    /// Changes the source of \c e to \c n. It changes the proper
+    /// node of the represented edge.
+    ///
+    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
+    ///referencing the changed arc remain
+    ///valid. However <tt>OutArcIt</tt>s are invalidated.
+    void changeSource(Arc e, Node n) { 
+      if (Parent::direction(e)) {
+        Parent::changeSource(e,n);
+      } else {
+        Parent::changeTarget(e,n);
+      } 
+    }
+    /// \brief Changes the target of \c e to \c n
+    ///
+    /// Changes the target of \c e to \c n. It changes the proper
+    /// node of the represented edge.
+    ///
+    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s
+    ///referencing the changed arc remain
+    ///valid. However <tt>InArcIt</tt>s are invalidated.
+    void changeTarget(Arc e, Node n) { 
+      if (Parent::direction(e)) {
+        Parent::changeTarget(e,n);
+      } else {
+        Parent::changeSource(e,n);
+      } 
+    }
+    /// \brief Contract two nodes.
+    ///
+    /// This function contracts two nodes.
+    ///
+    /// Node \p b will be removed but instead of deleting
+    /// its neighboring arcs, they will be joined to \p a.
+    /// The last parameter \p r controls whether to remove loops. \c true
+    /// means that loops will be removed.
+    ///
+    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
+    /// valid.
+    void contract(Node a, Node b, bool r = true) {
+      for(IncArcIt e(*this, b); e!=INVALID;) {
+	IncArcIt f = e; ++f;
+	if (r && runningNode(e) == a) {
+	  erase(e);
+	} else if (source(e) == b) {
+	  changeSource(e, a);
+	} else {
+	  changeTarget(e, a);
+	}
+	e = f;
+      }
+      erase(b);
+    }
+
+
+    /// \brief Class to make a snapshot of the digraph and restore
+    /// to it later.
+    ///
+    /// Class to make a snapshot of the digraph and to restore it
+    /// later.
+    ///
+    /// The newly added nodes and edges can be removed
+    /// using the restore() function.
+    ///
+    /// \warning Arc and node deletions cannot be restored. This
+    /// events invalidate the snapshot. 
+    class Snapshot {
+    protected:
+
+      typedef Parent::NodeNotifier NodeNotifier;
+
+      class NodeObserverProxy : public NodeNotifier::ObserverBase {
+      public:
+
+        NodeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using NodeNotifier::ObserverBase::attach;
+        using NodeNotifier::ObserverBase::detach;
+        using NodeNotifier::ObserverBase::attached;
+        
+      protected:
+        
+        virtual void add(const Node& node) {
+          snapshot.addNode(node);
+        }
+        virtual void add(const std::vector<Node>& nodes) {
+          for (int i = nodes.size() - 1; i >= 0; ++i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void erase(const Node& node) {
+          snapshot.eraseNode(node);
+        }
+        virtual void erase(const std::vector<Node>& nodes) {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            snapshot.eraseNode(nodes[i]);
+          }
+        }
+        virtual void build() {
+          Node node;
+          std::vector<Node> nodes;
+          for (notifier()->first(node); node != INVALID; 
+               notifier()->next(node)) {
+            nodes.push_back(node);
+          }
+          for (int i = nodes.size() - 1; i >= 0; --i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void clear() {
+          Node node;
+          for (notifier()->first(node); node != INVALID; 
+               notifier()->next(node)) {
+            snapshot.eraseNode(node);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
+      public:
+
+        EdgeObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using EdgeNotifier::ObserverBase::attach;
+        using EdgeNotifier::ObserverBase::detach;
+        using EdgeNotifier::ObserverBase::attached;
+        
+      protected:
+
+        virtual void add(const Edge& arc) {
+          snapshot.addEdge(arc);
+        }
+        virtual void add(const std::vector<Edge>& arcs) {
+          for (int i = arcs.size() - 1; i >= 0; ++i) {
+            snapshot.addEdge(arcs[i]);
+          }
+        }
+        virtual void erase(const Edge& arc) {
+          snapshot.eraseEdge(arc);
+        }
+        virtual void erase(const std::vector<Edge>& arcs) {
+          for (int i = 0; i < int(arcs.size()); ++i) {
+            snapshot.eraseEdge(arcs[i]);
+          }
+        }
+        virtual void build() {
+          Edge arc;
+          std::vector<Edge> arcs;
+          for (notifier()->first(arc); arc != INVALID; 
+               notifier()->next(arc)) {
+            arcs.push_back(arc);
+          }
+          for (int i = arcs.size() - 1; i >= 0; --i) {
+            snapshot.addEdge(arcs[i]);
+          }
+        }
+        virtual void clear() {
+          Edge arc;
+          for (notifier()->first(arc); arc != INVALID; 
+               notifier()->next(arc)) {
+            snapshot.eraseEdge(arc);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+      
+      ListGraph *digraph;
+
+      NodeObserverProxy node_observer_proxy;
+      EdgeObserverProxy arc_observer_proxy;
+
+      std::list<Node> added_nodes;
+      std::list<Edge> added_arcs;
+
+
+      void addNode(const Node& node) {
+        added_nodes.push_front(node);        
+      }
+      void eraseNode(const Node& node) {
+        std::list<Node>::iterator it = 
+          std::find(added_nodes.begin(), added_nodes.end(), node);
+        if (it == added_nodes.end()) {
+          clear();
+          arc_observer_proxy.detach();
+          throw NodeNotifier::ImmediateDetach();
+        } else {
+          added_nodes.erase(it);
+        }
+      }
+
+      void addEdge(const Edge& arc) {
+        added_arcs.push_front(arc);        
+      }
+      void eraseEdge(const Edge& arc) {
+        std::list<Edge>::iterator it = 
+          std::find(added_arcs.begin(), added_arcs.end(), arc);
+        if (it == added_arcs.end()) {
+          clear();
+          node_observer_proxy.detach();
+          throw EdgeNotifier::ImmediateDetach();
+        } else {
+          added_arcs.erase(it);
+        }        
+      }
+
+      void attach(ListGraph &_digraph) {
+	digraph = &_digraph;
+	node_observer_proxy.attach(digraph->notifier(Node()));
+        arc_observer_proxy.attach(digraph->notifier(Edge()));
+      }
+            
+      void detach() {
+	node_observer_proxy.detach();
+	arc_observer_proxy.detach();
+      }
+
+      bool attached() const {
+        return node_observer_proxy.attached();
+      }
+
+      void clear() {
+        added_nodes.clear();
+        added_arcs.clear();        
+      }
+
+    public:
+
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// To actually make a snapshot you must call save().
+      Snapshot() 
+        : digraph(0), node_observer_proxy(*this), 
+          arc_observer_proxy(*this) {}
+      
+      /// \brief Constructor that immediately makes a snapshot.
+      ///      
+      /// This constructor immediately makes a snapshot of the digraph.
+      /// \param _digraph The digraph we make a snapshot of.
+      Snapshot(ListGraph &_digraph) 
+        : node_observer_proxy(*this), 
+          arc_observer_proxy(*this) {
+	attach(_digraph);
+      }
+      
+      /// \brief Make a snapshot.
+      ///
+      /// Make a snapshot of the digraph.
+      ///
+      /// This function can be called more than once. In case of a repeated
+      /// call, the previous snapshot gets lost.
+      /// \param _digraph The digraph we make the snapshot of.
+      void save(ListGraph &_digraph) {
+        if (attached()) {
+          detach();
+          clear();
+        }
+        attach(_digraph);
+      }
+      
+      /// \brief Undo the changes until the last snapshot.
+      // 
+      /// Undo the changes until the last snapshot created by save().
+      void restore() {
+	detach();
+	for(std::list<Edge>::iterator it = added_arcs.begin(); 
+            it != added_arcs.end(); ++it) {
+	  digraph->erase(*it);
+	}
+	for(std::list<Node>::iterator it = added_nodes.begin(); 
+            it != added_nodes.end(); ++it) {
+	  digraph->erase(*it);
+	}
+        clear();
+      }
+
+      /// \brief Gives back true when the snapshot is valid.
+      ///
+      /// Gives back true when the snapshot is valid.
+      bool valid() const {
+        return attached();
+      }
+    };
+  };
+  
+  /// @}  
+} //namespace lemon
+  
+
+#endif
