Index: lemon/bits/alteration_notifier.h
===================================================================
--- lemon/bits/alteration_notifier.h	(revision 1701)
+++ lemon/bits/alteration_notifier.h	(revision 1718)
@@ -140,7 +140,7 @@
 
       /// \brief The member function to notificate the observer about 
-      /// simulitem is added to the container.
-      ///
-      /// The add() member function notificates the observer about an item
+      /// more item is added to the container.
+      ///
+      /// The add() member function notificates the observer about more item
       /// is added to the container. It have to be overrided in the
       /// subclasses.
@@ -161,4 +161,10 @@
       virtual void erase(const Item&) = 0;
 
+      /// \brief The member function to notificate the observer about 
+      /// more item is erased from the container.
+      ///
+      /// The erase() member function notificates the observer about more item
+      /// is erased from the container. It have to be overrided in the
+      /// subclasses.
       virtual void erase(const std::vector<Item>& items) {
 	for (int i = 0; i < (int)items.size(); ++i) {
@@ -166,4 +172,20 @@
 	}
       }
+
+      /// \brief Signal a property change on the given item.
+      ///
+      /// Signal a property change on the given item. It should
+      /// be used always with the commitChange() function.
+      /// This function is called always the property change.
+      /// The commitChange() is called always after the change.
+      virtual void signalChange(const Item&) {}
+
+      /// \brief Commit the property change on the given item.
+      ///
+      /// Commit the property change on the given item. It should
+      /// be used always with the signalChange() function.
+      /// This function is called always the property change.
+      /// The commitChange() is called always after the change.
+      virtual void commitChange(const Item&) {}
 
       /// \brief The member function to notificate the observer about the
@@ -304,4 +326,29 @@
     }
     
+    /// \brief Signal a property change on the given item.
+    ///
+    /// Signal a property change on the given item. It should
+    /// be used always with the commitChange() function.
+    /// This function is called always the property change.
+    /// The commitChange() is called always after the change.
+    void signalChange(const Item& item) {
+      typename Container::iterator it;
+      for (it = container.begin(); it != container.end(); ++it) {
+	(*it)->signalChange(item);
+      }
+    }
+    
+    /// \brief Commit the property change on the given item.
+    ///
+    /// Commit the property change on the given item. It should
+    /// be used always with the signalChange() function.
+    /// This function is called always the property change.
+    /// The commitChange() is called always after the change.
+    void commitChange(const Item& item) {
+      typename Container::iterator it;
+      for (it = container.begin(); it != container.end(); ++it) {
+	(*it)->commitChange(item);
+      }
+    }
 
     /// \brief Notifies all the registered observers about the container is 
Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 1702)
+++ lemon/list_graph.h	(revision 1718)
@@ -309,9 +309,4 @@
   };
 
-  typedef AlterableGraphExtender<ListGraphBase> AlterableListGraphBase;
-  typedef IterableGraphExtender<AlterableListGraphBase> IterableListGraphBase;
-  typedef MappableGraphExtender<IterableListGraphBase> MappableListGraphBase;
-  typedef ExtendableGraphExtender<MappableListGraphBase> ExtendableListGraphBase;
-  typedef ClearableGraphExtender<ExtendableListGraphBase> ClearableListGraphBase;
   typedef ErasableGraphExtender<
     ClearableGraphExtender<
@@ -321,6 +316,6 @@
     AlterableGraphExtender<ListGraphBase> > > > > > ExtendedListGraphBase;
 
-/// \addtogroup graphs
-/// @{
+  /// \addtogroup graphs
+  /// @{
 
   ///A list graph class.
@@ -343,5 +338,9 @@
     ///referencing the changed edge remain
     ///valid. However <tt>InEdge</tt>'s are invalidated.
-    void changeTarget(Edge e, Node n) { _changeTarget(e,n); }
+    void changeTarget(Edge e, Node n) { 
+      getNotifier(Edge()).signalChange(e); 
+      _changeTarget(e,n); 
+      getNotifier(Edge()).commitChange(e); 
+    }
     /// Changes the source of \c e to \c n
 
@@ -351,5 +350,9 @@
     ///referencing the changed edge remain
     ///valid. However <tt>OutEdge</tt>'s are invalidated.
