diff --git a/product/ERP5Type/Base.py b/product/ERP5Type/Base.py
index 08f6eb86b26e111f1e2ba3fe3452d58454fb0428..c862c3534394d5cd359d6cfd2c052c37c5d56b40 100755
--- a/product/ERP5Type/Base.py
+++ b/product/ERP5Type/Base.py
@@ -133,11 +133,11 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
     return aq_inner(self.getPortalObject().portal_categories)
 
   # Generic accessor
-  def _getDefaultAcquiredProperty(self, key, default_value, null_value,
-    base_category=None, portal_type=None, copy_value=0, mask_value=0, sync_value=0,
-    accessor_id=None, depends=None, storage_id=None, alt_accessor_id=None,
-    is_list_type=0):
-    """
+  def _getDefaultAcquiredProperty(self, key, default_value, null_value, 
+        base_category=None, portal_type=None, copy_value=0, mask_value=0, sync_value=0,
+        accessor_id=None, depends=None, storage_id=None, alt_accessor_id=None,
+        is_list_type=0):  
+    """           
       This method implements programmable acquisition of values in ERP5.
 
       The principle is that some object attributes should be looked up,
@@ -188,20 +188,33 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
 
       Other case : we want to change the phone number of a related object without
       going to edit the related object
-    """
+      
+    """
+    # Push context to prevent loop
+    from Globals import get_request
+    TRANSACTION = get_transaction()
+    if not hasattr(TRANSACTION, '_erp5_acquisition_stack'): TRANSACTION._erp5_acquisition_stack = {}
+    acquisition_key = ('_getDefaultAcquiredProperty', self.getPath(), key, base_category,
+                       portal_type, copy_value, mask_value, sync_value, 
+                       accessor_id, depends, storage_id, alt_accessor_id, is_list_type)
+    if TRANSACTION._erp5_acquisition_stack.has_key(acquisition_key): return null_value
+    TRANSACTION._erp5_acquisition_stack[acquisition_key] = 1    
+    
     #LOG("Get Acquired Property key",0,str(key))
     if storage_id is None: storage_id=key
     # LOG("Get Acquired Property storage_id",0,str(storage_id))
     # If we hold an attribute and mask_value is set, return the attribute
     if mask_value and hasattr(self, storage_id):
       if getattr(self, storage_id) != None:
+        # Pop context
+        del TRANSACTION._erp5_acquisition_stack[acquisition_key]
         return getattr(self, storage_id)
     # Retrieve the list of related objects
     #LOG("Get Acquired Property self",0,str(self))
     #LOG("Get Acquired Property portal_type",0,str(portal_type))
     #LOG("Get Acquired Property base_category",0,str(base_category))
     #super_list = self._getValueList(base_category, portal_type=portal_type) # We only do a single jump
-    super_list = self._getAcquiredValueList(base_category, portal_type=portal_type) # We only do a single jump
+    super_list = self._getAcquiredValueList(base_category, portal_type=portal_type) # Full acquisition
     super_list = filter(lambda o: o.getPhysicalPath() != self.getPhysicalPath(), super_list) # Make sure we do not create stupid loop here
     #LOG("Get Acquired Property super_list",0,str(super_list))
     #LOG("Get Acquired Property accessor_id",0,str(accessor_id))
@@ -237,6 +250,8 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
     else:
       result = None
     if result is not None:
+      # Pop context
+      del TRANSACTION._erp5_acquisition_stack[acquisition_key]
       return result
     else:
       #LOG("alt_accessor_id",0,str(alt_accessor_id))
@@ -251,20 +266,30 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
                 if type(result) is type([]) or type(result) is type(()):
                   # We must provide the first element of the alternate result
                   if len(result) > 0:
+                    # Pop context
+                    del TRANSACTION._erp5_acquisition_stack[acquisition_key]                    
                     return result[0]
                 else:
+                  # Pop context
+                  del TRANSACTION._erp5_acquisition_stack[acquisition_key]
                   return result
               else:
