Index: pyatspi/accessible.py
===================================================================
--- pyatspi/accessible.py	(revision 942)
+++ pyatspi/accessible.py	(working copy)
@@ -49,6 +49,9 @@
 _ACCESSIBLE_CACHE = {}
 _CACHE_LEVEL = None
 
+_USER_DATA = {}
+_USER_DATA_UPDATE_REGISTERED = False
+
 class _PropertyCache(object):
   '''Fixed-size bag class for holding cached values.'''
   __slots__ = ('name', 'description', 'rolename')
@@ -115,6 +118,17 @@
   except KeyError:
     return
 
+def _updateUserData(event):
+  '''
+  Removes a dictionary entry when it's consuming accessible dies.
+
+  @param event: An "object:state-changed:defunct" event.
+  @type event: L{event.Event}
+  '''
+  h = hash(event.source)
+  if _USER_DATA.has_key(h):
+    del _USER_DATA[h]
+    
 def _makeQuery(iid):
   '''
   Builds a function querying to a specific interface and returns it.
@@ -324,7 +338,7 @@
   @type SLOTS: tuple
   '''
   SLOTTED_CLASSES = {}
-  SLOTS = ('_icache', 'user_data')
+  SLOTS = ('_icache',)
   
   def __new__(cls):
     '''
@@ -434,6 +448,30 @@
     '''
     return self.childCount
   
+  def _get_user_data(self):
+    '''
+    Gets the user_data from global dict if available.
+    '''
+    h = hash(self)
+    try:
+      return _USER_DATA[h]
+    except KeyError:
+      return None
+
+  def _set_user_data(self, value):
+    '''
+    Sets user data to global dict.
+    '''
+    global _USER_DATA_UPDATE_REGISTERED
+    if not _USER_DATA_UPDATE_REGISTERED:
+      r = registry.Registry()
+      r.registerEventListener(_updateUserData, 'object:state-changed:defunct')
+      _USER_DATA_UPDATE_REGISTERED = True
+    h = hash(self)
+    _USER_DATA[h] = value
+    
+  user_data = property(_get_user_data, _set_user_data)
+
   def _get_name(self):
     '''
     Gets the name of the accessible from the cache if it is available, 
