void OnClassInformationChanged (object sender, TypeUpdateInformationEventArgs e)
		{
//			DateTime t = DateTime.Now;
			Dictionary<object,bool> oldStatus = new Dictionary<object,bool> ();
			List<string> namespacesToClean = new List<string> ();
			ITreeBuilder tb = Context.GetTreeBuilder ();
						
			foreach (IType cls in e.TypeUpdateInformation.Removed) {
				if (tb.MoveToObject (new ClassData (e.Project, cls))) {
					oldStatus [tb.DataItem] = tb.Expanded;
					
					ITreeNavigator np = tb.Clone ();
					np.MoveToParent ();
					oldStatus [np.DataItem] = np.Expanded;
					
					tb.Remove (true);
				}
				namespacesToClean.Add (cls.Namespace);
			}
			
			foreach (IType cls in e.TypeUpdateInformation.Modified) {
				ClassData ucd = new ClassData (e.Project, cls);
				if (tb.MoveToObject (ucd)) {
					ClassData cd = (ClassData) tb.DataItem;
					cd.UpdateFrom (ucd);
					tb.UpdateAll ();
				}
			}
			
			foreach (IType cls in e.TypeUpdateInformation.Added) {
				AddClass (e.Project, cls);
			}
			
			// Clean empty namespaces
			
			foreach (string ns in namespacesToClean) {
				string subns = ns;
				while (subns != null) {
					bool found = tb.MoveToObject (new ProjectNamespaceData (e.Project, subns));
					if (!found) found = tb.MoveToObject (new ProjectNamespaceData (null, subns));
					if (found) {
						while (tb.DataItem is NamespaceData && !tb.HasChildren())
							tb.Remove (true);
						break;
					}
					int i = subns.LastIndexOf ('.');
					if (i != -1) subns = subns.Substring (0,i);
					else subns = null;
				}
			}
			
			// Restore expand status
			
			foreach (KeyValuePair<object,bool> de in oldStatus) {
				if (de.Value && tb.MoveToObject (de.Key)) {
					tb.ExpandToNode ();
					tb.Expanded = true;
				}
			}
		}
 void OnTypesUpdated(object sender, TypeUpdateInformationEventArgs e)
 {
     Gtk.Application.Invoke (delegate { Diagram.UpdateRange (e.TypeUpdateInformation.Modified); });
     Gtk.Application.Invoke (delegate { Diagram.RemoveRange (e.TypeUpdateInformation.Removed); });
 }