+                # Pop context
+                del TRANSACTION._erp5_acquisition_stack[acquisition_key]
                 # Result is a simple type
                 return result
 
       if copy_value:
+        # Pop context
+        del TRANSACTION._erp5_acquisition_stack[acquisition_key]
         return getattr(self,storage_id, default_value)
       else:
+        # Pop context
+        del TRANSACTION._erp5_acquisition_stack[acquisition_key]
         # Return the default value defined at the class level XXXXXXXXXXXXXXX
         return default_value
 
-  def _getAcquiredPropertyList(self, key, default_value, null_value,
+  def _getAcquiredPropertyList(self, key, default_value, null_value, 
      base_category, portal_type=None, copy_value=0, mask_value=0, sync_value=0, append_value=0,
      accessor_id=None, depends=None, storage_id=None, alt_accessor_id=None,
      is_list_type=0):
@@ -275,10 +300,23 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
       portal_type
       copy_value
       depends
-    """
+      
+    """
+    # Push context to prevent loop
+    from Globals import get_request
+    TRANSACTION = get_transaction()
+    if not hasattr(TRANSACTION, '_erp5_acquisition_stack'): TRANSACTION._erp5_acquisition_stack = {}
+    acquisition_key = ('_getAcquiredPropertyList', self.getPath(), key, base_category,
+                       portal_type, copy_value, mask_value, sync_value, 
+                       accessor_id, depends, storage_id, alt_accessor_id, is_list_type)
+    if TRANSACTION._erp5_acquisition_stack.has_key(acquisition_key): return null_value
+    TRANSACTION._erp5_acquisition_stack[acquisition_key] = 1    
+        
     if storage_id is None: storage_id=key
     if mask_value and hasattr(self, storage_id):
       if getattr(self, storage_id) != None:
+        # Pop context
+        del TRANSACTION._erp5_acquisition_stack[acquisition_key]        
         return getattr(self, storage_id)
     if type(base_category) == 'a':
       base_category = (base_category, )
@@ -288,7 +326,7 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
     psuper = []
     for cat in base_category:
       #super_list = self._getValueList(cat) # We only do a single jump - no acquisition
-      super_list = self._getAcquiredValueList(cat) # We only do a single jump - no acquisition
+      super_list = self._getAcquiredValueList(cat) # Full acquisition
       for super in super_list:
         if super is not None:
           # Performance should be increased
@@ -320,12 +358,18 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
       if copy_value:
         if not hasattr(self, storage_id):
           setattr(self, value)
+      # Pop context
+      del TRANSACTION._erp5_acquisition_stack[acquisition_key]
       return value
     else:
       # ?????
       if copy_value:
+        # Pop context
+        del TRANSACTION._erp5_acquisition_stack[acquisition_key]
         return getattr(self,storage_id, default_value)
       else:
+        # Pop context
+        del TRANSACTION._erp5_acquisition_stack[acquisition_key]
         return default_value
 
   security.declareProtected( Permissions.AccessContentsInformation, 'getProperty' )
@@ -460,6 +504,7 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
     except:
       categoryIds = []
     id_changed = 0
+    self._v_modified_property_dict = {}
     for key in kw.keys():
       #if key in categoryIds:
       #  self._setCategoryMembership(key, kw[key])
@@ -472,12 +517,13 @@ class Base( CopyContainer, PortalContent, Base18, ActiveObject, ERP5PropertyMana
         elif hasattr(self, accessor_name):
           #LOG("Calling: ",0, accessor_name)
           method = getattr(self, accessor_name)
-          old_value = method()
+          old_value = method() # XXX Why not use getProperty ???
           #LOG("Old value: ",0, str(old_value))
           #LOG("New value: ",0, str(kw[key]))
         else:
           old_value = None
         if old_value != kw[key] or force_update:
+          self._v_modified_property_dict[key] = old_value # We keep in a thread var the previous values - this can be useful for interaction workflow to implement lookups
           self._setProperty(key, kw[key])
       elif self.id != kw['id']:
         self.recursiveFlushActivity(invoke=1) # Do not rename until everything flushed