diff --git a/product/ERP5Type/Accessor/AcquiredProperty.py b/product/ERP5Type/Accessor/AcquiredProperty.py
new file mode 100755
index 0000000000000000000000000000000000000000..1abd54d9f4382aa624ab473c6c4bf226f2f17a5b
--- /dev/null
+++ b/product/ERP5Type/Accessor/AcquiredProperty.py
@@ -0,0 +1,162 @@
+##############################################################################
+#
+# Copyright (c) 2002-2003 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Jean-Paul Smets-Solanes <jp@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+
+from Base import func_code, type_definition, list_types, ATTRIBUTE_PREFIX, Method
+
+class Getter(Method):
+    """
+      Gets the default reference of a relation
+    """
+    _need__name__=1
+
+    # Generic Definition of Method Object
+    # This is required to call the method form the Web
+    func_code = func_code()
+    func_code.co_varnames = ('self',)
+    func_code.co_argcount = 1
+    func_defaults = ()
+
+    def __init__(self,  id, key, property_type, portal_type, acquired_property,
+                        acquisition_base_category,
+                        acquisition_portal_type,
+                        acquisition_accessor_id,
+                        acquisition_copy_value,
+                        acquisition_mask_value,
+                        acquisition_sync_value,
+                        storage_id=None,
+                        alt_accessor_id = None,
+                        is_list_type = 0,                        
+                  ):
+      if type(portal_type) == type('a'): portal_type = (portal_type, )
+      self._id = id
+      self.__name__ = id
+      self._key = key
+      self._type = property_type
+      self._portal_type = portal_type
+      self._null = type_definition[property_type]['null']
+      self._acquisition_base_category = acquisition_base_category
+      self._acquisition_portal_type = acquisition_portal_type
+      self._acquisition_accessor_id = acquisition_accessor_id
+      self._acquisition_copy_value = acquisition_copy_value
+      self._acquisition_mask_value = acquisition_mask_value
+      self._acquisition_sync_value = acquisition_sync_value
+      self._acquired_property = acquired_property
+      if storage_id is None:
+        storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
+      self._storage_id = storage_id
+      self._alt_accessor_id = alt_accessor_id
+      self._is_list_type = is_list_type
+
+    def __call__(self, instance, *args, **kw):
+      if len(args) > 0:
+        default = args[0]
+      else:
+        default = None
+      value = instance._getDefaultAcquiredProperty(self._key, None, self._null,
+            base_category=self._acquisition_base_category,
+            portal_type=self._acquisition_portal_type,
+            accessor_id=self._acquisition_accessor_id,
+            copy_value=self._acquisition_copy_value,
+            mask_value=self._acquisition_mask_value,
+            sync_value=self._acquisition_sync_value,
+            storage_id=self._storage_id,
+            alt_accessor_id=self._alt_accessor_id,
+            is_list_type=self._is_list_type
+            )
+      if value is not None:
+        return value.getProperty(self._acquired_property, default)
+      else:
+        return default
+
+class Setter(Method):
+    """
+      Gets the default reference of a relation
+    """
+    _need__name__=1
+
+    # Generic Definition of Method Object
+    # This is required to call the method form the Web
+    func_code = func_code()
+    func_code.co_varnames = ('self',)
+    func_code.co_argcount = 1
+    func_defaults = ()
+
+    def __init__(self,  id, key, property_type, portal_type, acquired_property,
+                        acquisition_base_category,
+                        acquisition_portal_type,
+                        acquisition_accessor_id,
+                        acquisition_copy_value,
+                        acquisition_mask_value,
+                        acquisition_sync_value,
+                        storage_id=None,
+                        alt_accessor_id = None,
+                        is_list_type = 0,    
+                        reindex = 0                    
+                  ):
+      if type(portal_type) == type('a'): portal_type = (portal_type, )
+      self._id = id
+      self.__name__ = id
+      self._key = key
+      self._type = property_type
+      self._portal_type = portal_type
+      self._null = type_definition[property_type]['null']
+      self._acquisition_base_category = acquisition_base_category
+      self._acquisition_portal_type = acquisition_portal_type
+      self._acquisition_accessor_id = acquisition_accessor_id
+      self._acquisition_copy_value = acquisition_copy_value
+      self._acquisition_mask_value = acquisition_mask_value
+      self._acquisition_sync_value = acquisition_sync_value
+      self._acquired_property = acquired_property
+      if storage_id is None:
+        storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
+      self._storage_id = storage_id
+      self._alt_accessor_id = alt_accessor_id
+      self._is_list_type = is_list_type
+      self._reindex = reindex
+
+    def __call__(self, instance, value, *args, **kw):             
+      o = instance._getDefaultAcquiredProperty(self._key, None, self._null,
+            base_category=self._acquisition_base_category,
+            portal_type=self._acquisition_portal_type,
+            accessor_id=self._acquisition_accessor_id,
+            copy_value=self._acquisition_copy_value,
+            mask_value=self._acquisition_mask_value,
+            sync_value=self._acquisition_sync_value,
+            storage_id=self._storage_id,
+            alt_accessor_id=self._alt_accessor_id,
+            is_list_type=self._is_list_type
+            )
+      if o is None:
+        from Products.ERP5Type.Utils import assertAttributePortalType   
+        assertAttributePortalType(instance, self._storage_id, self._portal_type)
+        o = instance.newContent(id = self._storage_id, portal_type = self._portal_type[0])
+      kw = {self._acquired_property : value}         
+      if self._reindex:
+        o.edit(**kw)
+      else:
+        o._edit(**kw)
diff --git a/product/ERP5Type/Accessor/ContentProperty.py b/product/ERP5Type/Accessor/ContentProperty.py
new file mode 100755
index 0000000000000000000000000000000000000000..2f539042d8626aebb1ce319e5f3b9c6b0aa7cd99
--- /dev/null
+++ b/product/ERP5Type/Accessor/ContentProperty.py
@@ -0,0 +1,283 @@
+##############################################################################
+#
+# Copyright (c) 2002-2003 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Jean-Paul Smets-Solanes <jp@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+
+from Base import func_code, type_definition, list_types, ATTRIBUTE_PREFIX, Method
+import Base
+
+Setter = Base.Setter
+DefaultSetter = Base.Setter
+ValueSetter = Base.Setter
+DefaultValueSetter = Base.Setter
+
+from zLOG import LOG
+
+class ValueGetter(Method):
+    """
+      Gets an attribute value. A default value can be
+      provided if needed
+    """
+    _need__name__=1
+
+    # Generic Definition of Method Object
+    # This is required to call the method form the Web
+    func_code = func_code()
+    func_code.co_varnames = ('self',)
+    func_code.co_argcount = 1
+    func_defaults = ()
+
+    def __init__(self, id, key, property_type, acquired_property, portal_type=None, storage_id=None, default=None):
+      self._id = id
+      self.__name__ = id
+      self._key = key
+      self._type = property_type
+      self._null = type_definition[property_type]['null']
+      self._default = default
+      if storage_id is None:
+        storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
+      elif type(storage_id) not in (type([]), type(())):
+        storage_id = [storage_id]
+      self._storage_id_list = storage_id
+      if type(portal_type) is type('a'):
+        portal_type = (portal_type,)
+      self._portal_type = portal_type
+      self._acquired_property = acquired_property
+
+    def __call__(self, instance, *args, **kw):
+      # We return the first available object in the list
+      if len(args) > 0:
+        default_result = args[0]
+      else:
+        default_result = self._default
+      o = None
+      LOG('ValueGetter.__call__, default',0,self._default)
+      LOG('ValueGetter.__call__, storage_id_list',0,self._storage_id_list)
+      LOG('ValueGetter.__call__, portal_type',0,self._portal_type)
+      for k in self._storage_id_list:
+        o = getattr(instance, k, None)
+        LOG('ValueGetter.__call__, o',0,o)
+        if o is not None and (o.portal_type is None or o.portal_type in self._portal_type):
+          LOG('ValueGetter.__call__, o will be returned...',0,'ok')
+          return o
+      return default_result
+
+class ValueListGetter(Method):
+    """
+      Gets an attribute value. A default value can be
+      provided if needed
+    """
+    _need__name__=1
+
+    # Generic Definition of Method Object
+    # This is required to call the method form the Web
+    func_code = func_code()
+    func_code.co_varnames = ('self',)
+    func_code.co_argcount = 1
+    func_defaults = ()
+
+    def __init__(self, id, key, property_type, acquired_property, portal_type=None, storage_id=None, default=None):
+      self._id = id
+      self.__name__ = id
+      self._key = key
+      self._type = property_type
+      self._null = type_definition[property_type]['null']
+      self._default = default
+      if storage_id is None:
+        storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
+      elif type(storage_id) is not type([]):
+        storage_id = [storage_id]
+      self._storage_id_list = storage_id
+      self._portal_type = portal_type
+      self._acquired_property = acquired_property
+
+    def __call__(self, instance, *args, **kw):
+      # We return the list of matching objects
+      return map(lambda o:o.getObject(),
+        self.contentValues({'portal_type': self._portal_type, 'id': self._storage_id_list}))
+
+DefaultValueGetter = ValueGetter
+
+class Getter(Method):
+    """
+      Gets an attribute value. A default value can be
+      provided if needed
+    """
+    _need__name__=1
+
+    # Generic Definition of Method Object
+    # This is required to call the method form the Web
+    func_code = func_code()
+    func_code.co_varnames = ('self',)
+    func_code.co_argcount = 1
+    func_defaults = ()
+
+    def __init__(self, id, key, property_type, acquired_property, portal_type=None, storage_id=None, default=None):
+      self._id = id
+      self.__name__ = id
+      self._key = key
+      self._type = property_type
+      self._null = type_definition[property_type]['null']
+      self._default = default
+      if storage_id is None:
+        storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
+      elif type(storage_id) is not type([]):
+        storage_id = [storage_id]
+      self._storage_id_list = storage_id
+      if type(portal_type) is type('a'):
+        portal_type = (portal_type,)
+      self._portal_type = portal_type
+      self._acquired_property = acquired_property
+
+    def __call__(self, instance, *args, **kw):
+      # We return the first available object in the list
+      if len(args) > 0:
+        default = args[0]
+      else:
+        default = None
+      o = None
+      for k in self._storage_id_list:
+        o = getattr(instance, k, None)
+        if o is not None and o.portal_type in self._portal_type:
+          #return o.getRelativeUrl()
+          return o.getProperty(self._acquired_property, default)
+      return default
+
+class Setter(Method):
+    """
+      Gets an attribute value. A default value can be
+      provided if needed
+    """
+    _need__name__=1
+
+    # Generic Definition of Method Object
+    # This is required to call the method form the Web
+    func_code = func_code()
+    func_code.co_varnames = ('self',)
+    func_code.co_argcount = 1
+    func_defaults = ()
+
+    def __init__(self, id, key, property_type, acquired_property, portal_type=None, storage_id=None, reindex=0):
+      self._id = id
+      self.__name__ = id
+      self._key = key
+      self._type = property_type
+      self._null = type_definition[property_type]['null']
+      if storage_id is None:
+        storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
+      elif type(storage_id) is not type([]):
+        storage_id = [storage_id]
+      self._storage_id_list = storage_id
+      if type(portal_type) is type('a'):
+        portal_type = (portal_type,)
+      self._portal_type = portal_type
+      self._acquired_property = acquired_property
+      self._reindex = reindex
+
+    def __call__(self, instance, value, *args, **kw):
+      # We return the first available object in the list
+      o = None
+      kw = {self._acquired_property : value}
+      available_id = None
+      for k in self._storage_id_list:
+        o = getattr(instance, k, None)
+        if o is None: available_id = k
+        if o is not None and o.portal_type in self._portal_type:
+          if self._reindex:
+            o.edit(**kw)
+          else:
+            o._edit(**kw)
+      if o is None and available_id is not None:
+        from Products.ERP5Type.Utils import assertAttributePortalType   
+        assertAttributePortalType(instance, self._storage_id, self._portal_type)
+        o = instance.newContent(id = available_id, portal_type = self._portal_type[0])
+        if self._reindex:
+          o.edit(**kw)
+        else:
+          o._edit(**kw)
+
+class ListGetter(Method):
+    """
+      Gets an attribute value. A default value can be
+      provided if needed
+    """
+    _need__name__=1
+
+    # Generic Definition of Method Object
+    # This is required to call the method form the Web
+    func_code = func_code()
+    func_code.co_varnames = ('self',)
+    func_code.co_argcount = 1
+    func_defaults = ()
+
+    def __init__(self, id, key, property_type, acquired_property, portal_type=None, storage_id=None):
+      self._id = id
+      self.__name__ = id
+      self._key = key
+      self._type = property_type
+      self._null = type_definition[property_type]['null']
+      if storage_id is None:
+        storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
+      elif type(storage_id) is not type([]):
+        storage_id = [storage_id]
+      self._storage_id_list = storage_id
+      self._portal_type = portal_type
+      self._acquired_property = acquired_property
+
+    def __call__(self, instance, *args, **kw):
+      # We return the list of matching objects
+      return map(lambda o:o.relative_url,
+        self.searchFolder(portal_type = self._portal_type, id = self._storage_id_list))
+
+DefaultGetter = Getter
+
+class Tester(Method):
+    """
+      Tests if an attribute value exists
+    """
+    _need__name__=1
+
+    # Generic Definition of Method Object
+    # This is required to call the method form the Web
+    func_code = func_code()
+    func_code.co_varnames = ('self',)
+    func_code.co_argcount = 1
+    func_defaults = ()
+
+    def __init__(self, id, key, property_type, acquired_property, storage_id=None):
+      self._id = id
+      self.__name__ = id
+      self._key = key
+      self._type = property_type
+      self._null = type_definition[property_type]['null']
+      if storage_id is None:
+        storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
+      self._storage_id = storage_id
+      self._acquired_property = acquired_property
+
+    def __call__(self, instance, *args, **kw):
+      #return getattr(instance, self._key, None) not in self._null
+      return getattr(instance, self._storage_id, None) is not None