-    void changeSource(Edge e, Node n) { _changeSource(e,n); }
+    void changeSource(Edge e, Node n) { 
+      getNotifier(Edge()).signalChange(e); 
+      _changeSource(e,n);
+      getNotifier(Edge()).commitChange(e); 
+    }
 
     /// Invert the direction of an edge.
@@ -360,6 +363,8 @@
     void reverseEdge(Edge e) {
       Node t=target(e);
+      getNotifier(Edge()).signalChange(e); 
       _changeTarget(e,source(e));
       _changeSource(e,t);
+      getNotifier(Edge()).commitChange(e); 
     }
 
@@ -383,5 +388,5 @@
     ///valid. However <tt>InEdge</tt>'s and <tt>OutEdge</tt>'s
     ///may be invalidated.
-    void contract(Node a,Node b,bool r=true) 
+    void contract(Node a, Node b, bool r = true) 
     {
       for(OutEdgeIt e(*this,b);e!=INVALID;) {
@@ -563,6 +568,6 @@
     UndirGraphExtender<ListGraphBase> > > > > > > ExtendedUndirListGraphBase;
 
-/// \addtogroup graphs
-/// @{
+  /// \addtogroup graphs
+  /// @{
 
   ///An undirected list graph class.
@@ -579,4 +584,64 @@
   ///
   class UndirListGraph : public ExtendedUndirListGraphBase {
+  public:
+    typedef ExtendedUndirListGraphBase Parent;
+    /// \brief Changes the target of \c e to \c n
+    ///
+    /// Changes the target of \c e to \c n
+    ///
+    /// \note The <tt>Edge</tt>'s and <tt>OutEdge</tt>'s
+    /// referencing the changed edge remain
+    /// valid. However <tt>InEdge</tt>'s are invalidated.
+    void changeTarget(UndirEdge e, Node n) { 
+      getNotifier(UndirEdge()).signalChange(e); 
+      getNotifier(Edge()).signalChange(direct(e, true)); 
+      getNotifier(Edge()).signalChange(direct(e, false)); 
+      _changeTarget(e,n); 
+      getNotifier(UndirEdge()).commitChange(e);
+      getNotifier(Edge()).commitChange(direct(e, true)); 
+      getNotifier(Edge()).commitChange(direct(e, false)); 
+    }
+    /// Changes the source of \c e to \c n
+    ///
+    /// Changes the source of \c e to \c n
+    ///
+    ///\note The <tt>Edge</tt>'s and <tt>InEdge</tt>'s
+    ///referencing the changed edge remain
+    ///valid. However <tt>OutEdge</tt>'s are invalidated.
+    void changeSource(UndirEdge e, Node n) { 
+      getNotifier(UndirEdge()).signalChange(e); 
+      getNotifier(Edge()).signalChange(direct(e, true)); 
+      getNotifier(Edge()).signalChange(direct(e, false)); 
+      _changeSource(e,n); 
+      getNotifier(UndirEdge()).commitChange(e);
+      getNotifier(Edge()).commitChange(direct(e, true)); 
+      getNotifier(Edge()).commitChange(direct(e, false)); 
+    }
+    /// \brief Contract two nodes.
+    ///
+    /// This function contracts two nodes.
+    ///
+    /// Node \p b will be removed but instead of deleting
+    /// its neighboring edges, 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>Edge</tt>s
+    /// referencing a moved edge remain
+    /// valid.
+    void contract(Node a, Node b, bool r = true) {
+      for(IncEdgeIt e(*this, b); e!=INVALID;) {
+	IncEdgeIt 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);
+    }
   };
 
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 1692)
+++ lemon/smart_graph.h	(revision 1718)
@@ -76,5 +76,6 @@
 
     SmartGraphBase() : nodes(), edges() { }
-    SmartGraphBase(const SmartGraphBase &_g) : nodes(_g.nodes), edges(_g.edges) { }
+    SmartGraphBase(const SmartGraphBase &_g) 
+      : nodes(_g.nodes), edges(_g.edges) { }
     
     typedef True NodeNumTag;
@@ -315,5 +316,12 @@
     Node split(Node n, bool connect = true) 
     {
-      return _split(n,connect);
+      for (OutEdgeIt it(*this, n); it != INVALID; ++it) {
+	getNotifier(Edge()).signalChange(it);
+      }
+      Node b = _split(n,connect);
+      for (OutEdgeIt it(*this, b); it != INVALID; ++it) {
+	getNotifier(Edge()).commitChange(it);
+      }
+      return b;
     }
   
